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



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

$sales_invoice_id = (int)$_POST['sales_invoice_id'];
$action = $_POST['action']; // save | final

$client_id = (int)$_POST['client_id'];
if ($client_id <= 0) {
    die("Client is required.");
}

// Check invoice status
$inv = $conn->query("SELECT status FROM sales_invoices WHERE id = $sales_invoice_id")->fetch_assoc();
if (!$inv || $inv['status'] !== 'draft') {
    die("Only draft invoices can be edited.");
}

$product_ids = $_POST['product_id'];
$batch_ids   = $_POST['purchase_item_id'];
$qtys        = $_POST['qty'];
$sell_prices = $_POST['sell_price'];
$disc_types  = $_POST['disc_type'];
$disc_vals   = $_POST['disc_value'];

$overall_disc_type = $_POST['overall_discount_type'] ?? null;
$overall_disc_val  = floatval($_POST['overall_discount_value'] ?? 0);

$received_amount = floatval($_POST['received_amount'] ?? 0);
$payment_mode = $_POST['payment_mode'];

$conn->begin_transaction();

try {

    // Delete old items
    $conn->query("DELETE FROM sales_items WHERE sales_invoice_id = $sales_invoice_id");

    $gross_total = 0;
    $total_taxable = 0;
    $total_gst = 0;

    foreach ($batch_ids as $i => $purchase_item_id) {
		$description = $_POST['description'][$i] ?? '';

        $purchase_item_id = (int)$purchase_item_id;
        if ($purchase_item_id <= 0) continue;

        $qty = floatval($qtys[$i]);
        if ($qty <= 0) continue;

        $sell_price_incl = floatval($sell_prices[$i]);
        $disc_type = $disc_types[$i] ?? null;
        $disc_val  = floatval($disc_vals[$i] ?? 0);

        $pi = $conn->query("SELECT * FROM purchase_items WHERE id = $purchase_item_id")->fetch_assoc();
        if (!$pi) throw new Exception("Invalid batch");

        if ($action === 'final' && $qty > $pi['available_qty']) {
			throw new Exception("Insufficient stock for batch {$pi['batch_no']}. Available: {$pi['available_qty']}");
		}

        $gstp = floatval($pi['gst_percent']);
        $purchase_price = floatval($pi['purchase_price']);

        // Per-unit discount on GST inclusive price
        $final_unit_incl = $sell_price_incl;
        if ($disc_type === 'percent') {
            $final_unit_incl -= ($sell_price_incl * $disc_val / 100);
        } elseif ($disc_type === 'amount') {
            $final_unit_incl -= $disc_val;
        }
        if ($final_unit_incl < 0) $final_unit_incl = 0;

        // Reverse GST
        $final_unit_excl = $final_unit_incl / (1 + $gstp / 100);
        $gst_unit = $final_unit_incl - $final_unit_excl;
        $taxable = $final_unit_excl * $qty;
        $gst_amt = $gst_unit * $qty;
        $line_total = $final_unit_incl * $qty;

        $gross_total += $line_total;
        $total_taxable += $taxable;
        $total_gst += $gst_amt;

        // Insert new item
        $stmtItem = $conn->prepare("
            INSERT INTO sales_items
            (sales_invoice_id, purchase_item_id, product_id, description, batch_no,
             sold_qty, selling_price_incl, selling_price_excl,
             discount_type, discount_value, purchase_price, gst_percent,
             taxable_amount, gst_amount, total_amount)
            VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)
        ");

        $stmtItem->bind_param(
            "iiissdddsdsdddd",
            $sales_invoice_id,
            $purchase_item_id,
            $pi['product_id'],
			$description,
            $pi['batch_no'],
            $qty,
            $final_unit_incl,
            $final_unit_excl,
            $disc_type,
            $disc_val,
            $purchase_price,
            $gstp,
            $taxable,
            $gst_amt,
            $line_total
        );
        $stmtItem->execute();

$inv = $conn->query("SELECT status FROM sales_invoices WHERE id = $sales_invoice_id")->fetch_assoc();
if ($inv['status'] === 'final') {
    throw new Exception("This invoice is already finalized. Modifications Restricted.");
}

        // Reduce stock only on Final
        if ($action === 'final') {
            $conn->query("
                UPDATE purchase_items
                SET available_qty = available_qty - $qty
                WHERE id = $purchase_item_id
            ");
        }
    }

    // Overall discount
    $net_total = $gross_total;
    if ($overall_disc_type === 'percent') {
        $net_total -= ($gross_total * $overall_disc_val / 100);
    } elseif ($overall_disc_type === 'amount') {
        $net_total -= $overall_disc_val;
    }
    if ($net_total < 0) $net_total = 0;

    // Proportionate GST after overall discount
    $discount_ratio = ($gross_total > 0) ? ($net_total / $gross_total) : 1;
    $total_taxable *= $discount_ratio;
    $total_gst *= $discount_ratio;

    $balance_amount = $net_total - $received_amount;
    if ($balance_amount < 0) $balance_amount = 0;

    if ($action === 'final') {
    $invoice_no = generateFinalInvoiceNo($client_id, $conn);
    $status = 'final';
} else {
    $status = 'draft';
}

    // Update invoice header
    $stmtUpd = $conn->prepare("
        UPDATE sales_invoices
        SET invoice_no = ?, client_id=?, gross_total=?, overall_discount_type=?, overall_discount_value=?,
            total_taxable=?, total_gst=?, net_total=?,
            received_amount=?, balance_amount=?, payment_mode=?, status=?
        WHERE id=?
    ");

    $stmtUpd->bind_param(
        "sidsddddddssi",
        $invoice_no,
		$client_id,
        $gross_total,
        $overall_disc_type,
        $overall_disc_val,
        $total_taxable,
        $total_gst,
        $net_total,
        $received_amount,
        $balance_amount,
        $payment_mode,
        $status,
        $sales_invoice_id
    );
    $stmtUpd->execute();

    $conn->commit();

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

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