<?php
/**
 * api/pawn/pledge_payment_add.php
 * Cash Module 2.0 — সরাসরি cash_transactions INSERT
 * Language Updated:
 *   সুদ / Interest wording -> লকার ভাড়া
 * Audit:
 *   1) pawn_payments INSERT
 *   2) pawn_pledges UPDATE
 *   3) cash_transactions INSERT for locker rent
 *   4) cash_transactions INSERT for principal
 *
 * POST: pledge_id, payment_date, cash_account_id, interest_paid, principal_paid, note
 *
 * NOTE:
 * DB column interest_paid রাখা হয়েছে, কারণ database structure change করা হচ্ছে না।
 * User-facing note/audit ভাষা হবে "লকার ভাড়া"।
 */

require_once __DIR__ . '/../../config/db.php';

header('Content-Type: application/json; charset=utf-8');

if (session_status() === PHP_SESSION_NONE) {
    session_start();
}

$user_id = (int)($_SESSION['user_id'] ?? 1);
$ip      = $_SERVER['REMOTE_ADDR'] ?? '127.0.0.1';

function pp_send($success, $message, $extra = [], $code = 200)
{
    http_response_code($code);
    echo json_encode(array_merge([
        'success' => $success,
        'message' => $message
    ], $extra), JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES);
    exit;
}

/**
 * Safe Audit Logger
 * Audit fail হলেও payment বন্ধ হবে না।
 */
function pledge_payment_safe_audit_log($pdo, $tableName, $recordId, $action, $changedBy, $note = '')
{
    try {
        if (!$pdo || !($pdo instanceof PDO)) {
            return;
        }

        $ipAddress = $_SERVER['REMOTE_ADDR'] ?? '';

        $stmt = $pdo->prepare("
            INSERT INTO audit_log
                (table_name, record_id, action, changed_by, changed_at, ip_address, note)
            VALUES
                (:table_name, :record_id, :action, :changed_by, NOW(), :ip_address, :note)
        ");

        $stmt->execute([
            ':table_name' => $tableName,
            ':record_id'  => (int)$recordId,
            ':action'     => $action,
            ':changed_by' => (int)$changedBy,
            ':ip_address' => $ipAddress,
            ':note'       => $note
        ]);

    } catch (Throwable $e) {
        return;
    }
}

// ── Input ────────────────────────────────────────────────────
$pledge_id       = (int)($_POST['pledge_id'] ?? 0);
$payment_date    = $_POST['payment_date'] ?? date('Y-m-d');
$cash_account_id = (int)($_POST['cash_account_id'] ?? 0);
$locker_rent     = round((float)($_POST['interest_paid'] ?? 0), 2);   // DB field old name
$principal_paid  = round((float)($_POST['principal_paid'] ?? 0), 2);
$note            = trim((string)($_POST['note'] ?? ''));

// ── Validation ───────────────────────────────────────────────
if ($pledge_id <= 0) {
    pp_send(false, 'pledge_id দেওয়া হয়নি।', [], 422);
}

if ($cash_account_id <= 0) {
    pp_send(false, 'Cash account নির্বাচন করুন।', [], 422);
}

$total_payment = round($locker_rent + $principal_paid, 2);

if ($total_payment <= 0) {
    pp_send(false, 'কমপক্ষে লকার ভাড়া অথবা মূল টাকা দিন।', [], 422);
}

// ── Load pledge ──────────────────────────────────────────────
$s = $pdo->prepare("
    SELECT 
        p.*, 
        pa.name AS party_name 
    FROM pawn_pledges p 
    LEFT JOIN parties pa ON pa.id = p.party_id 
    WHERE p.id = ? 
    LIMIT 1
");
$s->execute([$pledge_id]);
$pledge = $s->fetch(PDO::FETCH_ASSOC);

if (!$pledge) {
    pp_send(false, 'বন্ধক পাওয়া যায়নি।', [], 404);
}

if (($pledge['status'] ?? '') === 'CLOSED') {
    pp_send(false, 'এই বন্ধক বন্ধ হয়ে গেছে।', [], 422);
}

$outstanding = round((float)($pledge['outstanding_principal'] ?? 0), 2);

if ($principal_paid > $outstanding + 0.01) {
    pp_send(false, 'মূল টাকা বকেয়ার বেশি হতে পারে না।', [], 422);
}

// ── Cash account check ───────────────────────────────────────
$ca = $pdo->prepare("
    SELECT id, account_name 
    FROM cash_accounts 
    WHERE id = ? AND is_active = 1 
    LIMIT 1
");
$ca->execute([$cash_account_id]);
$account = $ca->fetch(PDO::FETCH_ASSOC);

if (!$account) {
    pp_send(false, 'Cash account সক্রিয় নেই।', [], 404);
}

// ── Voucher number helper ────────────────────────────────────
function makeVoucher(PDO $pdo): string
{
    $ym     = date('Ym');
    $prefix = 'CV-' . $ym . '-';

    $stmt = $pdo->prepare("
        SELECT COUNT(*) 
        FROM cash_transactions 
        WHERE voucher_no LIKE ?
    ");
    $stmt->execute([$prefix . '%']);

    $row = $stmt->fetchColumn();

    return $prefix . str_pad((int)$row + 1, 4, '0', STR_PAD_LEFT);
}

// ── Transaction ──────────────────────────────────────────────
try {
    $pdo->beginTransaction();

    // 1. pawn_payments
    // DB column interest_paid রাখা হয়েছে, কিন্তু business wording হলো "লকার ভাড়া"
    $ins = $pdo->prepare("
        INSERT INTO pawn_payments
            (
                pledge_id,
                payment_date,
                amount,
                interest_paid,
                principal_paid,
                cash_account_id,
                note,
                created_at
            )
        VALUES
            (?, ?, ?, ?, ?, ?, ?, NOW())
    ");

    $ins->execute([
        $pledge_id,
        $payment_date,
        $total_payment,
        $locker_rent,
        $principal_paid,
        $cash_account_id,
        $note
    ]);

    $pawn_payment_id = (int)$pdo->lastInsertId();

    // 2. Update outstanding
    $new_outstanding = round(max(0, $outstanding - $principal_paid), 2);

    $pdo->prepare("
        UPDATE pawn_pledges 
        SET outstanding_principal = ? 
        WHERE id = ?
    ")->execute([
        $new_outstanding,
        $pledge_id
    ]);

    $lockerRentTxnId = 0;
    $principalTxnId  = 0;
    $lockerRentVoucher = '';
    $principalVoucher  = '';

    // 3. Cash IN — লকার ভাড়া category_id=4
    if ($locker_rent > 0) {
        $lockerRentVoucher = makeVoucher($pdo);

        $note1 = 'লকার ভাড়া | ' . ($pledge['pledge_code'] ?? '') . ' | ' . ($pledge['party_name'] ?? '');
        if ($note !== '') {
            $note1 .= ' | ' . $note;
        }

        $stmtRent = $pdo->prepare("
            INSERT INTO cash_transactions
                (
                    voucher_no,
                    transaction_date,
                    cash_account_id,
                    category_id,
                    direction,
                    amount,
                    note,
                    reference_type,
                    reference_id,
                    party_id,
                    pledge_id,
                    created_by,
                    created_ip,
                    created_at
                )
            VALUES
                (?, ?, ?, 4, 'IN', ?, ?, 'PLEDGE', ?, ?, ?, ?, ?, NOW())
        ");

        $stmtRent->execute([
            $lockerRentVoucher,
            $payment_date,
            $cash_account_id,
            $locker_rent,
            $note1,
            $pawn_payment_id,
            $pledge['party_id'],
            $pledge_id,
            $user_id,
            $ip
        ]);

        $lockerRentTxnId = (int)$pdo->lastInsertId();

        $pdo->prepare("
            UPDATE cash_accounts 
            SET current_balance = current_balance + ? 
            WHERE id = ?
        ")->execute([
            $locker_rent,
            $cash_account_id
        ]);
    }

    // 4. Cash IN — মূল টাকা category_id=5
    if ($principal_paid > 0) {
        $principalVoucher = makeVoucher($pdo);

        $note2 = 'মূল টাকা ফেরত | ' . ($pledge['pledge_code'] ?? '') . ' | ' . ($pledge['party_name'] ?? '');
        if ($note !== '') {
            $note2 .= ' | ' . $note;
        }

        $stmtPrincipal = $pdo->prepare("
            INSERT INTO cash_transactions
                (
                    voucher_no,
                    transaction_date,
                    cash_account_id,
                    category_id,
                    direction,
                    amount,
                    note,
                    reference_type,
                    reference_id,
                    party_id,
                    pledge_id,
                    created_by,
                    created_ip,
                    created_at
                )
            VALUES
                (?, ?, ?, 5, 'IN', ?, ?, 'PLEDGE', ?, ?, ?, ?, ?, NOW())
        ");

        $stmtPrincipal->execute([
            $principalVoucher,
            $payment_date,
            $cash_account_id,
            $principal_paid,
            $note2,
            $pawn_payment_id,
            $pledge['party_id'],
            $pledge_id,
            $user_id,
            $ip
        ]);

        $principalTxnId = (int)$pdo->lastInsertId();

        $pdo->prepare("
            UPDATE cash_accounts 
            SET current_balance = current_balance + ? 
            WHERE id = ?
        ")->execute([
            $principal_paid,
            $cash_account_id
        ]);
    }

    /**
     * Audit 1: pawn_payments INSERT
     */
    $auditPaymentNote = "Pledge payment received"
        . " | Pledge: " . ($pledge['pledge_code'] ?? '')
        . " | Party: " . ($pledge['party_name'] ?? '')
        . " | Total: " . number_format($total_payment, 2)
        . " | Locker Rent: " . number_format($locker_rent, 2)
        . " | Principal: " . number_format($principal_paid, 2)
        . " | Cash Account: " . ($account['account_name'] ?? '') . " (#" . $cash_account_id . ")";

    pledge_payment_safe_audit_log(
        $pdo,
        'pawn_payments',
        $pawn_payment_id,
        'INSERT',
        $user_id,
        $auditPaymentNote
    );

    /**
     * Audit 2: pawn_pledges UPDATE
     */
    $auditPledgeNote = "Pawn outstanding updated after payment"
        . " | Pledge: " . ($pledge['pledge_code'] ?? '')
        . " | Old Outstanding: " . number_format($outstanding, 2)
        . " | Principal Paid: " . number_format($principal_paid, 2)
        . " | New Outstanding: " . number_format($new_outstanding, 2);

    pledge_payment_safe_audit_log(
        $pdo,
        'pawn_pledges',
        $pledge_id,
        'UPDATE',
        $user_id,
        $auditPledgeNote
    );

    /**
     * Audit 3: Locker rent cash transaction
     */
    if ($lockerRentTxnId > 0) {
        $auditRentNote = "Locker rent cash received"
            . " | Pledge: " . ($pledge['pledge_code'] ?? '')
            . " | Payment ID: " . $pawn_payment_id
            . " | Voucher: " . $lockerRentVoucher
            . " | Amount: " . number_format($locker_rent, 2);

        pledge_payment_safe_audit_log(
            $pdo,
            'cash_transactions',
            $lockerRentTxnId,
            'INSERT',
            $user_id,
            $auditRentNote
        );
    }

    /**
     * Audit 4: Principal cash transaction
     */
    if ($principalTxnId > 0) {
        $auditPrincipalNote = "Pawn principal cash received"
            . " | Pledge: " . ($pledge['pledge_code'] ?? '')
            . " | Payment ID: " . $pawn_payment_id
            . " | Voucher: " . $principalVoucher
            . " | Amount: " . number_format($principal_paid, 2);

        pledge_payment_safe_audit_log(
            $pdo,
            'cash_transactions',
            $principalTxnId,
            'INSERT',
            $user_id,
            $auditPrincipalNote
        );
    }

    $pdo->commit();

    echo json_encode([
        'success'         => true,
        'message'         => 'লকার ভাড়া পেমেন্ট সংরক্ষিত হয়েছে।',
        'pawn_payment_id' => $pawn_payment_id,
        'pledge_code'     => $pledge['pledge_code'],
        'party_name'      => $pledge['party_name'] ?? '',
        'total_paid'      => $total_payment,
        'locker_rent'     => $locker_rent,
        'interest_paid'   => $locker_rent,
        'principal_paid'  => $principal_paid,
        'new_outstanding' => $new_outstanding,
        'account_name'    => $account['account_name'],
        'locker_rent_txn_id' => $lockerRentTxnId,
        'principal_txn_id'   => $principalTxnId
    ], JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES);

} catch (Throwable $e) {
    if (isset($pdo) && $pdo instanceof PDO && $pdo->inTransaction()) {
        $pdo->rollBack();
    }

    echo json_encode([
        'success' => false,
        'message' => 'DB error: ' . $e->getMessage()
    ], JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES);
}