<?php
require_once '../includes/auth.php';
require_once '../db.php';

if ($_SERVER['REQUEST_METHOD'] !== 'POST') {
    die("Invalid Request");
}

$return_id = (int)$_POST['sales_return_id'];
$return_date = $_POST['return_date'];
$action = $_POST['action']; // draft | final
$round_off = floatval($_POST['round_off'] ?? 0);
$return_qtys = $_POST['return_qty'] ?? []; // [product_id => qty]

// Load return header
$sr = $conn->query("SELECT * FROM sales_returns WHERE id = $return_id AND company_id = $cid")->fetch_assoc();
if (!$sr || $sr['status'] !== 'draft') {
    die("Only draft returns can be updated.");
}

$sales_invoice_id = $sr['sales_invoice_id'];

$conn->begin_transaction();

try {

    // Delete old return items first (clean slate)
    $conn->query("DELETE FROM sales_return_items WHERE sales_return_id = $return_id");

    $total_taxable = 0;
    $total_gst = 0;
    $total_amount = 0;

    foreach ($return_qtys as $product_id => $qty) {
        $product_id = (int)$product_id;
        $qty = floatval($qty);
        if ($qty <= 0) continue;

        // Fetch all sales_items for this product in FIFO order
        $salesItemsRes = $conn->query("
            SELECT si.id, si.sold_qty, si.selling_price_incl, si.gst_percent,
                   si.batch_no, si.purchase_item_id,
                   COALESCE(v.total_returned_qty, 0) AS already_returned,
                   (si.sold_qty - COALESCE(v.total_returned_qty, 0)) AS balance_qty
            FROM sales_items si
            LEFT JOIN v_sales_returned_qty v ON v.sales_item_id = si.id
            WHERE si.sales_invoice_id = $sales_invoice_id AND si.product_id = $product_id
            ORDER BY si.id ASC
        ");

        $remaining = $qty;

        while ($remaining > 0.001 && ($si = $salesItemsRes->fetch_assoc())) {
            $available = floatval($si['balance_qty']);
            if ($available <= 0.001) continue;

            $take = min($remaining, $available);
            $rate_incl = floatval($si['selling_price_incl']);
            $gstp = floatval($si['gst_percent']);
            $line_total = $take * $rate_incl;
            $taxable = $line_total / (1 + $gstp / 100);
            $gst_amt = $line_total - $taxable;

            $si_id = (int)$si['id'];
            $batch_no = $si['batch_no'];
            $sold_qty = floatval($si['sold_qty']);

            $stmtItem = $conn->prepare("
                INSERT INTO sales_return_items
                (sales_return_id, sales_item_id, product_id, batch_no,
                 sold_qty, return_qty, rate_incl_gst, gst_percent,
                 taxable_amount, gst_amount, total_amount)
                VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)
            ");
            $stmtItem->bind_param(
                "iiisddddddd",
                $return_id, $si_id, $product_id, $batch_no,
                $sold_qty, $take, $rate_incl, $gstp, $taxable, $gst_amt, $line_total
            );
            $stmtItem->execute();

            // Restore stock only when finalizing
            if ($action === 'final') {
                $purchase_item_id = (int)$si['purchase_item_id'];
                $conn->query("
                    UPDATE purchase_items
                    SET available_qty = available_qty + $take
                    WHERE id = $purchase_item_id
                ");
            }

            $total_taxable += $taxable;
            $total_gst += $gst_amt;
            $total_amount += $line_total;
            $remaining -= $take;
        }

        if ($remaining > 0.001) {
            throw new Exception("Return qty exceeds available balance for one or more products.");
        }
    }

    // Apply round off
    $total_amount = round($total_amount + $round_off, 2);

    // Update header totals & status
    $status = ($action === 'final') ? 'final' : 'draft';

    $stmtUpd = $conn->prepare("
        UPDATE sales_returns
        SET return_date=?, total_taxable=?, total_gst=?, total_amount=?, round_off=?, status=?
        WHERE id=?
    ");
    $stmtUpd->bind_param("sddddsi", $return_date, $total_taxable, $total_gst, $total_amount, $round_off, $status, $return_id);
    $stmtUpd->execute();

    $conn->commit();

    if ($status === 'final') {
        header("Location: view.php?id=" . $return_id);
    } else {
        header("Location: edit.php?id=" . $return_id);
    }
    exit;

} catch (Exception $e) {
    $conn->rollback();
    die("Return Update Failed: " . $e->getMessage());
}
