<?php
session_start();
include('../../includes/config.php');

// Ensure user is logged in and is cashier (role_id 3)
if (!isset($_SESSION['user_id']) || $_SESSION['role_id'] != 3) {
    http_response_code(403);
    echo json_encode(['success' => false, 'message' => 'Unauthorized']);
    exit;
}

// Accept JSON input if content-type is application/json
$contentType = $_SERVER['CONTENT_TYPE'] ?? '';
if (strpos($contentType, 'application/json') !== false) {
    $inputJSON = file_get_contents('php://input');
    $_POST = json_decode($inputJSON, true);
}

// Validate required data
if (
    empty($_POST['items']) || !is_array($_POST['items']) ||
    empty($_POST['payment_method']) ||
    empty($_POST['store_id'])
) {
    echo json_encode(['success' => false, 'message' => 'Missing required data (items, payment_method, store_id).']);
    exit;
}

$items = $_POST['items'];
$payment_method = $_POST['payment_method'];
$store_id = (int)$_POST['store_id'];
$sold_by = $_SESSION['user_id'];
$created_at = date('Y-m-d H:i:s');
$receipt_number = $_POST['receipt_number'] ?? '';
$customer_name = $_POST['customer_name'] ?? '';
$amount_paid = isset($_POST['amount_paid']) ? floatval($_POST['amount_paid']) : 0.0;

$conn->begin_transaction();

try {
    $subtotal = 0;
    $total_vat = 0;
    $total_discount = 0;

    // 1. Calculate totals including discount and VAT per item
    foreach ($items as $item) {
        if (empty($item['product_id']) || empty($item['quantity']) || $item['quantity'] <= 0) {
            throw new Exception("Invalid item data.");
        }

        $product_id = (int)$item['product_id'];
        $quantity = (int)$item['quantity'];
        $discount = isset($item['discount']) ? floatval($item['discount']) : 0.0;
        if ($discount < 0) $discount = 0.0;

        $stmt = $conn->prepare("SELECT selling_price, vat_rate FROM products WHERE id = ? LIMIT 1");
        if (!$stmt) throw new Exception("Prepare statement failed: " . $conn->error);
        $stmt->bind_param("i", $product_id);
        $stmt->execute();
        $stmt->bind_result($selling_price, $vat_rate);
        if (!$stmt->fetch()) {
            $stmt->close();
            throw new Exception("Product ID $product_id not found.");
        }
        $stmt->close();

        $line_total = $selling_price * $quantity;
        if ($discount > $line_total) {
            throw new Exception("Discount cannot exceed line total for product ID $product_id.");
        }
        $line_vat = (($line_total - $discount) * $vat_rate) / 100;

        $subtotal += $line_total;
        $total_discount += $discount;
        $total_vat += $line_vat;
    }

    $total_amount = $subtotal - $total_discount + $total_vat;

    if ($amount_paid < $total_amount) {
        throw new Exception("Amount paid is less than the total amount due.");
    }

    $change_due = round($amount_paid - $total_amount, 2);

    // 2. Insert into sales_transactions
    $stmt = $conn->prepare("INSERT INTO sales_transactions 
        (store_id, total_amount, vat_total, discount_total, payment_method, sold_by, created_at, receipt_number, customer_name, amount_paid, transaction_type, status) 
        VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, 'sale', 'completed')");
    if (!$stmt) throw new Exception("Prepare statement failed: " . $conn->error);

    $stmt->bind_param(
        "idddsisssd",
        $store_id,
        $total_amount,
        $total_vat,
        $total_discount,
        $payment_method,
        $sold_by,
        $created_at,
        $receipt_number,
        $customer_name,
        $amount_paid
    );
    $stmt->execute();
    $sale_id = $stmt->insert_id;
    $stmt->close();

    // 3. Insert sale_items and update inventory
    foreach ($items as $item) {
        $product_id = (int)$item['product_id'];
        $quantity = (int)$item['quantity'];
        $discount = isset($item['discount']) ? floatval($item['discount']) : 0.0;

        $stmt = $conn->prepare("SELECT selling_price, vat_rate FROM products WHERE id = ? LIMIT 1");
        $stmt->bind_param("i", $product_id);
        $stmt->execute();
        $stmt->bind_result($selling_price, $vat_rate);
        $stmt->fetch();
        $stmt->close();

        $total_price = ($selling_price * $quantity) - $discount;

        $stmt = $conn->prepare("INSERT INTO sales_items 
            (transaction_id, product_id, quantity, unit_price, discount, vat_rate, total_price) 
            VALUES (?, ?, ?, ?, ?, ?, ?)");
        $stmt->bind_param("iiiiddd", $sale_id, $product_id, $quantity, $selling_price, $discount, $vat_rate, $total_price);
        $stmt->execute();
        $stmt->close();

        $stmt = $conn->prepare("SELECT quantity FROM inventory WHERE product_id = ? AND store_id = ? LIMIT 1");
        $stmt->bind_param("ii", $product_id, $store_id);
        $stmt->execute();
        $stmt->bind_result($stock_quantity);
        if (!$stmt->fetch()) {
            $stmt->close();
            throw new Exception("No inventory record found for product ID $product_id in store ID $store_id.");
        }
        $stmt->close();

        if ($stock_quantity < $quantity) {
            throw new Exception("Not enough stock for product ID $product_id in store ID $store_id.");
        }

        $stmt = $conn->prepare("UPDATE inventory SET quantity = quantity - ? WHERE product_id = ? AND store_id = ? AND quantity >= ?");
        $stmt->bind_param("iiii", $quantity, $product_id, $store_id, $quantity);
        $stmt->execute();
        if ($stmt->affected_rows === 0) {
            $stmt->close();
            throw new Exception("Failed to update stock for product ID $product_id.");
        }
        $stmt->close();
    }

    // 4. Insert into bank_transactions
    $transaction_date = date('Y-m-d');
    $reference = $receipt_number ?: 'SALE-' . $sale_id;
    $amount = $total_amount;
    $type = 'sale';
    $description = 'Sale Payment - Receipt: ' . $reference;

    $stmt = $conn->prepare("INSERT INTO bank_transactions 
        (transaction_date, reference, amount, type, description, reconciled, created_at, updated_at, linked_sales_batch_id, reconciliation_status) 
        VALUES (?, ?, ?, ?, ?, 0, ?, ?, ?, 'pending')");
    if (!$stmt) throw new Exception("Failed to prepare bank transaction insert: " . $conn->error);

    $stmt->bind_param(
        "ssdssssi",
        $transaction_date,
        $reference,
        $amount,
        $type,
        $description,
        $created_at,
        $created_at,
        $sale_id
    );
    $stmt->execute();
    $bank_txn_id = $stmt->insert_id;
    $stmt->close();

    // 5. Insert financial transactions (journal entries)

    // These account IDs should match your chart of accounts IDs
    $account_bank_id = 101;           // Bank account (Asset)
    $account_sales_revenue_id = 401;  // Sales Revenue (Income)
    $account_vat_payable_id = 202;    // VAT Payable (Liability)

    $status = 'completed';
    $reconciliation_status = 'pending';

    // Debit bank account (increase asset)
    $description_debit = "Sale payment received for Sale ID $sale_id";
    $type_debit = 'debit';
    $amount_debit = $total_amount;

    $payment_method_str = $payment_method; // e.g. 'cash', 'card'
    $account_str = ''; // Optional account name or empty string
    $reference_id = $sale_id;
    $store_created_by = $store_id;
    $created_by = $sold_by;
    $updated_at = $created_at;
    $linked_bank_transaction_id = $bank_txn_id;
    $debit = $total_amount;
    $credit = 0.00;
    $linked_sale_id = $sale_id;
    $linked_bank_txn_id = $bank_txn_id;

    $stmt = $conn->prepare("INSERT INTO financial_transactions
        (transaction_date, account_id, type, amount, payment_method, account, description, reference_id, store_id, created_by, status, created_at, updated_at, reconciliation_status, linked_bank_transaction_id, debit, credit, linked_sale_id, linked_bank_txn_id)
        VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)");
    $stmt->bind_param(
        "sissssssiiisssiiddii",
        $transaction_date,
        $account_bank_id,
        $type_debit,
        $amount_debit,
        $payment_method_str,
        $account_str,
        $description_debit,
        $reference_id,
        $store_created_by,
        $created_by,
        $status,
        $created_at,
        $updated_at,
        $reconciliation_status,
        $linked_bank_transaction_id,
        $debit,
        $credit,
        $linked_sale_id,
        $linked_bank_txn_id
    );
    $stmt->execute();
    $stmt->close();

    // Credit sales revenue account (income)
    $description_credit_sales = "Sales revenue for Sale ID $sale_id";
    $type_credit = 'credit';
    $amount_credit_sales = $subtotal - $total_discount;
    $debit_credit_sales = 0.00;
    $credit_credit_sales = $amount_credit_sales;
    $linked_bank_transaction_id = null;
    $linked_bank_txn_id = null;

    $stmt = $conn->prepare("INSERT INTO financial_transactions
        (transaction_date, account_id, type, amount, payment_method, account, description, reference_id, store_id, created_by, status, created_at, updated_at, reconciliation_status, linked_bank_transaction_id, debit, credit, linked_sale_id, linked_bank_txn_id)
        VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)");
    $stmt->bind_param(
        "sissssssiiisssiiddii",
        $transaction_date,
        $account_sales_revenue_id,
        $type_credit,
        $amount_credit_sales,
        $payment_method_str,
        $account_str,
        $description_credit_sales,
        $reference_id,
        $store_created_by,
        $created_by,
        $status,
        $created_at,
        $updated_at,
        $reconciliation_status,
        $linked_bank_transaction_id,
        $debit_credit_sales,
        $credit_credit_sales,
        $linked_sale_id,
        $linked_bank_txn_id
    );
    $stmt->execute();
    $stmt->close();

    // Credit VAT payable account if VAT > 0
    if ($total_vat > 0) {
        $description_credit_vat = "VAT collected on Sale ID $sale_id";
        $amount_credit_vat = $total_vat;
        $debit_credit_vat = 0.00;
        $credit_credit_vat = $amount_credit_vat;

        $stmt = $conn->prepare("INSERT INTO financial_transactions
            (transaction_date, account_id, type, amount, payment_method, account, description, reference_id, store_id, created_by, status, created_at, updated_at, reconciliation_status, linked_bank_transaction_id, debit, credit, linked_sale_id, linked_bank_txn_id)
            VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)");
        $stmt->bind_param(
            "sissssssiiisssiiddii",
            $transaction_date,
            $account_vat_payable_id,
            $type_credit,
            $amount_credit_vat,
            $payment_method_str,
            $account_str,
            $description_credit_vat,
            $reference_id,
            $store_created_by,
            $created_by,
            $status,
            $created_at,
            $updated_at,
            $reconciliation_status,
            $linked_bank_transaction_id,
            $debit_credit_vat,
            $credit_credit_vat,
            $linked_sale_id,
            $linked_bank_txn_id
        );
        $stmt->execute();
        $stmt->close();
    }

    $conn->commit();

    echo json_encode([
        'success' => true,
        'message' => 'Sale, bank transaction, and financial transactions recorded successfully.',
        'sale_id' => $sale_id,
        'total_amount' => round($total_amount, 2),
        'change_due' => $change_due
    ]);

} catch (Exception $e) {
    $conn->rollback();
    http_response_code(400);
    echo json_encode(['success' => false, 'message' => $e->getMessage()]);
}
?>
