<?php
session_start();
include '../layouts/dbconn.php';
include '../layouts/session.php';

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

if (!isset($_SESSION['user_id'])) {
    echo json_encode(['success' => false, 'message' => 'Unauthorized']);
    exit();
}

$allowed_roles = ['SUPER_ADMIN', 'HOSPITAL_ADMIN', 'ACCOUNTANT', 'BILLING_CLERK'];
if (!in_array($_SESSION['role_code'], $allowed_roles)) {
    echo json_encode(['success' => false, 'message' => 'Access denied']);
    exit();
}

if ($_SERVER['REQUEST_METHOD'] !== 'POST') {
    echo json_encode(['success' => false, 'message' => 'Invalid method']);
    exit();
}

$item_id        = (int)($_POST['item_id']        ?? 0);
$invoice_id     = (int)($_POST['invoice_id']     ?? 0);
$apply_payment  = (int)($_POST['apply_payment']  ?? 0);
$user_id        = (int)$_SESSION['user_id'];
$post_ms        = strtoupper(trim($_POST['match_status'] ?? ''));
$allowed_statuses = ['DISPUTED', 'UNMATCHED'];
$force_status   = in_array($post_ms, $allowed_statuses) ? $post_ms : null;

if (!$item_id) {
    echo json_encode(['success' => false, 'message' => 'Invalid item ID']);
    exit();
}

// ── Load remittance item ──────────────────────────────────────────────────────
$stmt = $conn->prepare(
    "SELECT ri.*, r.insurance_provider_id, r.remittance_id, r.payment_method, r.status AS rem_status
     FROM insurance_remittance_items ri
     JOIN insurance_remittances r ON ri.remittance_id = r.remittance_id
     WHERE ri.item_id = ?"
);
$stmt->bind_param('i', $item_id);
$stmt->execute();
$item = $stmt->get_result()->fetch_assoc();
$stmt->close();

if (!$item) {
    echo json_encode(['success' => false, 'message' => 'Remittance item not found']);
    exit();
}
if ($item['match_status'] === 'MANUAL_MATCHED' || $item['applied_at']) {
    echo json_encode(['success' => false, 'message' => 'Payment already applied to this item']);
    exit();
}

$conn->begin_transaction();

try {
    // Update item with invoice match (or forced status e.g. DISPUTED)
    $new_ms = $invoice_id ? 'MANUAL_MATCHED' : ($force_status ?? $item['match_status']);
    $upd = $conn->prepare(
        "UPDATE insurance_remittance_items
         SET invoice_id = ?, match_status = ?
         WHERE item_id = ?"
    );
    $inv_nullable = $invoice_id ?: null;
    $upd->bind_param('isi', $inv_nullable, $new_ms, $item_id);
    $upd->execute();
    $upd->close();

    if ($apply_payment && $invoice_id && $item['amount_paid'] > 0) {
        // Validate invoice exists and is for this insurer
        $inv_stmt = $conn->prepare(
            "SELECT invoice_id, total_amount, amount_paid, balance, status
             FROM invoices WHERE invoice_id = ? AND insurance_provider_id = ?"
        );
        $inv_stmt->bind_param('ii', $invoice_id, $item['insurance_provider_id']);
        $inv_stmt->execute();
        $inv = $inv_stmt->get_result()->fetch_assoc();
        $inv_stmt->close();

        if (!$inv) throw new Exception('Invoice not found or belongs to a different insurer');

        $pay_amount = min((float)$item['amount_paid'], (float)$inv['balance']);
        if ($pay_amount <= 0) throw new Exception('Invoice has no outstanding balance');

        // Insert payment record
        $cnt_r  = $conn->query("SELECT COUNT(*) AS c FROM payments WHERE DATE(created_at) = CURDATE()");
        $pay_no = 'PAY-' . date('Ymd') . '-' . str_pad((int)$cnt_r->fetch_assoc()['c'] + 1, 4, '0', STR_PAD_LEFT);

        $pay_stmt = $conn->prepare(
            "INSERT INTO payments
                (payment_number, invoice_id, amount, payment_date, payment_method,
                 payment_status, reference_number, received_by, notes, created_at)
             VALUES (?,?,?,CURDATE(),?,'COMPLETED',?,?,?,NOW())"
        );
        $pay_notes = "Reconciled via remittance item #{$item_id}";
        $pay_stmt->bind_param('ssdssss', $pay_no, $invoice_id, $pay_amount,
                              $item['payment_method'], $item['claim_number'] ?? '',
                              $user_id, $pay_notes);
        $pay_stmt->execute();
        $pay_stmt->close();

        // Update invoice amount_paid and status
        $new_paid = (float)$inv['amount_paid'] + $pay_amount;
        $new_bal  = (float)$inv['total_amount'] - $new_paid;
        $new_status = $new_bal <= 0.01 ? 'PAID' : 'PARTIAL_PAYMENT';

        $inv_upd = $conn->prepare(
            "UPDATE invoices SET amount_paid = ?, balance = ?, status = ?, updated_at = NOW()
             WHERE invoice_id = ?"
        );
        $inv_upd->bind_param('ddsi', $new_paid, $new_bal, $new_status, $invoice_id);
        $inv_upd->execute();
        $inv_upd->close();

        // Mark item as applied
        $conn->prepare(
            "UPDATE insurance_remittance_items SET applied_at = NOW(), applied_by = ? WHERE item_id = ?"
        )->execute() || null;
        $ai_stmt = $conn->prepare("UPDATE insurance_remittance_items SET applied_at = NOW(), applied_by = ? WHERE item_id = ?");
        $ai_stmt->bind_param('ii', $user_id, $item_id);
        $ai_stmt->execute();
        $ai_stmt->close();

        // Update remittance allocated_amount and status
        $conn->query(
            "UPDATE insurance_remittances
             SET allocated_amount = (
                 SELECT COALESCE(SUM(ri2.amount_paid), 0)
                 FROM insurance_remittance_items ri2
                 WHERE ri2.remittance_id = {$item['remittance_id']}
                   AND ri2.applied_at IS NOT NULL
             ),
             status = IF(
                 (SELECT COALESCE(SUM(ri3.amount_paid), 0) FROM insurance_remittance_items ri3
                  WHERE ri3.remittance_id = {$item['remittance_id']} AND ri3.applied_at IS NULL) < 0.01,
                 'RECONCILED', 'PARTIAL'
             ),
             updated_at = NOW()
             WHERE remittance_id = {$item['remittance_id']}"
        );
    }

    // Activity log
    $log_d = "Applied remittance item #{$item_id} (KES {$item['amount_paid']}) to invoice #{$invoice_id}";
    $ip    = $_SERVER['REMOTE_ADDR'] ?? '';
    $log_s = $conn->prepare("INSERT INTO activity_logs (user_id, action, entity_type, entity_id, description, ip_address, status) VALUES (?, 'UPDATE', 'REMITTANCE', ?, ?, ?, 'SUCCESS')");
    $log_s->bind_param('iiss', $user_id, $item_id, $log_d, $ip);
    $log_s->execute();
    $log_s->close();

    $conn->commit();
    echo json_encode(['success' => true, 'message' => 'Payment applied successfully']);

} catch (Exception $e) {
    $conn->rollback();
    echo json_encode(['success' => false, 'message' => 'Error: ' . $e->getMessage()]);
}
