<?php
// ============================================================
//  MediCore — Suppliers API
//  File: api/suppliers.php
// ============================================================
require_once '../includes/db.php';
require_once '../includes/auth.php';
require_login();
session_write_close(); // release session lock — prevents XAMPP request queuing

header('Content-Type: application/json');

ensure_soft_delete('suppliers');

$body   = json_decode(file_get_contents('php://input'), true) ?? [];
$action = trim($body['action'] ?? '');

try {
    match($action) {
        'list'   => api_list($body),
        'detail' => api_detail($body),
        'add'    => api_add($body),
        'edit'   => api_edit($body),
        'delete' => api_delete($body),
        'pay'    => api_pay($body),
        default  => fail('Unknown action')
    };
} catch (Throwable $e) {
    fail($e->getMessage());
}

// ── List / Search ─────────────────────────────────────────────
function api_list(array $b): void {
    $q      = trim($b['q'] ?? '');
    $where  = $q
        ? "WHERE s.is_deleted = 0 AND (s.name LIKE ? OR s.contact LIKE ? OR s.phone LIKE ?)"
        : "WHERE s.is_deleted = 0";
    $params = $q ? ["%$q%", "%$q%", "%$q%"] : [];

    $rows = db_rows(
        "SELECT s.*,
                COALESCE(SUM(p.final_price), 0)            AS total_purchase,
                COALESCE(SUM(p.paid),        0)            AS total_po_paid
           FROM suppliers s
      LEFT JOIN purchases p ON p.supplier_id = s.id
         $where
         GROUP BY s.id
         ORDER BY s.name",
        $params
    );

    // Add payments made via cash_ledger for each supplier
    foreach ($rows as &$row) {
        $row['total_paid'] = (float) db_val(
            "SELECT COALESCE(SUM(amount),0) FROM cash_ledger
              WHERE ref LIKE ? AND type = 'out'",
            ['SUP-' . $row['id'] . '-%']
        );
    }
    unset($row);

    ok(['data' => $rows]);
}

// ── Detail ────────────────────────────────────────────────────
function api_detail(array $b): void {
    $id = (int)($b['id'] ?? 0);
    if (!$id) fail('Missing id');
    $row = db_row("SELECT * FROM suppliers WHERE id = ?", [$id]);
    if (!$row) fail('Supplier not found');
    ok(['data' => $row]);
}

// ── Add ───────────────────────────────────────────────────────
function api_add(array $b): void {
    $name = trim($b['name'] ?? '');
    if (!$name) fail('Supplier name is required');

    if (db_val("SELECT id FROM suppliers WHERE name = ?", [$name]))
        fail("\"$name\" already exists");

    $balance = max(0, (float)($b['balance'] ?? 0));

    $id = db_insert(
        "INSERT INTO suppliers (name, contact, phone, address, balance)
         VALUES (?, ?, ?, ?, ?)",
        [
            $name,
            trim($b['contact'] ?? ''),
            trim($b['phone']   ?? ''),
            trim($b['address'] ?? ''),
            $balance,
        ]
    );

    // If opening balance > 0, log it as a credit in cash_ledger
    if ($balance > 0) {
        db_run(
            "INSERT INTO cash_ledger (date, description, account, type, amount, ref)
             VALUES (?, ?, 'Cash', 'out', ?, ?)",
            [
                date('Y-m-d'),
                "Opening balance — $name",
                $balance,
                "SUP-{$id}-OPEN",
            ]
        );
    }

    ok(['id' => $id, 'msg' => 'Supplier added']);
}

// ── Edit ──────────────────────────────────────────────────────
function api_edit(array $b): void {
    $id   = (int)($b['id']   ?? 0);
    $name = trim($b['name']  ?? '');
    if (!$id)   fail('Missing id');
    if (!$name) fail('Supplier name is required');

    if (db_val("SELECT id FROM suppliers WHERE name = ? AND id != ?", [$name, $id]))
        fail("\"$name\" already exists");

    db_run(
        "UPDATE suppliers
            SET name    = ?,
                contact = ?,
                phone   = ?,
                address = ?
          WHERE id = ?",
        [
            $name,
            trim($b['contact'] ?? ''),
            trim($b['phone']   ?? ''),
            trim($b['address'] ?? ''),
            $id,
        ]
    );
    ok(['msg' => 'Supplier updated']);
}

// ── Pay ───────────────────────────────────────────────────────
function api_pay(array $b): void {
    $id      = (int)($b['id']     ?? 0);
    $amount  = (float)($b['amount']  ?? 0);
    $account = trim($b['account'] ?? 'Cash');
    $note    = trim($b['note']    ?? '');

    if (!$id)       fail('Missing supplier id');
    if ($amount <= 0) fail('Amount must be greater than zero');

    $validAccounts = ['Cash', 'Bank', 'MFS', 'Card'];
    if (!in_array($account, $validAccounts))
        fail('Invalid payment account');

    // Load supplier
    $sup = db_row("SELECT * FROM suppliers WHERE id = ?", [$id]);
    if (!$sup) fail('Supplier not found');

    $balance = (float) $sup['balance'];
    if ($amount > $balance + 0.001)
        fail("Payment ({$amount}) exceeds balance ({$balance})");

    // Run both updates in a transaction
    db()->beginTransaction();
    try {
        // 1. Reduce supplier balance
        db_run(
            "UPDATE suppliers SET balance = GREATEST(0, balance - ?) WHERE id = ?",
            [$amount, $id]
        );

        // 2. Record in cash_ledger
        $ref  = 'SUP-' . $id . '-' . date('YmdHis');
        $desc = "Payment to {$sup['name']}" . ($note ? " — $note" : '');
        db_run(
            "INSERT INTO cash_ledger (date, description, account, type, amount, ref)
             VALUES (?, ?, ?, 'out', ?, ?)",
            [date('Y-m-d'), $desc, $account, $amount, $ref]
        );

        db()->commit();
        ok(['msg' => 'Payment recorded successfully', 'ref' => $ref]);

    } catch (Throwable $e) {
        db()->rollBack();
        fail('Payment failed: ' . $e->getMessage());
    }
}

// ── Delete ────────────────────────────────────────────────────
function api_delete(array $b): void {
    require_admin();
    $id  = (int)($b['id'] ?? 0);
    if (!$id) fail('Missing id');

    $rec = db_row("SELECT * FROM `suppliers` WHERE id = ? AND is_deleted = 0", [$id]);
    if (!$rec) fail('Record not found');

    $uid = current_user_id();
    db_run(
        "UPDATE `suppliers`
            SET is_deleted = 1,
                deleted_at = NOW(),
                deleted_by = ?
          WHERE id = ?",
        [$uid, $id]
    );

    log_action('delete', 'suppliers', $id,
        'Soft-deleted: ' . ($rec['name'] ?? '#' . $id));

    ok(['msg' => 'Moved to Recycle Bin']);
}


// ── Helpers ───────────────────────────────────────────────────
function ok(array $extra = []): void {
    echo json_encode(array_merge(['success' => true], $extra));
    exit;
}
function fail(string $msg): never {
    echo json_encode(['success' => false, 'error' => $msg]);
    exit;
}
