<?php
// hps_core.php
// SINGLE SOURCE OF TRUTH FOR ALL HP CALCULATIONS
// Compatible with ledger having DR / CR columns

/* ======================================================
   MAIN CALCULATION FUNCTION
====================================================== */
function hps_sale_calc(mysqli $conn, int $sale_id): array
{
    /* ---------- LOAD SALE ---------- */
    $sale = mysqli_fetch_assoc(mysqli_query($conn, "
        SELECT *
        FROM hps_sales
        WHERE id = $sale_id
        LIMIT 1
    "));

    if (!$sale) return [];

    /* ---------- CASH SALE TOTAL (fallback) ---------- */
    $cash_total = 0;

    if (isset($sale['sale_price'])) {
        $cash_total = (float)$sale['sale_price'];
    } elseif (isset($sale['total_amount'])) {
        $cash_total = (float)$sale['total_amount'];
    } else {
        $it = mysqli_fetch_assoc(mysqli_query($conn, "
            SELECT IFNULL(SUM(qty * price),0) t
            FROM hps_sale_items
            WHERE sale_id = $sale_id
        "));
        $cash_total = (float)($it['t'] ?? 0);
    }

    /* ---------- BASIC VALUES ---------- */
    $down = (float)($sale['down_payment'] ?? 0);
    $doc  = (float)($sale['documentation_charges'] ?? 0);

    /* ---------- MONTHLY INSTALLMENT ---------- */
    $monthly = 0;
    foreach ([
        'monthly_installment',
        'installment_amount',
        'monthly_amount',
        'per_month'
    ] as $k) {
        if (!empty($sale[$k])) {
            $monthly = (float)$sale[$k];
            break;
        }
    }

    /* ---------- TOTAL INSTALLMENTS ---------- */
    $months = 0;
    foreach ([
        'total_installments',
        'installments',
        'months',
        'tenure_months'
    ] as $k) {
        if (!empty($sale[$k])) {
            $months = (int)$sale[$k];
            break;
        }
    }

    /* ---------- HP TOTAL (SALES VALUE) ---------- */
    $hp_total = 0;
    foreach ([
        'hp_total',
        'hp_amount',
        'total_hp',
        'grand_total',
        'net_total'
    ] as $k) {
        if (!empty($sale[$k])) {
            $hp_total = (float)$sale[$k];
            break;
        }
    }

    if ($hp_total <= 0) {
        if ($monthly > 0 && $months > 0) {
            $hp_total = $down + ($monthly * $months);
        } else {
            $hp_total = $cash_total;
        }
    }

    /* ---------- LEDGER PAYMENTS (CR - DR) ---------- */
    $paid_down = hps_ledger_sum($conn, $sale_id, ['DOWN']);
    $paid_doc  = hps_ledger_sum($conn, $sale_id, ['DOC', 'DOCUMENT']);
    $paid_inst = hps_ledger_sum($conn, $sale_id, ['INST', 'INSTALLMENT']);

    $paid_total = hps_ledger_total($conn, $sale_id);

    /* ---------- OUTSTANDING CALCULATIONS ---------- */

    // HP outstanding (what reports expect)
    $outstanding_hp = max(0, $hp_total - ($paid_down + $paid_inst));

    // Total receivable (HP + Doc)
    $total_receivable = $hp_total + $doc;

    // Total outstanding (including doc)
    $outstanding_total = max(
        0,
        $total_receivable - ($paid_down + $paid_inst + $paid_doc)
    );

    /* ---------- FIRST COLLECTION ---------- */
    $unpaid_down = max(0, $down - $paid_down);
    $unpaid_doc  = max(0, $doc  - $paid_doc);

    $amount_to_receive_now = $unpaid_down + $unpaid_doc;

    /* ---------- INSTALLMENT DUE ---------- */
    $installment_due = 0;
    if ($monthly > 0 && $outstanding_hp > 0) {
        if ($down <= 0 || $paid_down >= $down) {
            $installment_due = min($monthly, $outstanding_hp);
        }
    }

    /* ---------- RETURN STRUCTURE ---------- */
    return [
        'sale' => $sale,

        'cash_total' => $cash_total,

        'down_payment' => $down,
        'doc_charges'  => $doc,

        'monthly_installment' => $monthly,
        'total_installments'  => $months,

        'hp_total' => $hp_total,                 // 460000
        'total_receivable' => $total_receivable, // 460300

        'paid_down' => $paid_down,
        'paid_doc'  => $paid_doc,
        'paid_installments' => $paid_inst,
        'paid_total' => $paid_total,

        'outstanding_hp' => $outstanding_hp,       // 360000
        'outstanding_total' => $outstanding_total,

        'amount_to_receive_now' => $amount_to_receive_now, // 100300
        'installment_due' => $installment_due      // 30000
    ];
}

/* ======================================================
   LEDGER TOTAL (CR - DR)
====================================================== */
function hps_ledger_total(mysqli $conn, int $sale_id): float
{
    $r = mysqli_fetch_assoc(mysqli_query($conn, "
        SELECT IFNULL(SUM(cr) - SUM(dr), 0) t
        FROM hps_customer_ledger
        WHERE ref_id = $sale_id
    "));
    return (float)($r['t'] ?? 0);
}

/* ======================================================
   LEDGER SUM BY TYPE (CR - DR)
====================================================== */
function hps_ledger_sum(mysqli $conn, int $sale_id, array $keywords): float
{
    $w = [];
    foreach ($keywords as $k) {
        $k = mysqli_real_escape_string($conn, $k);
        $w[] = "description LIKE '%$k%'";
        $w[] = "ref_type LIKE '%$k%'";
    }
    $where = implode(" OR ", $w);

    $r = mysqli_fetch_assoc(mysqli_query($conn, "
        SELECT IFNULL(SUM(cr) - SUM(dr), 0) t
        FROM hps_customer_ledger
        WHERE ref_id = $sale_id
          AND ($where)
    "));
    return (float)($r['t'] ?? 0);
}
