<?php
include 'db.php';
include 'auth.php';
require 'journal_entry_handler.php';
require_right('Add Purchase');

// Set JSON header for AJAX responses
header('Content-Type: application/json');

$vendor_id     = $_POST['vendor_id'];
$store_id      = $_POST['store_id'] ?? 1; // Default to main store if not specified
$purchase_date = $_POST['purchase_date'];
$reference     = $_POST['reference_no'];
$discount      = floatval($_POST['discount']);
$shipping      = floatval($_POST['shipping']);
$status        = $_POST['status'];
$notes         = $_POST['notes'];

$item_ids      = $_POST['item_id'];
$quantities    = $_POST['quantity'];
$cost_prices   = $_POST['price'];
$retail_prices = $_POST['retail_price'];

$total = 0;
$tax_total = 0;

foreach ($item_ids as $i => $item_id) {
    $qty = floatval($quantities[$i]);
    $cost_price = floatval($cost_prices[$i]);
    $retail_price = floatval($retail_prices[$i]);
    $subtotal = $qty * $cost_price;

    $res = $conn->query("SELECT i.name, i.cost_price, i.retail_price, tr.rate 
                         FROM items i 
                         LEFT JOIN tax_rates tr ON i.tax_rate_id = tr.id 
                         WHERE i.id = $item_id");
    $row = $res->fetch_assoc();

    $item_name = $row['name'];
    $old_cost_price = floatval($row['cost_price']);
    $old_retail_price = floatval($row['retail_price']);
    $taxRate = floatval($row['rate']);

    $taxAmount = ($taxRate / 100) * $subtotal;
    $total += $subtotal;
    $tax_total += $taxAmount;

    if ($old_cost_price != $cost_price || $old_retail_price != $retail_price) {
        $stmt_history = $conn->prepare("
            INSERT INTO price_history (item_id, item_name, vendor_id, old_cost_price, new_cost_price, old_retail_price, new_retail_price, changed_by) 
            VALUES (?, ?, ?, ?, ?, ?, ?, ?)
        ");
        $user = 'admin';
        $stmt_history->bind_param("isidddds", $item_id, $item_name, $vendor_id, $old_cost_price, $cost_price, $old_retail_price, $retail_price, $user);
        $stmt_history->execute();
    }

    $conn->query("UPDATE items SET cost_price = $cost_price, retail_price = $retail_price WHERE id = $item_id");
}

$net = $total + $tax_total + $shipping - $discount;

// Convert purchase_date to datetime format (add current time)
$purchase_datetime = $purchase_date . ' ' . date('H:i:s');

// Start transaction for data integrity
$conn->begin_transaction();

try {

$stmt = $conn->prepare("
    INSERT INTO purchases (purchase_number, vendor_id, store_id, purchase_date, total_amount, tax_amount, discount_amount, net_amount, payment_method, status, created_at) 
    VALUES (?, ?, ?, ?, ?, ?, ?, ?, 'cash', ?, NOW())
");
$stmt->bind_param("ssisdidds", $reference, $vendor_id, $store_id, $purchase_datetime, $total, $tax_total, $discount, $net, $status);
$stmt->execute();
$purchase_id = $stmt->insert_id;

foreach ($item_ids as $i => $item_id) {
    $qty = floatval($quantities[$i]);
    $cost_price = floatval($cost_prices[$i]);
    $subtotal = $qty * $cost_price;

    $stmt2 = $conn->prepare("
        INSERT INTO purchase_items (purchase_id, item_id, store_id, item_name, quantity, unit_cost, total_cost, tax_rate) 
        VALUES (?, ?, ?, ?, ?, ?, ?, ?)
    ");
    $stmt2->bind_param("iiisdidd", $purchase_id, $item_id, $store_id, $item_name, $qty, $cost_price, $subtotal, $taxRate);
    $stmt2->execute();
}

// ✅ Add supplier outstanding record if not marked as paid
if ($status !== 'paid') {
    $conn->query("
        INSERT INTO sup_outstanding (purchase_id, vendor_id, amount, status) 
        VALUES ($purchase_id, $vendor_id, $net, 'unpaid')
    ");
}

// ✅ CRITICAL FIX: Create journal entry for purchase transaction
if (function_exists('createPurchaseJournalEntry')) {
    $payment_method = ($status === 'paid') ? 'cash' : 'credit';
    $journal_success = createPurchaseJournalEntry($conn, $purchase_id, $net, $payment_method, $store_id);
    if (!$journal_success) {
        error_log("Failed to create journal entry for purchase #$purchase_id");
    }
}



// ✅ Log inventory movement if status is 'received'
if ($status === 'received') {
    foreach ($item_ids as $i => $item_id) {
        $qty = floatval($quantities[$i]);
        $insertMovement = $conn->prepare("
            INSERT INTO inventory_movements (item_id, store_id, movement_type, reference_type, reference_id, quantity) 
            VALUES (?, ?, 'in', 'purchase', ?, ?)
        ");
        $insertMovement->bind_param("iiid", $item_id, $store_id, $purchase_id, $qty);
        $insertMovement->execute();
        $insertMovement->close();
    }
}

// ✅ Update BOM-based stock items if any of the materials were updated
function update_all_bom_costs($conn, $changed_item_ids = []) {
    if (empty($changed_item_ids)) return;

    $in_ids = implode(',', array_map('intval', $changed_item_ids));
    $sql = "
        SELECT DISTINCT bm.item_id
        FROM bom_components bc
        JOIN bom_master bm ON bc.bom_id = bm.id
        WHERE bc.component_item_id IN ($in_ids)
    ";
    $result = $conn->query($sql);
    $affected_stock_items = [];

    while ($row = $result->fetch_assoc()) {
        $affected_stock_items[] = intval($row['item_id']);
    }

    foreach ($affected_stock_items as $stock_item_id) {
        $q = "
            SELECT bc.quantity, i.cost_price
            FROM bom_components bc
            JOIN items i ON bc.component_item_id = i.id
            JOIN bom_master bm ON bc.bom_id = bm.id
            WHERE bm.item_id = $stock_item_id
        ";
        $r = $conn->query($q);
        $bom_total = 0;

        while ($row = $r->fetch_assoc()) {
            $bom_total += floatval($row['quantity']) * floatval($row['cost_price']);
        }

        $update = $conn->prepare("UPDATE items SET cost_price = ? WHERE id = ?");
        $update->bind_param("di", $bom_total, $stock_item_id);
        $update->execute();
        $update->close();
    }
}

    // ✅ Now actually run the BOM cost updates
    update_all_bom_costs($conn, $item_ids);
    
    // Commit transaction
    $conn->commit();
    
    // Return success response
    echo json_encode([
        'success' => true,
        'message' => 'Purchase created successfully!',
        'purchase_id' => $purchase_id,
        'redirect' => 'purchase-list.php?success=1'
    ]);
    exit;
    
} catch (Exception $e) {
    // Rollback transaction on error
    $conn->rollback();
    error_log("Purchase creation error: " . $e->getMessage());
    
    // Check if it's a duplicate entry error
    $error_message = $e->getMessage();
    if (strpos($error_message, 'Duplicate entry') !== false) {
        $error_message = "Purchase number '$reference' already exists. Please use a different reference number.";
    }
    
    // Return error response
    echo json_encode([
        'success' => false,
        'message' => $error_message,
        'error_type' => 'duplicate_entry'
    ]);
    exit;
}
?>
