<?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');
$transaction_date = date('Y-m-d');
$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;

    // Calculate totals
    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");
        $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 exceeds 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 total.");
    $change_due = round($amount_paid - $total_amount, 2);

    // 1. 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')");
    $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();

    // 2. Insert sale_items & 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 for product ID $product_id.");
        }
        $stmt->close();

        if ($stock_quantity < $quantity) throw new Exception("Insufficient stock for product ID $product_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();
        $stmt->close();
    }

    // 3. Insert into bank_transactions
    $reference = $receipt_number ?: 'SALE-' . $sale_id;
    $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 (?, ?, ?, 'sale', ?, 0, ?, ?, ?, 'pending')");
    $stmt->bind_param("ssdsssi", $transaction_date, $reference, $total_amount, $description, $created_at, $created_at, $sale_id);
    $stmt->execute();
    $bank_transaction_id = $stmt->insert_id;
    $stmt->close();

    // 4. Insert into financial_transactions
    $account_id = 1; // Fixed as per your requirement
    $status = 'completed';
    $reconciliation_status = 'pending';
    $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, linked_sale_id) 
        VALUES (?, ?, 'credit', ?, ?, 'Sales Account', ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)");
    $stmt->bind_param("sidsisiiisssii", $transaction_date, $account_id, $total_amount, $payment_method, $description, $reference, $store_id, $sold_by, $status, $created_at, $created_at, $reconciliation_status, $bank_transaction_id, $sale_id);
    $stmt->execute();
    $financial_txn_id = $stmt->insert_id;
    $stmt->close();

    // 5. Insert into payments
    $stmt = $conn->prepare("INSERT INTO payments (sale_id, payment_method, amount, created_at, created_by) VALUES (?, ?, ?, ?, ?)");
    $stmt->bind_param("isssi", $sale_id, $payment_method, $total_amount, $created_at, $sold_by);
    $stmt->execute();
    $payment_id = $stmt->insert_id;
    $stmt->close();

    // 6. Update bank_transactions to link payment and financial transaction
    $stmt = $conn->prepare("UPDATE bank_transactions SET linked_payment_id = ?, linked_financial_transaction_id = ? WHERE id = ?");
    $stmt->bind_param("iii", $payment_id, $financial_txn_id, $bank_transaction_id);
    $stmt->execute();
    $stmt->close();

    $conn->commit();

    echo json_encode([
        'success' => true,
        'message' => 'Sale, bank, financial transaction, and payment recorded.',
        '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()]);
}
?>
