403Webshell
Server IP : 72.60.21.38  /  Your IP : 216.73.216.25
Web Server : LiteSpeed
System : Linux uk-fast-web1372.main-hosting.eu 4.18.0-553.121.1.lve.el8.x86_64 #1 SMP Thu Apr 30 16:40:41 UTC 2026 x86_64
User : u390967363 ( 390967363)
PHP Version : 8.2.30
Disable Function : system, exec, shell_exec, passthru, mysql_list_dbs, ini_alter, dl, symlink, link, chgrp, leak, popen, apache_child_terminate, virtual, mb_send_mail
MySQL : OFF  |  cURL : ON  |  WGET : ON  |  Perl : OFF  |  Python : OFF  |  Sudo : OFF  |  Pkexec : OFF
Directory :  /home/u390967363/domains/aibenproperties.com/public_html/app/

Upload File :
current_dir [ Writeable ] document_root [ Writeable ]

 

Command :


[ Back ]     

Current File : /home/u390967363/domains/aibenproperties.com/public_html/app/finance-payments.php
<?php
$GLOBALS['SKIP_GUARDS'] = true;
if ($_SERVER['REQUEST_METHOD'] === 'POST' && (isset($_POST['pm_action']) || isset($_POST['tx_action']))) {
    $GLOBALS['JSON_MODE'] = true;
}
if (session_status() === PHP_SESSION_NONE) { session_start(); }
require_once __DIR__ . '/includes/db.php';
require_once __DIR__ . '/includes/functions.php';
global $pdo;
if (function_exists('ensureFinancialControlsColumns')) { ensureFinancialControlsColumns(); }
$roleRaw = $_SESSION['user_role'] ?? 'guest';
$role = strtolower(str_replace([' ', '-'], '_', (string)$roleRaw));
$userId = (int)($_SESSION['user_id'] ?? 0);
$companyId = function_exists('getCurrentCompanyId') ? getCurrentCompanyId() : ($_SESSION['company_id'] ?? null);
$isAdminTier = in_array($role, ['admin','super_admin']);
$canVerify = in_array($role, ['finance','finance_officer','finance_manager','accountant','super_admin']);
$canApprovePayments = in_array($role, ['finance_manager','super_admin'], true);
$isAdminReadOnly = ($role === 'admin');
$applyCompanyFilter = $companyId && !$isAdminTier;
if ($isAdminReadOnly) {
    if (!empty($GLOBALS['JSON_MODE'])) {
        header('Content-Type: application/json; charset=UTF-8');
        http_response_code(403);
        echo json_encode(['ok' => false, 'message' => 'Access denied.'], JSON_UNESCAPED_SLASHES);
        exit;
    }
    header('Location: approved-payments.php');
    exit;
}

require_once __DIR__ . '/includes/header.php';
$queueStatuses = function_exists('kpiFinanceQueuePaymentStatuses')
    ? (array)kpiFinanceQueuePaymentStatuses()
    : ['pending_verification','pending_confirmation','pending_gateway','payment_verification','awaiting_verification','pending','submitted'];
$queueStatusesSql = "('" . implode("','", $queueStatuses) . "')";

function colExists($table, $col) {
    static $CACHE = [];
    global $pdo;
    $t = strtolower($table);
    $c = strtolower($col);
    if (isset($CACHE[$t])) {
        return in_array($c, $CACHE[$t], true);
    }
    try {
        $stmt = $pdo->query("SHOW COLUMNS FROM `$table`");
        $cols = $stmt ? $stmt->fetchAll(PDO::FETCH_COLUMN) : [];
        $cols = array_map('strtolower', $cols ?: []);
        $CACHE[$t] = $cols;
        return in_array($c, $cols, true);
    } catch (Throwable $e) {
        $CACHE[$t] = [];
        return false;
    }
}

$pdo->exec("
    CREATE TABLE IF NOT EXISTS transactions (
        id INT AUTO_INCREMENT PRIMARY KEY,
        user_id INT NOT NULL,
        property_id INT NULL,
        company_id INT NULL,
        transaction_type ENUM('form_fee','property_deposit','installment_payment','full_payment') NOT NULL,
        reference VARCHAR(100),
        amount DECIMAL(12,2),
        payment_method VARCHAR(50) DEFAULT 'bank_transfer',
        receipt_file VARCHAR(255),
        status ENUM('pending_verification','approved','rejected') DEFAULT 'pending_verification',
        created_at DATETIME DEFAULT CURRENT_TIMESTAMP,
        verified_at DATETIME NULL,
        verified_by INT NULL
    )
");
$repairCount = 0;
try {
    $hasForms = $pdo->query("SHOW TABLES LIKE 'client_forms'")->rowCount() > 0;
    $hasPayments = $pdo->query("SHOW TABLES LIKE 'payments'")->rowCount() > 0;
    if ($hasForms && $hasPayments) {
        $formCols0 = ['id','client_id','company_id','amount_due','receipt_path'];
        $tsCol0 = colExists('client_forms','updated_at') ? 'updated_at' : (colExists('client_forms','created_at') ? 'created_at' : null);
        if ($tsCol0) { $formCols0[] = $tsCol0 . " AS form_ts"; }
        $qf = "SELECT " . implode(',', $formCols0) . " FROM client_forms WHERE receipt_path IS NOT NULL AND TRIM(receipt_path) <> ''";
        $sf = $pdo->query($qf);
        $forms = $sf ? $sf->fetchAll(PDO::FETCH_ASSOC) : [];
        foreach ($forms as $f) {
            $rid = (int)($f['id'] ?? 0);
            $cid = (int)($f['client_id'] ?? 0);
            $cmp = $f['company_id'] ?? null;
            $amt = (float)($f['amount_due'] ?? 0);
            if ($amt <= 0) { $amt = 30000; }
            $path = (string)($f['receipt_path'] ?? '');
            if ($cid <= 0 || $path === '') { continue; }
            $formTs = (string)($f['form_ts'] ?? '');
            if ($formTs === '' || $formTs === '0000-00-00 00:00:00') { $formTs = date('Y-m-d H:i:s'); }
            $receiptCol = null;
            if (colExists('payments','receipt_file')) { $receiptCol = 'receipt_file'; }
            elseif (colExists('payments','proof_file')) { $receiptCol = 'proof_file'; }
            if ($receiptCol && $formTs !== '' && (colExists('payments','created_at') || colExists('payments','date')) && colExists('payments','reference')) {
                $set = [];
                $updParams = [];
                if (colExists('payments','created_at')) { $set[] = "created_at = ?"; $updParams[] = $formTs; }
                if (colExists('payments','date')) { $set[] = "date = ?"; $updParams[] = date('Y-m-d', strtotime($formTs)); }
                if (!empty($set)) {
                    $updSql = "UPDATE payments SET " . implode(',', $set) . " WHERE user_id = ? AND {$receiptCol} = ? AND UPPER(reference) LIKE 'FORM_FEE%'";
                    $updParams[] = $cid;
                    $updParams[] = $path;
                    if (colExists('payments','created_at')) {
                        $updSql .= " AND (created_at IS NULL OR created_at = '' OR created_at > DATE_ADD(?, INTERVAL 6 HOUR) OR created_at < DATE_SUB(?, INTERVAL 6 HOUR))";
                        $updParams[] = $formTs;
                        $updParams[] = $formTs;
                    } elseif (colExists('payments','date')) {
                        $updSql .= " AND (date IS NULL OR date = '' OR date > DATE_ADD(DATE(?), INTERVAL 1 DAY) OR date < DATE_SUB(DATE(?), INTERVAL 1 DAY))";
                        $updParams[] = $formTs;
                        $updParams[] = $formTs;
                    }
                    try { $pdo->prepare($updSql)->execute($updParams); } catch (Throwable $eU0) {}
                }
            }
            $existsSql = "SELECT COUNT(*) FROM payments WHERE user_id = ? AND status IN ('pending_verification','approved','rejected','duplicate')";
            $ep = [$cid];
            if ($receiptCol) { $existsSql .= " AND {$receiptCol} = ?"; $ep[] = $path; }
            if (!$receiptCol && colExists('payments','reference')) { $existsSql .= " AND UPPER(reference) LIKE 'FORM_FEE%'"; }
            $es = $pdo->prepare($existsSql); $es->execute($ep);
            if ((int)$es->fetchColumn() === 0) {
                $cols = ['user_id','amount','status'];
                $vals = [$cid, $amt, 'pending_verification'];
                $place = '?,?,?';
                $refVal = 'FORM_FEE-' . $rid;
                if (colExists('payments','payment_method')) { $cols[]='payment_method'; $vals[]='bank_transfer'; $place .= ',?'; }
                elseif (colExists('payments','method')) { $cols[]='method'; $vals[]='bank_transfer'; $place .= ',?'; }
                if (colExists('payments','reference')) { $cols[]='reference'; $vals[]=$refVal; $place .= ',?'; }
                if (colExists('payments','receipt_file')) { $cols[]='receipt_file'; $vals[]=$path; $place .= ',?'; }
                elseif (colExists('payments','proof_file')) { $cols[]='proof_file'; $vals[]=$path; $place .= ',?'; }
                if (colExists('payments','company_id') && $cmp) { $cols[]='company_id'; $vals[]=$cmp; $place .= ',?'; }
                if (colExists('payments','created_at')) { $cols[]='created_at'; $vals[]=$formTs; $place .= ',?'; }
                if (colExists('payments','date')) { $cols[]='date'; $vals[]=date('Y-m-d', strtotime($formTs)); $place .= ',?'; }
                $ins = $pdo->prepare("INSERT INTO payments (".implode(',', $cols).") VALUES ($place)");
                $ins->execute($vals);
                $repairCount++;
            }
        }
    }
} catch (Throwable $e) {}

$syncCount = 0;
try {
    $hasTx = $pdo->query("SHOW TABLES LIKE 'transactions'")->rowCount() > 0;
    $hasPayments = $pdo->query("SHOW TABLES LIKE 'payments'")->rowCount() > 0;
    if ($hasTx && $hasPayments) {
        $colReceipt = 'receipt_file';
        if (!colExists('payments','receipt_file') && colExists('payments','proof_file')) { $colReceipt = 'proof_file'; }
        $dateCol = colExists('payments','created_at') ? 'created_at' : (colExists('payments','date') ? 'date' : null);
        $sql = "SELECT id, user_id, amount, reference, $colReceipt AS receipt_file, status" . ($dateCol ? ", $dateCol AS created_at" : "") . " FROM payments WHERE status = 'pending_verification'";
        $st = $pdo->query($sql);
        $rowsP = $st ? $st->fetchAll(PDO::FETCH_ASSOC) : [];
        foreach ($rowsP as $p) {
            $uid = (int)($p['user_id'] ?? 0);
            if ($uid <= 0) { continue; }
            $rt = strtolower((string)($p['reference'] ?? ''));
            $type = (strpos($rt, 'form_fee') === 0) ? 'form_fee' : 'property_deposit';
            $dup = $pdo->prepare("SELECT id FROM transactions WHERE user_id = ? AND transaction_type = ? AND status = 'pending_verification' LIMIT 1");
            $dup->execute([$uid, $type]);
            if ((int)($dup->fetchColumn() ?: 0) === 0) {
                $ins = $pdo->prepare("INSERT INTO transactions (user_id, amount, transaction_type, receipt_file, status, created_at) VALUES (?, ?, ?, ?, 'pending_verification', NOW())");
                $ins->execute([$uid, (float)($p['amount'] ?? 0), $type, (string)($p['receipt_file'] ?? '')]);
                $syncCount++;
            }
        }
    }
} catch (Throwable $e) {}

if (!empty($_GET['backfill_core'])) {
    try {
        $refCol = colExists('payments','reference') ? 'reference' : (colExists('payments','ref') ? 'ref' : null);
        $rcpCol = colExists('payments','receipt_file') ? 'receipt_file' : (colExists('payments','proof_file') ? 'proof_file' : null);
        $dateCol = colExists('payments','created_at') ? 'created_at' : (colExists('payments','date') ? 'date' : (colExists('payments','updated_at') ? 'updated_at' : null));
        $sql = "SELECT id, user_id" . ($refCol ? ", {$refCol} AS reference" : ", NULL AS reference") . ($rcpCol ? ", {$rcpCol} AS receipt_file" : ", NULL AS receipt_file") . ", " . ($dateCol ? "{$dateCol} AS created_at" : "NULL AS created_at") . (colExists('payments','deal_id') ? ", deal_id" : ", NULL AS deal_id") . " FROM payments WHERE " . ($refCol ? "{$refCol}" : "''") . " LIKE 'deal-submission-%' ORDER BY " . ($dateCol ?: 'id') . " DESC LIMIT 300";
        $st = $pdo->prepare($sql); $st->execute(); $prs = $st->fetchAll(PDO::FETCH_ASSOC) ?: [];
        $updDeals = 0; $linkCnt = 0; $scan = 0;
        foreach ($prs as $p) {
            $scan++;
            $pid = (int)($p['id'] ?? 0);
            $dealId = (int)($p['deal_id'] ?? 0);
            $created = (string)($p['created_at'] ?? '');
            $receipt = (string)($p['receipt_file'] ?? '');
            $uid = (int)($p['user_id'] ?? 0);
            if ($dealId <= 0) {
                $guess = 0;
                if ($receipt !== '') {
                    if (colExists('deals','receipt_file')) {
                        $q = $pdo->prepare("SELECT id FROM deals WHERE receipt_file = ? ORDER BY id DESC LIMIT 1"); $q->execute([$receipt]); $guess = (int)($q->fetchColumn() ?: 0);
                        if ($guess <= 0) { $b = basename($receipt); if ($b !== '') { $q = $pdo->prepare("SELECT id FROM deals WHERE receipt_file LIKE ? ORDER BY id DESC LIMIT 1"); $q->execute(['%'.$b]); $guess = (int)($q->fetchColumn() ?: 0); } }
                    } elseif (colExists('deals','proof_file')) {
                        $q = $pdo->prepare("SELECT id FROM deals WHERE proof_file = ? ORDER BY id DESC LIMIT 1"); $q->execute([$receipt]); $guess = (int)($q->fetchColumn() ?: 0);
                        if ($guess <= 0) { $b = basename($receipt); if ($b !== '') { $q = $pdo->prepare("SELECT id FROM deals WHERE proof_file LIKE ? ORDER BY id DESC LIMIT 1"); $q->execute(['%'.$b]); $guess = (int)($q->fetchColumn() ?: 0); } }
                    }
                }
                if ($guess <= 0 && $created !== '' && colExists('deals','created_at')) {
                    if ($uid > 0 && colExists('deals','user_id')) {
                        $q = $pdo->prepare("SELECT id FROM deals WHERE user_id = ? AND created_at BETWEEN DATE_SUB(?, INTERVAL 1 DAY) AND DATE_ADD(?, INTERVAL 1 DAY) ORDER BY created_at DESC LIMIT 1"); $q->execute([$uid, $created, $created]); $guess = (int)($q->fetchColumn() ?: 0);
                    } else {
                        $q = $pdo->prepare("SELECT id FROM deals WHERE created_at BETWEEN DATE_SUB(?, INTERVAL 1 DAY) AND DATE_ADD(?, INTERVAL 1 DAY) ORDER BY created_at DESC LIMIT 1"); $q->execute([$created, $created]); $guess = (int)($q->fetchColumn() ?: 0);
                    }
                }
                if ($guess > 0) {
                    $dealId = $guess;
                    $up = $pdo->prepare("UPDATE payments SET deal_id = ? WHERE id = ?"); $up->execute([$dealId, $pid]);
                    try { @file_put_contents(__DIR__ . '/debug_sql.txt', "PAYMENT_LINK:\nUPDATE payments SET deal_id = {$dealId} WHERE id = {$pid}\n", FILE_APPEND); } catch (Throwable $ePL) {}
                    $linkCnt++;
                }
            }
            if ($dealId > 0) {
                $dr = [];
                try { $qd = $pdo->prepare("SELECT * FROM deals WHERE id = ? LIMIT 1"); $qd->execute([$dealId]); $dr = $qd->fetch(PDO::FETCH_ASSOC) ?: []; } catch (Throwable $eD) {}
                $meta = [];
                if (!empty($dr) && isset($dr['meta_json']) && is_string($dr['meta_json']) && $dr['meta_json'] !== '') {
                    $m = json_decode($dr['meta_json'], true); if (is_array($m)) { $meta = $m; }
                } else {
                    if (colExists('payments','meta_json')) {
                        $qm = $pdo->prepare("SELECT meta_json FROM payments WHERE id = ? LIMIT 1"); $qm->execute([$pid]); $mj = (string)($qm->fetchColumn() ?: '');
                        if ($mj !== '') { $m = json_decode($mj, true); if (is_array($m)) { $meta = $m; } }
                    }
                }
                $get = function($arr, $keys) {
                    foreach ($keys as $k) { if (isset($arr[$k]) && $arr[$k] !== '' && $arr[$k] !== null) { return $arr[$k]; } }
                    return null;
                };
                $upd = [];
                if (colExists('deals','project_name')) { $v = $get($meta, ['project_desc','project_name','property','estate','project']); if (!$v && isset($dr['project_desc'])) { $v = $dr['project_desc']; } if ($v !== null && trim((string)($dr['project_name'] ?? '')) === '') { $upd['project_name'] = (string)$v; } }
                if (colExists('deals','project_desc')) { $v = $get($meta, ['project_desc','property','estate','project']); if ($v !== null && trim((string)($dr['project_desc'] ?? '')) === '') { $upd['project_desc'] = (string)$v; } }
                if (colExists('deals','deal_source')) { $v = $get($meta, ['deal_source','source','deal_source_type','lead_source']); if ($v !== null && trim((string)($dr['deal_source'] ?? '')) === '') { $upd['deal_source'] = (string)$v; } }
                if (colExists('deals','payment_plan')) { $v = $get($meta, ['plan_type','payment_plan','plan','plan_name']); if ($v !== null && trim((string)($dr['payment_plan'] ?? '')) === '') { $upd['payment_plan'] = (string)$v; } }
                if (colExists('deals','marketer_name')) { $v = $get($meta, ['marketer_name','Marketer Name','Marketer or Contact Centre Name','Marketer or Contact Center Name','Contact Centre Name','Contact Center Name','marketer','sales_agent','sales_rep','contact_rep','agent_name']); if ($v !== null && trim((string)($dr['marketer_name'] ?? '')) === '') { $upd['marketer_name'] = (string)$v; } }
                if (colExists('deals','amount_offered')) { $v = $get($meta, ['amount_offered']); if ($v !== null && (float)($dr['amount_offered'] ?? 0) == 0.0) { $upd['amount_offered'] = (float)$v; } }
                if (colExists('deals','amount_paid_so_far')) { $v = $get($meta, ['amount_paid_so_far']); if ($v !== null && (float)($dr['amount_paid_so_far'] ?? 0) == 0.0) { $upd['amount_paid_so_far'] = (float)$v; } }
                if (colExists('deals','commission_percent')) { $v = $get($meta, ['commission_pct','commission_percent']); if ($v !== null && (float)($dr['commission_percent'] ?? 0) == 0.0) { $upd['commission_percent'] = (float)$v; } }
                if (colExists('deals','discount_amount')) { $v = $get($meta, ['discount_amount']); if ($v !== null && (float)($dr['discount_amount'] ?? 0) == 0.0) { $upd['discount_amount'] = (float)$v; } }
                if (colExists('deals','balance_remaining')) { $v = $get($meta, ['balance_remaining']); if ($v !== null && (float)($dr['balance_remaining'] ?? 0) == 0.0) { $upd['balance_remaining'] = (float)$v; } }
                if (colExists('deals','notes')) { $v = $get($meta, ['client_payment_status','notes']); if ($v !== null && trim((string)($dr['notes'] ?? '')) === '') { $upd['notes'] = (string)$v; } }
                if (!empty($upd)) {
                    $sets = []; $vals = [];
                    foreach ($upd as $k=>$v) { $sets[] = "{$k} = ?"; $vals[] = $v; }
                    $vals[] = $dealId;
                    $u = $pdo->prepare("UPDATE deals SET ".implode(',', $sets)." WHERE id = ?");
                    $u->execute($vals);
                    try { @file_put_contents(__DIR__ . '/debug_sql.txt', "REPAIR_UPDATE_DEAL:\nUPDATE deals SET ".implode(',', $sets)." WHERE id = {$dealId}\nPARAMS:\n".print_r($vals, true)."\n", FILE_APPEND); } catch (Throwable $eRU) {}
                    $updDeals++;
                }
            }
        }
        echo "<pre>backfill_core\nscanned: {$scan}\nlinked_payments: {$linkCnt}\nupdated_deals: {$updDeals}\n</pre>";
        exit;
    } catch (Throwable $e) {
        echo "<pre>backfill_core_failed\n".(string)$e->getMessage()."</pre>";
        exit;
    }
}

// Ensure any client_forms receipts are present in transactions (form_fee)
try {
    $hasForms = $pdo->query("SHOW TABLES LIKE 'client_forms'")->rowCount() > 0;
    $hasTx = $pdo->query("SHOW TABLES LIKE 'transactions'")->rowCount() > 0;
    $hasPayments = $pdo->query("SHOW TABLES LIKE 'payments'")->rowCount() > 0;
    if ($hasForms && ($hasTx || $hasPayments)) {
        $formCols = ['client_id','receipt_path'];
        if (colExists('client_forms','amount_due')) { $formCols[] = 'amount_due'; }
        if (colExists('client_forms','company_id')) { $formCols[] = 'company_id'; }
        $tsCol = colExists('client_forms','updated_at') ? 'updated_at' : (colExists('client_forms','created_at') ? 'created_at' : null);
        if ($tsCol) { $formCols[] = $tsCol . ' AS form_ts'; }
        $qf = "SELECT " . implode(',', $formCols) . " FROM client_forms WHERE receipt_path IS NOT NULL AND TRIM(receipt_path) <> '' AND status IN ('payment_verification','pending_verification')";
        $stf = $pdo->query($qf);
        $formsRows = $stf ? $stf->fetchAll(PDO::FETCH_ASSOC) : [];
        foreach ($formsRows as $fr) {
            $cid = (int)($fr['client_id'] ?? 0);
            $rpath = (string)($fr['receipt_path'] ?? '');
            if ($cid <= 0 || $rpath === '') continue;
            $amtForm = (float)($fr['amount_due'] ?? 30000);
            if ($hasTx) {
                $dup = $pdo->prepare("SELECT id FROM transactions WHERE user_id = ? AND transaction_type = 'form_fee' AND receipt_file = ? AND status IN ('pending_verification','approved') LIMIT 1");
                $dup->execute([$cid, $rpath]);
                if ((int)($dup->fetchColumn() ?: 0) === 0) {
                    $ins = $pdo->prepare("INSERT INTO transactions (user_id, amount, transaction_type, receipt_file, status, created_at) VALUES (?, ?, 'form_fee', ?, 'pending_verification', NOW())");
                    $ins->execute([$cid, $amtForm, $rpath]);
                }
            }
            if ($hasPayments) {
                $payReceiptCol = colExists('payments','receipt_file') ? 'receipt_file' : (colExists('payments','proof_file') ? 'proof_file' : null);
                $existsStatusesSql = "('" . implode("','", array_merge($queueStatuses, ['approved','rejected','duplicate'])) . "')";
                $existsSql = "SELECT COUNT(*) FROM payments WHERE user_id = ?";
                $existsParams = [$cid];
                if ($payReceiptCol) { $existsSql .= " AND {$payReceiptCol} = ?"; $existsParams[] = $rpath; }
                if (colExists('payments','reference')) { $existsSql .= " AND UPPER(reference) LIKE 'FORM_FEE%'"; }
                $existsSql .= " AND status IN " . $existsStatusesSql;
                $stx = $pdo->prepare($existsSql);
                $stx->execute($existsParams);
                if ((int)($stx->fetchColumn() ?: 0) === 0) {
                    $cols = ['user_id','amount','status'];
                    $vals = [$cid, $amtForm, 'pending_verification'];
                    if (colExists('payments','payment_method')) { $cols[]='payment_method'; $vals[]='bank_transfer'; }
                    elseif (colExists('payments','method')) { $cols[]='method'; $vals[]='bank_transfer'; }
                    if (colExists('payments','reference')) { $cols[]='reference'; $vals[]='FORM_FEE-' . $cid . '-' . (string)($fr['form_ts'] ?? date('YmdHis')); }
                    if ($payReceiptCol) { $cols[]=$payReceiptCol; $vals[]=$rpath; }
                    $cmp = $fr['company_id'] ?? null;
                    if (colExists('payments','company_id') && $cmp) { $cols[]='company_id'; $vals[]=$cmp; }
                    $ts = (string)($fr['form_ts'] ?? '');
                    if ($ts !== '' && colExists('payments','created_at')) { $cols[]='created_at'; $vals[]=$ts; }
                    if (colExists('payments','date')) {
                        $d = $ts !== '' ? date('Y-m-d', strtotime($ts)) : date('Y-m-d');
                        if (!in_array('date', $cols, true)) { $cols[]='date'; $vals[]=$d; }
                    }
                    $ins = $pdo->prepare("INSERT INTO payments (".implode(',', $cols).") VALUES (".implode(',', array_fill(0,count($cols),'?')).")");
                    $ins->execute($vals);
                }
            }
        }
    }
} catch (Throwable $e) {}

// Migrate pending transactions into payments (one-time backfill)
try {
    $hasTx = $pdo->query("SHOW TABLES LIKE 'transactions'")->rowCount() > 0;
    $hasPayments = $pdo->query("SHOW TABLES LIKE 'payments'")->rowCount() > 0;
    if ($hasTx && $hasPayments) {
        $qtx = $pdo->query("SELECT id, user_id, amount, transaction_type, receipt_file, status, created_at, company_id FROM transactions WHERE status IN ('pending_verification','pending_confirmation') ORDER BY created_at DESC");
        $rowsTx = $qtx ? $qtx->fetchAll(PDO::FETCH_ASSOC) : [];
        foreach ($rowsTx as $t) {
            $uid = (int)($t['user_id'] ?? 0);
            $amt = (float)($t['amount'] ?? 0);
            $rcp = (string)($t['receipt_file'] ?? '');
            $stat = (string)($t['status'] ?? 'pending_verification');
            $cmp = $t['company_id'] ?? null;
            if ($uid <= 0) continue;
            $tt = strtolower((string)($t['transaction_type'] ?? ''));
            $txId = (int)($t['id'] ?? 0);
            $ref = ($tt !== '' ? strtoupper($tt) : 'PAYMENT') . '-TX-' . (string)$txId;
            if ($tt === 'form_fee') { $ref = 'FORM_FEE-TX-' . (string)$txId; }
            $final = function_exists('kpiPaymentFinalizedStatuses') ? array_map('strtolower', (array)kpiPaymentFinalizedStatuses()) : ['verified','approved','paid','completed','success'];
            $existsStatuses = array_values(array_unique(array_filter(array_merge($queueStatuses, $final, ['rejected','duplicate']))));
            $existsSql = "SELECT COUNT(*) FROM payments WHERE user_id = ? AND LOWER(TRIM(status)) IN (" . implode(',', array_fill(0, count($existsStatuses), '?')) . ")";
            $params = [$uid];
            foreach ($existsStatuses as $s0) { $params[] = strtolower(trim((string)$s0)); }
            if (colExists('payments','receipt_file') && $rcp !== '') { $existsSql .= " AND receipt_file = ?"; $params[] = $rcp; }
            elseif (colExists('payments','proof_file') && $rcp !== '') { $existsSql .= " AND proof_file = ?"; $params[] = $rcp; }
            $stx = $pdo->prepare($existsSql); $stx->execute($params);
            if ((int)($stx->fetchColumn() ?: 0) === 0) {
                $cols = ['user_id','amount','status'];
                $vals = [$uid, $amt, ($stat === 'pending_confirmation' ? 'pending_confirmation' : 'pending_verification')];
                if (colExists('payments','payment_method')) { $cols[]='payment_method'; $vals[]='bank_transfer'; }
                elseif (colExists('payments','method')) { $cols[]='method'; $vals[]='bank_transfer'; }
                if (colExists('payments','reference')) { $cols[]='reference'; $vals[]=$ref; }
                if (colExists('payments','receipt_file') && $rcp !== '') { $cols[]='receipt_file'; $vals[]=$rcp; }
                elseif (colExists('payments','proof_file') && $rcp !== '') { $cols[]='proof_file'; $vals[]=$rcp; }
                if (colExists('payments','company_id') && $cmp) { $cols[]='company_id'; $vals[]=$cmp; }
                $txTs = !empty($t['created_at']) ? (string)$t['created_at'] : '';
                if (colExists('payments','created_at') && $txTs !== '') { $cols[]='created_at'; $vals[]=$txTs; }
                if (colExists('payments','date')) {
                    $d = $txTs !== '' ? date('Y-m-d', strtotime($txTs)) : date('Y-m-d');
                    if (!in_array('date', $cols, true)) { $cols[]='date'; $vals[]=$d; }
                }
                $ins = $pdo->prepare("INSERT INTO payments (".implode(',', $cols).") VALUES (".implode(',', array_fill(0,count($cols),'?')).")");
                $ins->execute($vals);
            }
        }
    }
} catch (Throwable $e) {}

$action_msg = '';
if ($canVerify && $_SERVER['REQUEST_METHOD'] !== 'POST') {
    try {
        $stmt = $pdo->prepare("
            SELECT 
                p.id AS payment_id, 
                p.user_id, 
                p.deal_id, 
                p.client_name, 
                p.client_email, 
                p.amount, 
                p.status, 
                p.reference, 
                p.created_at, 
                p.meta_json AS payment_meta, 

                d.id AS deal_id, 
                d.project_name, 
                d.project_desc, 
                d.deal_source, 
                d.payment_plan, 
                d.marketer_name, 
                d.amount_offered, 
                d.amount_paid_so_far, 
                d.discount_amount, 
                d.commission_percent, 
                d.balance_remaining, 
                d.notes, 
                d.meta_json AS deal_meta,

                ds.submitted_by AS ds_submitted_by,
                ds.marketer_name AS ds_marketer_name,
                ds.notes AS ds_notes,
                ds.marketer_bank AS ds_marketer_bank,
                ds.agent_bank AS ds_agent_bank,
                ds.meta_json AS ds_meta

            FROM payments p 
            LEFT JOIN deals d ON p.deal_id = d.id 
            LEFT JOIN deals_submit ds ON " . (colExists('payments','deal_id') ? "p.deal_id = ds.id" : "p.user_id = ds.user_id") . " 
            ORDER BY p.id DESC
        ");
        $stmt->execute();
        $rows = $stmt->fetchAll(PDO::FETCH_ASSOC);
        try { @file_put_contents(__DIR__ . '/debug_finance.txt', "FINANCE_ROWS_JOIN:\n".print_r($rows, true)."\n", FILE_APPEND); } catch (Throwable $eDbgF3) {}
        if (!empty($_GET['break_finance'])) { echo "<pre>"; print_r($rows); echo "</pre>"; exit; }
        foreach ($rows as $row) {
            if (!empty($_GET['debug_finance'])) {
                echo "<pre style=\"white-space:pre-wrap; background:#fee; border:1px solid #f99; padding:8px;\">";
                echo "payment_row:\n"; print_r($row);
                echo "</pre>";
            }
            // Decode meta fields
            $dealMeta = !empty($row['deal_meta']) ? (json_decode($row['deal_meta'], true) ?: []) : [];
            $paymentMeta = !empty($row['payment_meta']) ? (json_decode($row['payment_meta'], true) ?: []) : [];
            $dsMeta = !empty($row['ds_meta']) ? (json_decode($row['ds_meta'], true) ?: []) : [];
            // Merge for downstream helpers (priority: payment > deal_submit > deal)
            $meta = array_merge(is_array($dealMeta)?$dealMeta:[], is_array($dsMeta)?$dsMeta:[], is_array($paymentMeta)?$paymentMeta:[]);
            // Inject explicit fields from deals_submit when present
            if (!empty($row['ds_marketer_name']) && empty($meta['marketer_name'])) { $meta['marketer_name'] = (string)$row['ds_marketer_name']; }
            if (!empty($row['ds_submitted_by']) && empty($meta['submitted_by_name'])) { $meta['submitted_by_name'] = (string)$row['ds_submitted_by']; }
            if (!empty($row['ds_notes']) && empty($meta['notes'])) { $meta['notes'] = (string)$row['ds_notes']; }
            // Inject bank details from deals_submit columns if not present in meta
            try {
                if (empty($meta['marketer_bank']) && !empty($row['ds_marketer_bank'])) {
                    $mb = $row['ds_marketer_bank'];
                    if (is_string($mb)) { $mb = json_decode($mb, true) ?: []; }
                    if (is_array($mb) && (!empty($mb['acc_no']) || !empty($mb['bank']) || !empty($mb['acc_name']))) {
                        $meta['marketer_bank'] = [
                            'acc_no' => trim((string)($mb['acc_no'] ?? '')),
                            'bank' => trim((string)($mb['bank'] ?? ($mb['bank_name'] ?? ($mb['bankName'] ?? '')))),
                            'acc_name' => trim((string)($mb['acc_name'] ?? ($mb['account_name'] ?? ($mb['accountName'] ?? ''))))
                        ];
                    }
                }
                if (empty($meta['agent_bank']) && !empty($row['ds_agent_bank'])) {
                    $ab = $row['ds_agent_bank'];
                    if (is_string($ab)) { $ab = json_decode($ab, true) ?: []; }
                    if (is_array($ab) && (!empty($ab['acc_no']) || !empty($ab['bank']) || !empty($ab['acc_name']))) {
                        $meta['agent_bank'] = [
                            'acc_no' => trim((string)($ab['acc_no'] ?? '')),
                            'bank' => trim((string)($ab['bank'] ?? ($ab['bank_name'] ?? ($ab['bankName'] ?? '')))),
                            'acc_name' => trim((string)($ab['acc_name'] ?? ($ab['account_name'] ?? ($ab['accountName'] ?? ''))))
                        ];
                    }
                }
            } catch (Throwable $eDSBanks) {}
            if (empty($meta) || !is_array($meta)) {
                try {
                    $uid = (int)($row['user_id'] ?? 0);
                    if ($uid > 0 && colExists('deals_submit','user_id') && colExists('deals_submit','meta_json')) {
                        $qs = $pdo->prepare("SELECT meta_json, submitted_by, marketer_name, notes FROM deals_submit WHERE user_id = ? ORDER BY id DESC LIMIT 1");
                        $qs->execute([$uid]);
                        $drs = $qs->fetch(PDO::FETCH_ASSOC) ?: [];
                        if (!empty($drs)) {
                            $dmj = (string)($drs['meta_json'] ?? '');
                            if ($dmj !== '') {
                                $m = json_decode($dmj, true) ?: [];
                                if (is_array($m)) {
                                    if (!empty($drs['submitted_by']) && empty($m['submitted_by_name'])) { $m['submitted_by_name'] = (string)$drs['submitted_by']; }
                                    if (!empty($drs['marketer_name']) && empty($m['marketer_name'])) { $m['marketer_name'] = (string)$drs['marketer_name']; }
                                    if (!empty($drs['notes']) && empty($m['notes'])) { $m['notes'] = (string)$drs['notes']; }
                                    $meta = $m;
                                }
                            }
                        }
                    }
                } catch (Throwable $eDs1) {}
            }
            if (empty($meta) || !is_array($meta)) {
                try {
                    $rcp = (string)($row['receipt_file'] ?? '');
                    if ($rcp !== '' && colExists('deals','meta_json')) {
                        if (colExists('deals','receipt_file')) {
                            $qs = $pdo->prepare("SELECT meta_json FROM deals WHERE receipt_file = ? LIMIT 1"); $qs->execute([$rcp]);
                            $dmj = (string)($qs->fetchColumn() ?: '');
                            if ($dmj !== '') { $meta = json_decode($dmj, true) ?: []; }
                            if (empty($meta)) {
                                $base = basename($rcp);
                                if ($base !== '') {
                                    $qs = $pdo->prepare("SELECT meta_json FROM deals WHERE receipt_file LIKE ? LIMIT 1"); $qs->execute(['%'.$base]);
                                    $dmj = (string)($qs->fetchColumn() ?: ''); if ($dmj !== '') { $meta = json_decode($dmj, true) ?: []; }
                                }
                            }
                        } elseif (colExists('deals','proof_file')) {
                            $qs = $pdo->prepare("SELECT meta_json FROM deals WHERE proof_file = ? LIMIT 1"); $qs->execute([$rcp]);
                            $dmj = (string)($qs->fetchColumn() ?: '');
                            if ($dmj !== '') { $meta = json_decode($dmj, true) ?: []; }
                            if (empty($meta)) {
                                $base = basename($rcp);
                                if ($base !== '') {
                                    $qs = $pdo->prepare("SELECT meta_json FROM deals WHERE proof_file LIKE ? LIMIT 1"); $qs->execute(['%'.$base]);
                                    $dmj = (string)($qs->fetchColumn() ?: ''); if ($dmj !== '') { $meta = json_decode($dmj, true) ?: []; }
                                }
                            }
                        }
                    }
                } catch (Throwable $e2) {}
            }
            if (empty($meta) || !is_array($meta)) {
                try {
                    $uid = (int)($row['user_id'] ?? 0);
                    if ($uid > 0 && colExists('deals','user_id') && colExists('deals','meta_json')) {
                        $qd = $pdo->prepare("SELECT meta_json FROM deals WHERE user_id = ? ORDER BY id DESC LIMIT 1");
                        $qd->execute([$uid]); $dmj = (string)($qd->fetchColumn() ?: '');
                        if ($dmj !== '') { $meta = json_decode($dmj, true) ?: []; }
                    }
                } catch (Throwable $e3) {}
            }
            if (empty($meta) || !is_array($meta)) {
                try {
                    $ref = (string)($row['reference'] ?? '');
                    if ($ref !== '' && colExists('deals','created_at') && colExists('deals','meta_json')) {
                        $ts = null; if (preg_match('/(\\d{14})/', $ref, $m)) { $ts = DateTime::createFromFormat('YmdHis', $m[1]); }
                        if ($ts) {
                            $win = $ts->format('Y-m-d H:i:s');
                            $uid = (int)($row['user_id'] ?? 0);
                            if ($uid > 0 && colExists('deals','user_id')) {
                                $qrf = $pdo->prepare("SELECT meta_json FROM deals WHERE user_id = ? AND created_at BETWEEN DATE_SUB(?, INTERVAL 1 DAY) AND DATE_ADD(?, INTERVAL 1 DAY) ORDER BY created_at DESC LIMIT 1");
                                $qrf->execute([$uid, $win, $win]);
                            } else {
                                $qrf = $pdo->prepare("SELECT meta_json FROM deals WHERE created_at BETWEEN DATE_SUB(?, INTERVAL 1 DAY) AND DATE_ADD(?, INTERVAL 1 DAY) ORDER BY created_at DESC LIMIT 1");
                                $qrf->execute([$win, $win]);
                            }
                            $dmj = (string)($qrf->fetchColumn() ?: '');
                            if ($dmj !== '') { $meta = json_decode($dmj, true) ?: []; }
                        }
                    }
                } catch (Throwable $e4) {}
            }
            if (empty($meta) || !is_array($meta)) {
                try {
                    $ref = (string)($row['reference'] ?? '');
                    if ($ref !== '' && colExists('deals_submit','created_at') && colExists('deals_submit','meta_json')) {
                        $ts = null; if (preg_match('/(\\d{14})/', $ref, $m)) { $ts = DateTime::createFromFormat('YmdHis', $m[1]); }
                        if ($ts) {
                            $win = $ts->format('Y-m-d H:i:s');
                            $uid = (int)($row['user_id'] ?? 0);
                            if ($uid > 0 && colExists('deals_submit','user_id')) {
                                $qrf = $pdo->prepare("SELECT meta_json, submitted_by, marketer_name, notes FROM deals_submit WHERE user_id = ? AND created_at BETWEEN DATE_SUB(?, INTERVAL 1 DAY) AND DATE_ADD(?, INTERVAL 1 DAY) ORDER BY created_at DESC LIMIT 1");
                                $qrf->execute([$uid, $win, $win]);
                            } else {
                                $qrf = $pdo->prepare("SELECT meta_json, submitted_by, marketer_name, notes FROM deals_submit WHERE created_at BETWEEN DATE_SUB(?, INTERVAL 1 DAY) AND DATE_ADD(?, INTERVAL 1 DAY) ORDER BY created_at DESC LIMIT 1");
                                $qrf->execute([$win, $win]);
                            }
                            $drs = $qrf->fetch(PDO::FETCH_ASSOC) ?: [];
                            if (!empty($drs)) {
                                $dmj = (string)($drs['meta_json'] ?? '');
                                if ($dmj !== '') {
                                    $m = json_decode($dmj, true) ?: [];
                                    if (is_array($m)) {
                                        if (!empty($drs['submitted_by']) && empty($m['submitted_by_name'])) { $m['submitted_by_name'] = (string)$drs['submitted_by']; }
                                        if (!empty($drs['marketer_name']) && empty($m['marketer_name'])) { $m['marketer_name'] = (string)$drs['marketer_name']; }
                                        if (!empty($drs['notes']) && empty($m['notes'])) { $m['notes'] = (string)$drs['notes']; }
                                        $meta = $m;
                                    }
                                }
                            }
                        }
                    }
                } catch (Throwable $eDs2) {}
            }
            try {
                $cfuid = (int)($row['user_id'] ?? 0);
                $cfjson = '';
                if ($cfuid > 0 && colExists('client_forms','form_data')) {
                    $qcf = $pdo->prepare("SELECT form_data FROM client_forms WHERE client_id = ? ORDER BY created_at DESC LIMIT 1");
                    $qcf->execute([$cfuid]);
                    $cfjson = (string)($qcf->fetchColumn() ?: '');
                }
                if ($cfjson === '' && colExists('client_forms','form_data') && colExists('users','email')) {
                    $emailProbe = '';
                    try {
                        $emailProbe = isset($meta['client_email']) ? (string)$meta['client_email'] : '';
                        if ($emailProbe === '' && $cfuid > 0) {
                            $qe = $pdo->prepare("SELECT email FROM users WHERE id = ? LIMIT 1");
                            $qe->execute([$cfuid]);
                            $emailProbe = (string)($qe->fetchColumn() ?: '');
                        }
                    } catch (Throwable $eE0) {}
                    if ($emailProbe !== '') {
                        $qcf = $pdo->prepare("SELECT cf.form_data FROM client_forms cf LEFT JOIN users u ON cf.client_id = u.id WHERE u.email = ? ORDER BY cf.created_at DESC LIMIT 1");
                        $qcf->execute([$emailProbe]);
                        $cfjson = (string)($qcf->fetchColumn() ?: '');
                    }
                }
                if ($cfjson === '' && colExists('client_forms','form_data') && colExists('users','name')) {
                    $nameProbe = '';
                    $nameProbe = isset($meta['client_name']) ? (string)$meta['client_name'] : ((string)($row['client_name'] ?? ''));
                    if ($nameProbe !== '') {
                        $qcf = $pdo->prepare("SELECT TOP 1 cf.form_data FROM client_forms cf LEFT JOIN users u ON cf.client_id = u.id WHERE u.name LIKE ? ORDER BY cf.created_at DESC");
                        // Fallback for MySQL where TOP is invalid; prefer LIMIT if TOP fails in runtime. This is safe to parse-only here.
                        try {
                            $qcf->execute(['%'.$nameProbe.'%']);
                            $tmp = $qcf->fetchColumn();
                            if ($tmp !== false) { $cfjson = (string)$tmp; }
                        } catch (Throwable $eTop) {
                            $qcf = $pdo->prepare("SELECT cf.form_data FROM client_forms cf LEFT JOIN users u ON cf.client_id = u.id WHERE u.name LIKE ? ORDER BY cf.created_at DESC LIMIT 1");
                            $qcf->execute(['%'.$nameProbe.'%']);
                            $cfjson = (string)($qcf->fetchColumn() ?: '');
                        }
                    }
                }
                if ($cfjson !== '') {
                    if ($cfjson !== '') {
                        $cf = json_decode($cfjson, true) ?: [];
                        $cfProj = '';
                        foreach (['project_desc','Project / Property Description','Project / Property','Property / Estate','Property/Estate','Estate / Property','project_or_property','preferred_property','preferred property','estate_name','property_estate','estate_property','property','estate','project_property','project','property_title','property_name','project_title','Project Name'] as $k) {
                            $v = isset($cf[$k]) ? trim((string)$cf[$k]) : '';
                            if ($v !== '') { $cfProj = $v; break; }
                        }
                        $cfSource = '';
                        foreach (['deal_source','Deal Source','source','deal_source_type','lead_source','referral_source','referral source','referrer','referral','ref','submitted_by_role','Submitted By Role','department','team','channel','source_of_deal','source of deal','how did you hear about us','how you heard about us','where did you hear about us','where heard'] as $k) {
                            $v = isset($cf[$k]) ? trim((string)$cf[$k]) : '';
                            if ($v !== '') { $cfSource = $v; break; }
                        }
                        $cfPlan = '';
                        foreach (['plan_type','Payment Plan','plan','payment_plan','plan_name','installment_plan','installment','payment_mode','payment mode'] as $k) {
                            $v = isset($cf[$k]) ? trim((string)$cf[$k]) : '';
                            if ($v !== '') { $cfPlan = $v; break; }
                        }
                        $cfMarketer = '';
                        foreach (['marketer_name','Marketer Name','Marketer or Contact Centre Name','Marketer or Contact Center Name','Contact Centre Name','Contact Center Name','Marketer’s Name','Marketer\'s Name','marketer','sales_agent','sales_rep','contact_rep','uploaded_by_name','submitted_by_name','uploaded_by','created_by_name','agent_name','marketer_full_name','marketer full name'] as $k) {
                            $v = isset($cf[$k]) ? trim((string)$cf[$k]) : '';
                            if ($v !== '') { $cfMarketer = $v; break; }
                        }
                        if ($cfMarketer === '') {
                            foreach ($cf as $kk=>$vv) {
                                if (!is_string($vv) || trim($vv)==='') continue;
                                $lk = strtolower(preg_replace('/[^a-z]/','', (string)$kk));
                                if (strpos($lk,'submittedby')!==false || strpos($lk,'marketername')!==false || strpos($lk,'marketer')!==false || strpos($lk,'contactcentre')!==false || strpos($lk,'contactcenter')!==false) { $cfMarketer = trim((string)$vv); break; }
                            }
                        }
                        if (!isset($meta['project_desc']) && $cfProj !== '') { $meta['project_desc'] = $cfProj; }
                        if (!isset($meta['property']) && isset($cf['property'])) { $meta['property'] = $cf['property']; }
                        if (!isset($meta['deal_source']) && $cfSource !== '') { $meta['deal_source'] = $cfSource; }
                        if (!isset($meta['plan_type']) && $cfPlan !== '') { $meta['plan_type'] = $cfPlan; }
                        if (!isset($meta['marketer_name']) && $cfMarketer !== '') { $meta['marketer_name'] = $cfMarketer; }
                        if (!isset($meta['client_payment_status'])) {
                            if (isset($cf['client_payment_status']) && trim((string)$cf['client_payment_status']) !== '') { $meta['client_payment_status'] = trim((string)$cf['client_payment_status']); }
                            elseif (isset($cf['Client Payment Status / Notes']) && trim((string)$cf['Client Payment Status / Notes']) !== '') { $meta['client_payment_status'] = trim((string)$cf['Client Payment Status / Notes']); }
                            elseif (isset($cf['Client Payment Status']) && trim((string)$cf['Client Payment Status']) !== '') { $meta['client_payment_status'] = trim((string)$cf['Client Payment Status']); }
                            elseif (isset($cf['notes']) && trim((string)$cf['notes']) !== '') { $meta['client_payment_status'] = trim((string)$cf['notes']); }
                        }
                        if (!isset($meta['client_email'])) {
                            if (isset($cf['client_email']) && trim((string)$cf['client_email']) !== '') { $meta['client_email'] = trim((string)$cf['client_email']); }
                            elseif (isset($cf['Client Email (for dashboard)']) && trim((string)$cf['Client Email (for dashboard)']) !== '') { $meta['client_email'] = trim((string)$cf['Client Email (for dashboard)']); }
                            elseif (isset($cf['email']) && trim((string)$cf['email']) !== '') { $meta['client_email'] = trim((string)$cf['email']); }
                        }
                        if (!isset($meta['client_name'])) {
                            if (isset($cf['Client’s Name (text)']) && trim((string)$cf['Client’s Name (text)']) !== '') { $meta['client_name'] = trim((string)$cf['Client’s Name (text)']); }
                            elseif (isset($cf["Client's Name (text)"]) && trim((string)$cf["Client's Name (text)"]) !== '') { $meta['client_name'] = trim((string)$cf["Client's Name (text)"]); }
                            elseif (isset($cf['client_name_text']) && trim((string)$cf['client_name_text']) !== '') { $meta['client_name'] = trim((string)$cf['client_name_text']); }
                        }
                        if (!isset($meta['amount_offered'])) {
                            if (isset($cf['Amount Offered (if installment)'])) { $meta['amount_offered'] = (float)$cf['Amount Offered (if installment)']; }
                            elseif (isset($cf['offered_amount'])) { $meta['amount_offered'] = (float)$cf['offered_amount']; }
                            elseif (isset($cf['offered amount'])) { $meta['amount_offered'] = (float)$cf['offered amount']; }
                        }
                        if (!isset($meta['amount_paid_so_far'])) {
                            if (isset($cf['Amount Paid So Far'])) { $meta['amount_paid_so_far'] = (float)$cf['Amount Paid So Far']; }
                            elseif (isset($cf['Paid So Far'])) { $meta['amount_paid_so_far'] = (float)$cf['Paid So Far']; }
                        }
                        if (!isset($meta['discount_approved_by'])) {
                            if (isset($cf['Discount Approved By']) && trim((string)$cf['Discount Approved By']) !== '') { $meta['discount_approved_by'] = trim((string)$cf['Discount Approved By']); }
                        }
                        if (!isset($meta['commission_pct'])) {
                            if (isset($cf['Commission %'])) { $meta['commission_pct'] = (float)$cf['Commission %']; }
                        }
                        if (!isset($meta['marketer_comm'])) {
                            if (isset($cf['Marketer Commission Amount'])) { $meta['marketer_comm'] = (float)$cf['Marketer Commission Amount']; }
                            elseif (isset($cf['Marketer Commission'])) { $meta['marketer_comm'] = (float)$cf['Marketer Commission']; }
                        }
                        if (!isset($meta['agent_comm'])) {
                            if (isset($cf['Agent Commission Amount'])) { $meta['agent_comm'] = (float)$cf['Agent Commission Amount']; }
                            elseif (isset($cf['Agent Commission'])) { $meta['agent_comm'] = (float)$cf['Agent Commission']; }
                        }
                        if (!isset($meta['amount_offered']) && isset($cf['amount_offered'])) { $meta['amount_offered'] = (float)$cf['amount_offered']; }
                        if (!isset($meta['amount_paid_so_far']) && isset($cf['amount_paid_so_far'])) { $meta['amount_paid_so_far'] = (float)$cf['amount_paid_so_far']; }
                        if (!isset($meta['discount_amount']) && isset($cf['discount_amount'])) { $meta['discount_amount'] = (float)$cf['discount_amount']; }
                        if (!isset($meta['discount_approved_by']) && isset($cf['discount_approved_by'])) { $meta['discount_approved_by'] = (string)$cf['discount_approved_by']; }
                        if (!isset($meta['balance_remaining']) && isset($cf['balance_remaining'])) { $meta['balance_remaining'] = (float)$cf['balance_remaining']; }
                        if (!isset($meta['marketer_bank'])) {
                            $mb = [
                                'acc_no' => trim((string)($cf['marketer_account_number'] ?? ($cf['marketer_acc_no'] ?? ''))),
                                'bank' => trim((string)($cf['marketer_bank_name'] ?? ($cf['marketer_bank'] ?? ''))),
                                'acc_name' => trim((string)($cf['marketer_account_name'] ?? ($cf['marketer_acc_name'] ?? '')))
                            ];
                            if ($mb['acc_no'] !== '' || $mb['bank'] !== '' || $mb['acc_name'] !== '') { $meta['marketer_bank'] = $mb; }
                        }
                        if (!isset($meta['agent_bank'])) {
                            $ab = [
                                'acc_no' => trim((string)($cf['agent_account_number'] ?? ($cf['agent_acc_no'] ?? ''))),
                                'bank' => trim((string)($cf['agent_bank_name'] ?? ($cf['agent_bank'] ?? ''))),
                                'acc_name' => trim((string)($cf['agent_account_name'] ?? ($cf['agent_acc_name'] ?? '')))
                            ];
                            if ($ab['acc_no'] !== '' || $ab['bank'] !== '' || $ab['acc_name'] !== '') { $meta['agent_bank'] = $ab; }
                        }
                    }
                }
            } catch (Throwable $eCFb) {}
            // Force data mapping (deal first, fallback to meta)
            $clientNameMeta = (string)($meta['client_name'] ?? '');
            $clientEmailView = (string)($meta['client_email'] ?? '');
            $proj = (string)($row['project_name'] ?: ($row['project_desc'] ?: ($dealMeta['project_desc'] ?? '')));
            $planType = (string)($row['payment_plan'] ?: ($dealMeta['plan_type'] ?? ''));
            $dealSource = (string)($row['deal_source'] ?: ($dealMeta['deal_source'] ?? ''));
            $marketerName = (string)($row['marketer_name'] ?: ($dealMeta['marketer_name'] ?? ''));
            $amountOffered = (float)($meta['amount_offered'] ?? ($row['amount_offered'] ?? 0));
            $amountPaidSoFar = (float)($meta['amount_paid_so_far'] ?? ($row['amount_paid_so_far'] ?? 0));
            $discountAmount = (float)($meta['discount_amount'] ?? ($row['discount_amount'] ?? 0));
            $discountBy = (string)($meta['discount_approved_by'] ?? '');
            $commissionPct = (float)($meta['commission_pct'] ?? ($row['commission_percent'] ?? 0));
            $marketerComm = (float)($meta['marketer_comm'] ?? ($row['marketer_commission'] ?? 0));
            $agentComm = (float)($meta['agent_comm'] ?? ($row['agent_commission'] ?? 0));
            $balanceRem = (float)($meta['balance_remaining'] ?? ($row['balance_remaining'] ?? 0));
            $statusNotes = (string)($row['notes'] ?: ($dealMeta['client_payment_status'] ?? ($meta['client_payment_status'] ?? ($meta['notes'] ?? ''))));
            // STRICT: fetch bank details only from deals_submit JSON columns (not from meta_json)
            $mkRaw = [];
            if (!empty($row['ds_marketer_bank'])) {
                $mkRaw = is_string($row['ds_marketer_bank']) ? (json_decode($row['ds_marketer_bank'], true) ?: []) : (is_array($row['ds_marketer_bank']) ? $row['ds_marketer_bank'] : []);
            }
            $agRaw = [];
            if (!empty($row['ds_agent_bank'])) {
                $agRaw = is_string($row['ds_agent_bank']) ? (json_decode($row['ds_agent_bank'], true) ?: []) : (is_array($row['ds_agent_bank']) ? $row['ds_agent_bank'] : []);
            }
            if ((empty($mkRaw) || (empty($mkRaw['acc_no']) && empty($mkRaw['bank']) && empty($mkRaw['acc_name']))) || (empty($agRaw) || (empty($agRaw['acc_no']) && empty($agRaw['bank']) && empty($agRaw['acc_name'])))) {
                try {
                    $uidProbe = (int)($row['user_id'] ?? 0);
                    if ($uidProbe > 0 && colExists('deals_submit','user_id')) {
                        $qs = $pdo->prepare("SELECT marketer_bank, agent_bank FROM deals_submit WHERE user_id = ? ORDER BY id DESC LIMIT 1");
                        $qs->execute([$uidProbe]);
                        $drs = $qs->fetch(PDO::FETCH_ASSOC) ?: [];
                        if ((empty($mkRaw) || (empty($mkRaw['acc_no']) && empty($mkRaw['bank']) && empty($mkRaw['acc_name']))) && !empty($drs['marketer_bank'])) {
                            $tmp = is_string($drs['marketer_bank']) ? (json_decode($drs['marketer_bank'], true) ?: []) : (is_array($drs['marketer_bank']) ? $drs['marketer_bank'] : []);
                            if (is_array($tmp)) { $mkRaw = $tmp; }
                        }
                        if ((empty($agRaw) || (empty($agRaw['acc_no']) && empty($agRaw['bank']) && empty($agRaw['acc_name']))) && !empty($drs['agent_bank'])) {
                            $tmp = is_string($drs['agent_bank']) ? (json_decode($drs['agent_bank'], true) ?: []) : (is_array($drs['agent_bank']) ? $drs['agent_bank'] : []);
                            if (is_array($tmp)) { $agRaw = $tmp; }
                        }
                    }
                    $didProbe = (int)($row['deal_id'] ?? 0);
                    if (($didProbe > 0 || $uidProbe > 0) && colExists('deals_submit','id')) {
                        $fields = [];
                        foreach (['marketer_account_number','marketer_acc_no','marketer_bank_name','marketer_bank','marketer_account_name','marketer_acc_name','agent_account_number','agent_acc_no','agent_bank_name','agent_bank','agent_account_name','agent_acc_name'] as $f) {
                            if (colExists('deals_submit',$f)) { $fields[] = $f; }
                        }
                        if (!empty($fields)) {
                            $sel = implode(', ', array_map(function($f){ return $f; }, $fields));
                            $qds = null; $pr = [];
                            if ($didProbe > 0) { $qds = $pdo->prepare("SELECT {$sel} FROM deals_submit WHERE id = ? LIMIT 1"); $pr = [$didProbe]; }
                            elseif ($uidProbe > 0 && colExists('deals_submit','user_id')) { $qds = $pdo->prepare("SELECT {$sel} FROM deals_submit WHERE user_id = ? ORDER BY id DESC LIMIT 1"); $pr = [$uidProbe]; }
                            if ($qds) {
                                $qds->execute($pr);
                                $dsr = $qds->fetch(PDO::FETCH_ASSOC) ?: [];
                                if (empty($mkRaw) || (empty($mkRaw['acc_no']) && empty($mkRaw['bank']) && empty($mkRaw['acc_name']))) {
                                    $accNo = trim((string)($dsr['marketer_account_number'] ?? ($dsr['marketer_acc_no'] ?? '')));
                                    $bankN = trim((string)($dsr['marketer_bank_name'] ?? ($dsr['marketer_bank'] ?? '')));
                                    $accNm = trim((string)($dsr['marketer_account_name'] ?? ($dsr['marketer_acc_name'] ?? '')));
                                    if ($accNo !== '' || $bankN !== '' || $accNm !== '') { $mkRaw = ['acc_no'=>$accNo,'bank'=>$bankN,'acc_name'=>$accNm]; }
                                }
                                if (empty($agRaw) || (empty($agRaw['acc_no']) && empty($agRaw['bank']) && empty($agRaw['acc_name']))) {
                                    $accNo = trim((string)($dsr['agent_account_number'] ?? ($dsr['agent_acc_no'] ?? '')));
                                    $bankN = trim((string)($dsr['agent_bank_name'] ?? ($dsr['agent_bank'] ?? '')));
                                    $accNm = trim((string)($dsr['agent_account_name'] ?? ($dsr['agent_acc_name'] ?? '')));
                                    if ($accNo !== '' || $bankN !== '' || $accNm !== '') { $agRaw = ['acc_no'=>$accNo,'bank'=>$bankN,'acc_name'=>$accNm]; }
                                }
                            }
                        }
                    }
                } catch (Throwable $eDSFallback) {}
            }
            $mkBank = [
                'acc_no' => trim((string)(
                    $mkRaw['acc_no'] ?? $mkRaw['account_number'] ?? $mkRaw['accountNumber'] ?? $mkRaw['accNo'] ?? ''
                )),
                'bank' => trim((string)(
                    $mkRaw['bank'] ?? $mkRaw['bank_name'] ?? $mkRaw['bankName'] ?? ''
                )),
                'acc_name' => trim((string)(
                    $mkRaw['acc_name'] ?? $mkRaw['account_name'] ?? $mkRaw['accountName'] ?? ''
                ))
            ];
            $agBank = [
                'acc_no' => trim((string)(
                    $agRaw['acc_no'] ?? $agRaw['account_number'] ?? $agRaw['accountNumber'] ?? $agRaw['accNo'] ?? ''
                )),
                'bank' => trim((string)(
                    $agRaw['bank'] ?? $agRaw['bank_name'] ?? $agRaw['bankName'] ?? ''
                )),
                'acc_name' => trim((string)(
                    $agRaw['acc_name'] ?? $agRaw['account_name'] ?? $agRaw['accountName'] ?? ''
                ))
            ];
            $transactionsMeta = isset($meta['transactions']) && is_array($meta['transactions']) ? $meta['transactions'] : [];
            // Leave client email lookup only if we truly lack email in meta
            if ($clientEmailView === '' && isset($paymentMeta['client_email'])) { $clientEmailView = (string)$paymentMeta['client_email']; }
            $dealIdRef = 0;
            try {
                if (isset($row['deal_id'])) { $dealIdRef = (int)$row['deal_id']; }
            } catch (Throwable $eDid) {}
            if ($dealIdRef > 0) {
                try {
                    $qdrow = $pdo->prepare("SELECT * FROM deals WHERE id = ? LIMIT 1");
                    $qdrow->execute([$dealIdRef]);
                    $dr = $qdrow->fetch(PDO::FETCH_ASSOC) ?: [];
                    if (!empty($dr)) {
                        if ($proj === '') {
                            $proj = (string)($dr['project_name'] ?? '');
                            if ($proj === '') { $proj = (string)($dr['project_desc'] ?? ($dr['property_estate'] ?? $proj)); }
                        }
                        if ($amountOffered <= 0 && isset($dr['amount_offered'])) { $amountOffered = (float)$dr['amount_offered']; }
                        if ($amountPaidSoFar <= 0 && isset($dr['amount_paid_so_far'])) { $amountPaidSoFar = (float)$dr['amount_paid_so_far']; }
                        if ($commissionPct <= 0) {
                            if (isset($dr['commission_percent'])) { $commissionPct = (float)$dr['commission_percent']; }
                            elseif (isset($dr['commission_pct'])) { $commissionPct = (float)$dr['commission_pct']; }
                        }
                        if ($balanceRem <= 0 && isset($dr['balance_remaining'])) { $balanceRem = (float)$dr['balance_remaining']; }
                        if (trim($dealSource) === '' && isset($dr['deal_source'])) { $dealSource = (string)$dr['deal_source']; }
                        if (trim($planType) === '' && isset($dr['payment_plan'])) { $planType = (string)$dr['payment_plan']; }
                        if (trim($marketerName) === '' && isset($dr['marketer_id']) && colExists('users','name')) {
                            $mid = (int)$dr['marketer_id']; if ($mid > 0) {
                                try { $qmname = $pdo->prepare("SELECT name FROM users WHERE id = ? LIMIT 1"); $qmname->execute([$mid]); $marketerName = (string)($qmname->fetchColumn() ?: $marketerName); } catch (Throwable $eMN) {}
                            }
                        }
                        $sets = []; $vals = [];
                        if (isset($dr['project_name']) && trim((string)$dr['project_name']) === '' && $proj !== '') { $sets[]='project_name = ?'; $vals[]=$proj; }
                        if (isset($dr['project_desc']) && trim((string)$dr['project_desc']) === '' && $proj !== '') { $sets[]='project_desc = ?'; $vals[]=$proj; }
                        if (isset($dr['deal_source']) && trim((string)$dr['deal_source']) === '' && $dealSource !== '') { $sets[]='deal_source = ?'; $vals[]=$dealSource; }
                        if (isset($dr['payment_plan']) && trim((string)$dr['payment_plan']) === '' && $planType !== '') { $sets[]='payment_plan = ?'; $vals[]=$planType; }
                        if (isset($dr['marketer_name']) && trim((string)$dr['marketer_name']) === '' && $marketerName !== '') { $sets[]='marketer_name = ?'; $vals[]=$marketerName; }
                        if (isset($dr['amount_offered']) && (float)$dr['amount_offered'] == 0.0 && $amountOffered > 0) { $sets[]='amount_offered = ?'; $vals[]=$amountOffered; }
                        if (isset($dr['amount_paid_so_far']) && (float)$dr['amount_paid_so_far'] == 0.0 && $amountPaidSoFar > 0) { $sets[]='amount_paid_so_far = ?'; $vals[]=$amountPaidSoFar; }
                        if (isset($dr['commission_percent']) && (float)$dr['commission_percent'] == 0.0 && $commissionPct > 0) { $sets[]='commission_percent = ?'; $vals[]=$commissionPct; }
                        if (isset($dr['discount_amount']) && (float)$dr['discount_amount'] == 0.0 && $discountAmount > 0) { $sets[]='discount_amount = ?'; $vals[]=$discountAmount; }
                        if (isset($dr['balance_remaining']) && (float)$dr['balance_remaining'] == 0.0 && $balanceRem > 0) { $sets[]='balance_remaining = ?'; $vals[]=$balanceRem; }
                        if (isset($dr['notes']) && trim((string)$dr['notes']) === '' && $statusNotes !== '') { $sets[]='notes = ?'; $vals[]=$statusNotes; }
                        if (!empty($sets)) {
                            $vals[] = $dealIdRef;
                            $upD = $pdo->prepare("UPDATE deals SET ".implode(',', $sets)." WHERE id = ?");
                            $upD->execute($vals);
                            try { @file_put_contents(__DIR__ . '/debug_sql.txt', "REPAIR_UPDATE_DEAL:\nUPDATE deals SET ".implode(',', $sets)." WHERE id = {$dealIdRef}\nPARAMS:\n".print_r($vals, true)."\n", FILE_APPEND); } catch (Throwable $eRU0) {}
                        }
                        if (empty($mkBank['acc_no']) && (isset($dr['marketer_account_number']) || isset($dr['marketer_acc_no']))) {
                            $mkBank['acc_no'] = trim((string)($dr['marketer_account_number'] ?? ($dr['marketer_acc_no'] ?? '')));
                        }
                        if (empty($mkBank['bank']) && (isset($dr['marketer_bank_name']) || isset($dr['marketer_bank']))) {
                            $mkBank['bank'] = trim((string)($dr['marketer_bank_name'] ?? ($dr['marketer_bank'] ?? '')));
                        }
                        if (empty($mkBank['acc_name']) && (isset($dr['marketer_account_name']) || isset($dr['marketer_acc_name']))) {
                            $mkBank['acc_name'] = trim((string)($dr['marketer_account_name'] ?? ($dr['marketer_acc_name'] ?? '')));
                        }
                        if (empty($agBank['acc_no']) && (isset($dr['agent_account_number']) || isset($dr['agent_acc_no']))) {
                            $agBank['acc_no'] = trim((string)($dr['agent_account_number'] ?? ($dr['agent_acc_no'] ?? '')));
                        }
                        if (empty($agBank['bank']) && (isset($dr['agent_bank_name']) || isset($dr['agent_bank']))) {
                            $agBank['bank'] = trim((string)($dr['agent_bank_name'] ?? ($dr['agent_bank'] ?? '')));
                        }
                        if (empty($agBank['acc_name']) && (isset($dr['agent_account_name']) || isset($dr['agent_acc_name']))) {
                            $agBank['acc_name'] = trim((string)($dr['agent_account_name'] ?? ($dr['agent_acc_name'] ?? '')));
                        }
                    }
                } catch (Throwable $eDL) {}
            }
            if (empty($transactionsMeta)) {
                try {
                    $histLimit = 10;
                    $list = [];
                    $uidH = (int)($row['user_id'] ?? 0);
                    $amountColP = colExists('payments','amount') ? 'amount' : (colExists('payments','total') ? 'total' : null);
                    $dateColP = colExists('payments','created_at') ? 'created_at' : (colExists('payments','updated_at') ? 'updated_at' : (colExists('payments','date') ? 'date' : (colExists('payments','payment_date') ? 'payment_date' : null)));
                    $amountColT = colExists('transactions','amount') ? 'amount' : (colExists('transactions','total') ? 'total' : null);
                    $dateColT = colExists('transactions','created_at') ? 'created_at' : (colExists('transactions','updated_at') ? 'updated_at' : (colExists('transactions','date') ? 'date' : null));
                    if ($uidH > 0 && $amountColP && $dateColP && colExists('payments','user_id')) {
                        $qh = $pdo->prepare("SELECT {$dateColP} AS d, {$amountColP} AS a FROM payments WHERE user_id = ? ORDER BY {$dateColP} DESC LIMIT ".$histLimit);
                        $qh->execute([$uidH]);
                        $rowsH = $qh->fetchAll(PDO::FETCH_ASSOC) ?: [];
                        foreach ($rowsH as $r0) {
                            $list[] = ['date' => (string)$r0['d'], 'amount' => (float)($r0['a'] ?? 0)];
                        }
                    } elseif (!empty($row['client_name']) && $amountColP && $dateColP && colExists('payments','client_name')) {
                        $qh = $pdo->prepare("SELECT {$dateColP} AS d, {$amountColP} AS a FROM payments WHERE client_name = ? ORDER BY {$dateColP} DESC LIMIT ".$histLimit);
                        $qh->execute([(string)$row['client_name']]);
                        $rowsH = $qh->fetchAll(PDO::FETCH_ASSOC) ?: [];
                        foreach ($rowsH as $r0) { $list[] = ['date' => (string)$r0['d'], 'amount' => (float)($r0['a'] ?? 0)]; }
                    } elseif ($clientEmailView !== '' && $amountColP && $dateColP && colExists('payments','client_email')) {
                        $qh = $pdo->prepare("SELECT {$dateColP} AS d, {$amountColP} AS a FROM payments WHERE client_email = ? ORDER BY {$dateColP} DESC LIMIT ".$histLimit);
                        $qh->execute([$clientEmailView]);
                        $rowsH = $qh->fetchAll(PDO::FETCH_ASSOC) ?: [];
                        foreach ($rowsH as $r0) { $list[] = ['date' => (string)$r0['d'], 'amount' => (float)($r0['a'] ?? 0)]; }
                    } elseif ($dealIdRef > 0 && $amountColP && $dateColP && colExists('payments','deal_id')) {
                        $qh = $pdo->prepare("SELECT {$dateColP} AS d, {$amountColP} AS a FROM payments WHERE deal_id = ? ORDER BY {$dateColP} DESC LIMIT ".$histLimit);
                        $qh->execute([$dealIdRef]);
                        $rowsH = $qh->fetchAll(PDO::FETCH_ASSOC) ?: [];
                        foreach ($rowsH as $r0) { $list[] = ['date' => (string)$r0['d'], 'amount' => (float)($r0['a'] ?? 0)]; }
                    }
                    if ($amountColT && $dateColT) {
                        if ($uidH > 0 && colExists('transactions','user_id')) {
                            $qt = $pdo->prepare("SELECT {$dateColT} AS d, {$amountColT} AS a FROM transactions WHERE user_id = ? ORDER BY {$dateColT} DESC LIMIT ".$histLimit);
                            $qt->execute([$uidH]);
                            $txRows = $qt->fetchAll(PDO::FETCH_ASSOC) ?: [];
                            foreach ($txRows as $tx) { $list[] = ['date' => (string)$tx['d'], 'amount' => (float)($tx['a'] ?? 0)]; }
                        } elseif (!empty($row['client_name']) && colExists('transactions','client_name')) {
                            $qt = $pdo->prepare("SELECT {$dateColT} AS d, {$amountColT} AS a FROM transactions WHERE client_name = ? ORDER BY {$dateColT} DESC LIMIT ".$histLimit);
                            $qt->execute([(string)$row['client_name']]);
                            $txRows = $qt->fetchAll(PDO::FETCH_ASSOC) ?: [];
                            foreach ($txRows as $tx) { $list[] = ['date' => (string)$tx['d'], 'amount' => (float)($tx['a'] ?? 0)]; }
                        } elseif ($clientEmailView !== '' && colExists('transactions','client_email')) {
                            $qt = $pdo->prepare("SELECT {$dateColT} AS d, {$amountColT} AS a FROM transactions WHERE client_email = ? ORDER BY {$dateColT} DESC LIMIT ".$histLimit);
                            $qt->execute([$clientEmailView]);
                            $txRows = $qt->fetchAll(PDO::FETCH_ASSOC) ?: [];
                            foreach ($txRows as $tx) { $list[] = ['date' => (string)$tx['d'], 'amount' => (float)($tx['a'] ?? 0)]; }
                        }
                    }
                    // Fallback by reference window → discover email/name from deals near timestamp
                    if (empty($list)) {
                        $ref = (string)($row['reference'] ?? '');
                        if ($ref !== '' && preg_match('/(\\d{14})/', $ref, $m)) {
                            $ts = DateTime::createFromFormat('YmdHis', $m[1]);
                            if ($ts && colExists('deals','created_at')) {
                                $win = $ts->format('Y-m-d H:i:s');
                                try {
                                    $qd = null;
                                    if (colExists('deals','meta_json')) {
                                        $qd = $pdo->prepare("SELECT meta_json FROM deals WHERE created_at BETWEEN DATE_SUB(?, INTERVAL 1 DAY) AND DATE_ADD(?, INTERVAL 1 DAY) ORDER BY created_at DESC LIMIT 1");
                                        $qd->execute([$win,$win]);
                                        $dm = (string)($qd->fetchColumn() ?: '');
                                        if ($dm !== '') {
                                            $mj = json_decode($dm, true) ?: [];
                                            $em = (string)($mj['client_email'] ?? '');
                                            $nm = (string)($mj['client_name'] ?? '');
                                            if ($em !== '' && $amountColP && $dateColP && colExists('payments','client_email')) {
                                                $qh = $pdo->prepare("SELECT {$dateColP} AS d, {$amountColP} AS a FROM payments WHERE client_email = ? ORDER BY {$dateColP} DESC LIMIT ".$histLimit);
                                                $qh->execute([$em]); $rowsH = $qh->fetchAll(PDO::FETCH_ASSOC) ?: [];
                                                foreach ($rowsH as $r0) { $list[] = ['date' => (string)$r0['d'], 'amount' => (float)($r0['a'] ?? 0)]; }
                                            }
                                            if ($nm !== '' && $amountColP && $dateColP && colExists('payments','client_name') && empty($list)) {
                                                $qh = $pdo->prepare("SELECT {$dateColP} AS d, {$amountColP} AS a FROM payments WHERE client_name = ? ORDER BY {$dateColP} DESC LIMIT ".$histLimit);
                                                $qh->execute([$nm]); $rowsH = $qh->fetchAll(PDO::FETCH_ASSOC) ?: [];
                                                foreach ($rowsH as $r0) { $list[] = ['date' => (string)$r0['d'], 'amount' => (float)($r0['a'] ?? 0)]; }
                                            }
                                        }
                                    }
                                } catch (Throwable $eRefWin) {}
                            }
                        }
                    }
                    if (!empty($list)) {
                        $transactionsMeta = [];
                        foreach ($list as $it) {
                            $d = (string)($it['date'] ?? '');
                            $amt = (float)($it['amount'] ?? 0);
                            $transactionsMeta[] = ['date' => ($d !== '' ? date('Y-m-d', strtotime($d)) : ''), 'amount' => $amt];
                        }
                    }
                } catch (Throwable $eHist) {}
            }
            $paymentRefView = (string)($row['reference'] ?? '');
            $methodCol = colExists('payments','payment_method') ? 'payment_method' : (colExists('payments','method') ? 'method' : null);
            $paymentMethodView = '';
            if ($methodCol) {
                try { $qp = $pdo->prepare("SELECT {$methodCol} AS method FROM payments WHERE id = ? LIMIT 1"); $qp->execute([(int)$row['payment_id']]); $paymentMethodView = (string)($qp->fetchColumn() ?: ''); } catch (Throwable $eM) {}
            }
            $normalized = [
                'client_name' => $clientNameMeta,
                'client_email' => $clientEmailView,
                'project_desc' => $proj,
                'deal_source' => $dealSource,
                'plan_type' => $planType,
                'amount_offered' => $amountOffered,
                'amount_paid_so_far' => $amountPaidSoFar,
                'amount_paid_now' => (float)($row['amount'] ?? 0),
                'discount_amount' => $discountAmount,
                'discount_approved_by' => $discountBy,
                'commission_pct' => $commissionPct,
                'marketer_comm' => $marketerComm,
                'agent_comm' => $agentComm,
                'balance_remaining' => $balanceRem,
                'client_payment_status' => $statusNotes,
                'marketer_bank' => $mkBank,
                'agent_bank' => $agBank,
                'transactions' => $transactionsMeta,
                'marketer_name' => $marketerName,
                'payment_reference' => $paymentRefView,
                'payment_method' => ($paymentMethodView !== '' ? $paymentMethodView : 'Bank Transfer')
            ];
            $currentMeta = is_array($meta) ? $meta : [];
            foreach ($normalized as $k=>$v) {
                $hasKey = array_key_exists($k, $currentMeta);
                $cur = $hasKey ? $currentMeta[$k] : null;
                $shouldSet = !$hasKey;
                if (!$shouldSet) {
                    if (is_string($cur)) { $t = trim($cur); $shouldSet = ($t === '' || $t === '-'); }
                    elseif (is_array($cur)) { $shouldSet = empty($cur); }
                    elseif ($cur === null) { $shouldSet = true; }
                }
                if ($shouldSet) { $currentMeta[$k] = $v; }
            }
            try {
                if (colExists('payments','meta_json')) {
                    $newJson = json_encode($currentMeta);
                    if ($newJson) {
                        $up = $pdo->prepare("UPDATE payments SET meta_json = ? WHERE id = ?");
                        $up->execute([$newJson, (int)$row['payment_id']]);
                    }
                }
            } catch (Throwable $eW) {}
            if ($methodCol) {
                try {
                    $methodExisting = '';
                    $qm = $pdo->prepare("SELECT {$methodCol} AS m FROM payments WHERE id = ? LIMIT 1"); $qm->execute([(int)$row['payment_id']]);
                    $methodExisting = (string)($qm->fetchColumn() ?: '');
                    if (trim($methodExisting) === '') {
                        $upm = $pdo->prepare("UPDATE payments SET {$methodCol} = ? WHERE id = ?");
                        $upm->execute(['Bank Transfer', (int)$row['payment_id']]);
                    }
                } catch (Throwable $eWM) {}
            }
        }
    } catch (Throwable $e) {}
}
if ($_SERVER['REQUEST_METHOD'] === 'POST' && $canVerify) {
    if (isset($_POST['backfill_meta'])) {
        $updated = 0; $scanned = 0;
        try {
            $params = [];
            $companyClause = '';
            if ($applyCompanyFilter && colExists('payments','company_id')) { $companyClause = " AND (company_id = ? OR company_id IS NULL)"; $params[] = $companyId; }
            $refCol = colExists('payments','reference') ? 'reference' : (colExists('payments','ref') ? 'ref' : "''");
            $rcpCol = colExists('payments','receipt_file') ? 'receipt_file' : (colExists('payments','proof_file') ? 'proof_file' : "NULL");
            $dateCol = colExists('payments','created_at') ? 'created_at' : (colExists('payments','date') ? 'date' : (colExists('payments','updated_at') ? 'updated_at' : null));
            $dealIdCol = colExists('payments','deal_id') ? 'deal_id' : 'NULL';
            $sql = "SELECT id, user_id, amount, {$refCol} AS reference, {$rcpCol} AS receipt_file, {$dealIdCol} AS deal_id"
                . ($dateCol ? ", {$dateCol} AS created_at" : "")
                . (colExists('payments','client_name') ? ", client_name" : ", NULL AS client_name")
                . (colExists('payments','client_email') ? ", client_email" : ", NULL AS client_email")
                . (colExists('payments','submitted_by_user') ? ", submitted_by_user" : ", NULL AS submitted_by_user")
                . (colExists('payments','submitted_by') ?      ", submitted_by"      : ", NULL AS submitted_by")
                . (colExists('payments','created_by') ?        ", created_by"        : ", NULL AS created_by")
                . (colExists('payments','created_by_user') ?   ", created_by_user"   : ", NULL AS created_by_user")
                . (colExists('payments','staff_id') ?          ", staff_id"          : ", NULL AS staff_id")
                . (colExists('payments','marketer_id') ?       ", marketer_id"       : ", NULL AS marketer_id")
                . (colExists('payments','agent_id') ?          ", agent_id"          : ", NULL AS agent_id")
                . (colExists('payments','contact_rep_id') ?    ", contact_rep_id"    : ", NULL AS contact_rep_id")
                . " FROM payments WHERE (".$refCol." LIKE 'deal-submission-%' OR ".$refCol." LIKE 'deal-quick-%' OR status IN ('pending_verification','approved')){$companyClause} ORDER BY ".($dateCol ?: 'id')." DESC LIMIT 500";
            $st = $pdo->prepare($sql); $st->execute($params);
            $rows = $st->fetchAll(PDO::FETCH_ASSOC) ?: [];
            foreach ($rows as $row) {
                $scanned++;
                $meta = [];
                try {
                    if (colExists('payments','meta_json')) {
                        $qm = $pdo->prepare("SELECT meta_json FROM payments WHERE id = ? LIMIT 1");
                        $qm->execute([(int)$row['id']]); $mj = (string)($qm->fetchColumn() ?: '');
                        if ($mj !== '') { $meta = json_decode($mj, true) ?: []; }
                    }
                } catch (Throwable $e0) {}
                // Pull from deals meta if missing
                try {
                    if ((empty($meta) || !is_array($meta)) && (int)($row['deal_id'] ?? 0) > 0 && colExists('deals','meta_json')) {
                        $qd = $pdo->prepare("SELECT meta_json FROM deals WHERE id = ? LIMIT 1");
                        $qd->execute([(int)$row['deal_id']]); $dmj = (string)($qd->fetchColumn() ?: '');
                        if ($dmj !== '') { $meta = json_decode($dmj, true) ?: []; }
                    }
                } catch (Throwable $e1) {}
                if (empty($meta) || !is_array($meta)) {
                    try {
                        $rcp = (string)($row['receipt_file'] ?? '');
                        if ($rcp !== '' && colExists('deals','meta_json')) {
                            if (colExists('deals','receipt_file')) {
                                $qs = $pdo->prepare("SELECT meta_json FROM deals WHERE receipt_file = ? LIMIT 1"); $qs->execute([$rcp]);
                                $dmj = (string)($qs->fetchColumn() ?: '');
                                if ($dmj !== '') { $meta = json_decode($dmj, true) ?: []; }
                                if (empty($meta)) {
                                    $base = basename($rcp);
                                    if ($base !== '') {
                                        $qs = $pdo->prepare("SELECT meta_json FROM deals WHERE receipt_file LIKE ? LIMIT 1"); $qs->execute(['%'.$base]);
                                        $dmj = (string)($qs->fetchColumn() ?: ''); if ($dmj !== '') { $meta = json_decode($dmj, true) ?: []; }
                                    }
                                }
                            } elseif (colExists('deals','proof_file')) {
                                $qs = $pdo->prepare("SELECT meta_json FROM deals WHERE proof_file = ? LIMIT 1"); $qs->execute([$rcp]);
                                $dmj = (string)($qs->fetchColumn() ?: '');
                                if ($dmj !== '') { $meta = json_decode($dmj, true) ?: []; }
                                if (empty($meta)) {
                                    $base = basename($rcp);
                                    if ($base !== '') {
                                        $qs = $pdo->prepare("SELECT meta_json FROM deals WHERE proof_file LIKE ? LIMIT 1"); $qs->execute(['%'.$base]);
                                        $dmj = (string)($qs->fetchColumn() ?: ''); if ($dmj !== '') { $meta = json_decode($dmj, true) ?: []; }
                                    }
                                }
                            }
                        }
                    } catch (Throwable $e2) {}
                }
                if (empty($meta) || !is_array($meta)) {
                    try {
                        $uid = (int)($row['user_id'] ?? 0);
                        if ($uid > 0 && colExists('deals','user_id') && colExists('deals','meta_json')) {
                            $qd = $pdo->prepare("SELECT meta_json FROM deals WHERE user_id = ? ORDER BY id DESC LIMIT 1");
                            $qd->execute([$uid]); $dmj = (string)($qd->fetchColumn() ?: '');
                            if ($dmj !== '') { $meta = json_decode($dmj, true) ?: []; }
                            if (empty($meta) && $dateCol && colExists('deals','created_at')) {
                                $dt = (string)($row['created_at'] ?? '');
                                if ($dt !== '') {
                                    $qdt = $pdo->prepare("SELECT meta_json FROM deals WHERE user_id = ? AND created_at BETWEEN DATE_SUB(?, INTERVAL 1 DAY) AND DATE_ADD(?, INTERVAL 1 DAY) ORDER BY created_at DESC LIMIT 1");
                                    $qdt->execute([$uid, $dt, $dt]); $dmj = (string)($qdt->fetchColumn() ?: '');
                                    if ($dmj !== '') { $meta = json_decode($dmj, true) ?: []; }
                                }
                            }
                        }
                    } catch (Throwable $e3) {}
                }
                if (empty($meta) || !is_array($meta)) {
                    try {
                        $ref = (string)($row['reference'] ?? '');
                        if ($ref !== '' && colExists('deals','created_at') && colExists('deals','meta_json')) {
                            $ts = null; if (preg_match('/(\\d{14})/', $ref, $m)) { $ts = DateTime::createFromFormat('YmdHis', $m[1]); }
                            if ($ts) {
                                $win = $ts->format('Y-m-d H:i:s');
                                $uid = (int)($row['user_id'] ?? 0);
                                if ($uid > 0 && colExists('deals','user_id')) {
                                    $qrf = $pdo->prepare("SELECT meta_json FROM deals WHERE user_id = ? AND created_at BETWEEN DATE_SUB(?, INTERVAL 1 DAY) AND DATE_ADD(?, INTERVAL 1 DAY) ORDER BY created_at DESC LIMIT 1");
                                    $qrf->execute([$uid, $win, $win]);
                                } else {
                                    $qrf = $pdo->prepare("SELECT meta_json FROM deals WHERE created_at BETWEEN DATE_SUB(?, INTERVAL 1 DAY) AND DATE_ADD(?, INTERVAL 1 DAY) ORDER BY created_at DESC LIMIT 1");
                                    $qrf->execute([$win, $win]);
                                }
                                $dmj = (string)($qrf->fetchColumn() ?: '');
                                if ($dmj !== '') { $meta = json_decode($dmj, true) ?: []; }
                            }
                        }
                    } catch (Throwable $e4) {}
                }
                try {
                    $cfuid = (int)($row['user_id'] ?? 0);
                    if ($cfuid > 0 && colExists('client_forms','form_data')) {
                        $qcf = $pdo->prepare("SELECT form_data FROM client_forms WHERE client_id = ? ORDER BY created_at DESC LIMIT 1");
                        $qcf->execute([$cfuid]);
                        $cfjson = (string)($qcf->fetchColumn() ?: '');
                        if ($cfjson !== '') {
                            $cf = json_decode($cfjson, true) ?: [];
                            if (!isset($meta['project_desc']) && isset($cf['project_desc'])) { $meta['project_desc'] = $cf['project_desc']; }
                            if (!isset($meta['property']) && isset($cf['property'])) { $meta['property'] = $cf['property']; }
                            if (!isset($meta['deal_source']) && isset($cf['deal_source'])) { $meta['deal_source'] = $cf['deal_source']; }
                            if (!isset($meta['plan_type']) && isset($cf['plan_type'])) { $meta['plan_type'] = $cf['plan_type']; }
                            if (!isset($meta['marketer_name']) && isset($cf['marketer_name'])) { $meta['marketer_name'] = $cf['marketer_name']; }
                            if (!isset($meta['amount_offered']) && isset($cf['amount_offered'])) { $meta['amount_offered'] = (float)$cf['amount_offered']; }
                            if (!isset($meta['amount_paid_so_far']) && isset($cf['amount_paid_so_far'])) { $meta['amount_paid_so_far'] = (float)$cf['amount_paid_so_far']; }
                            if (!isset($meta['discount_amount']) && isset($cf['discount_amount'])) { $meta['discount_amount'] = (float)$cf['discount_amount']; }
                            if (!isset($meta['discount_approved_by']) && isset($cf['discount_approved_by'])) { $meta['discount_approved_by'] = (string)$cf['discount_approved_by']; }
                            if (!isset($meta['balance_remaining']) && isset($cf['balance_remaining'])) { $meta['balance_remaining'] = (float)$cf['balance_remaining']; }
                            if (!isset($meta['marketer_bank'])) {
                                $mb = [
                                    'acc_no' => trim((string)($cf['marketer_account_number'] ?? ($cf['marketer_acc_no'] ?? ''))),
                                    'bank' => trim((string)($cf['marketer_bank_name'] ?? ($cf['marketer_bank'] ?? ''))),
                                    'acc_name' => trim((string)($cf['marketer_account_name'] ?? ($cf['marketer_acc_name'] ?? '')))
                                ];
                                if ($mb['acc_no'] !== '' || $mb['bank'] !== '' || $mb['acc_name'] !== '') { $meta['marketer_bank'] = $mb; }
                            }
                            if (!isset($meta['agent_bank'])) {
                                $ab = [
                                    'acc_no' => trim((string)($cf['agent_account_number'] ?? ($cf['agent_acc_no'] ?? ''))),
                                    'bank' => trim((string)($cf['agent_bank_name'] ?? ($cf['agent_bank'] ?? ''))),
                                    'acc_name' => trim((string)($cf['agent_account_name'] ?? ($cf['agent_acc_name'] ?? '')))
                                ];
                                if ($ab['acc_no'] !== '' || $ab['bank'] !== '' || $ab['acc_name'] !== '') { $meta['agent_bank'] = $ab; }
                            }
                        }
                    }
                } catch (Throwable $eCFb) {}
                // Build normalized block using the same rules as the UI renderer
                $clientNameMeta = (string)($meta['client_name'] ?? '');
                $proj = (string)($meta['project_desc'] ?? ($meta['property'] ?? ''));
                $planType = (string)($meta['plan_type'] ?? '');
                $dealSource = (string)($meta['deal_source'] ?? '');
                $marketerName = (string)($meta['marketer_name'] ?? '');
                $amountOffered = (float)($meta['amount_offered'] ?? 0);
                $amountPaidSoFar = (float)($meta['amount_paid_so_far'] ?? 0);
                $discountAmount = (float)($meta['discount_amount'] ?? 0);
                $discountBy = (string)($meta['discount_approved_by'] ?? '');
                $commissionPct = (float)($meta['commission_pct'] ?? 0);
                $marketerComm = (float)($meta['marketer_comm'] ?? 0);
                $agentComm = (float)($meta['agent_comm'] ?? 0);
                $balanceRem = (float)($meta['balance_remaining'] ?? 0);
                $statusNotes = (string)($meta['client_payment_status'] ?? ($meta['notes'] ?? ''));
                $mkRaw = isset($meta['marketer_bank']) && is_array($meta['marketer_bank']) ? $meta['marketer_bank'] : [];
                $agRaw = isset($meta['agent_bank']) && is_array($meta['agent_bank']) ? $meta['agent_bank'] : [];
                if ((empty($mkRaw) || (empty($mkRaw['acc_no']) && empty($mkRaw['bank']) && empty($mkRaw['acc_name']))) || (empty($agRaw) || (empty($agRaw['acc_no']) && empty($agRaw['bank']) && empty($agRaw['acc_name'])))) {
                    try {
                        $uidProbe = (int)($row['user_id'] ?? 0);
                        $didProbe = (int)($row['deal_id'] ?? 0);
                        if ($didProbe > 0 || $uidProbe > 0) {
                            if (colExists('deals_submit','marketer_bank') || colExists('deals_submit','agent_bank')) {
                                $qs = null; $pr = [];
                                if ($didProbe > 0 && colExists('deals_submit','id')) {
                                    $qs = $pdo->prepare("SELECT marketer_bank, agent_bank FROM deals_submit WHERE id = ? LIMIT 1"); $pr = [$didProbe];
                                } elseif ($uidProbe > 0 && colExists('deals_submit','user_id')) {
                                    $qs = $pdo->prepare("SELECT marketer_bank, agent_bank FROM deals_submit WHERE user_id = ? ORDER BY id DESC LIMIT 1"); $pr = [$uidProbe];
                                }
                                if ($qs) {
                                    $qs->execute($pr);
                                    $drs = $qs->fetch(PDO::FETCH_ASSOC) ?: [];
                                    if ((empty($mkRaw) || (empty($mkRaw['acc_no']) && empty($mkRaw['bank']) && empty($mkRaw['acc_name']))) && !empty($drs['marketer_bank'])) {
                                        $tmp = is_string($drs['marketer_bank']) ? (json_decode($drs['marketer_bank'], true) ?: []) : (is_array($drs['marketer_bank']) ? $drs['marketer_bank'] : []);
                                        if (is_array($tmp)) { $mkRaw = $tmp; }
                                    }
                                    if ((empty($agRaw) || (empty($agRaw['acc_no']) && empty($agRaw['bank']) && empty($agRaw['acc_name']))) && !empty($drs['agent_bank'])) {
                                        $tmp = is_string($drs['agent_bank']) ? (json_decode($drs['agent_bank'], true) ?: []) : (is_array($drs['agent_bank']) ? $drs['agent_bank'] : []);
                                        if (is_array($tmp)) { $agRaw = $tmp; }
                                    }
                                }
                            }
                            $fields = [];
                            foreach (['marketer_account_number','marketer_acc_no','marketer_bank_name','marketer_bank','marketer_account_name','marketer_acc_name','agent_account_number','agent_acc_no','agent_bank_name','agent_bank','agent_account_name','agent_acc_name'] as $f) {
                                if (colExists('deals_submit',$f)) { $fields[] = $f; }
                            }
                            if (!empty($fields)) {
                                $sel = implode(', ', $fields);
                                $qds = null; $pr2 = [];
                                if ($didProbe > 0 && colExists('deals_submit','id')) { $qds = $pdo->prepare("SELECT {$sel} FROM deals_submit WHERE id = ? LIMIT 1"); $pr2 = [$didProbe]; }
                                elseif ($uidProbe > 0 && colExists('deals_submit','user_id')) { $qds = $pdo->prepare("SELECT {$sel} FROM deals_submit WHERE user_id = ? ORDER BY id DESC LIMIT 1"); $pr2 = [$uidProbe]; }
                                if ($qds) {
                                    $qds->execute($pr2);
                                    $dsr = $qds->fetch(PDO::FETCH_ASSOC) ?: [];
                                    if (empty($mkRaw) || (empty($mkRaw['acc_no']) && empty($mkRaw['bank']) && empty($mkRaw['acc_name']))) {
                                        $accNo = trim((string)($dsr['marketer_account_number'] ?? ($dsr['marketer_acc_no'] ?? '')));
                                        $bankN = trim((string)($dsr['marketer_bank_name'] ?? ($dsr['marketer_bank'] ?? '')));
                                        $accNm = trim((string)($dsr['marketer_account_name'] ?? ($dsr['marketer_acc_name'] ?? '')));
                                        if ($accNo !== '' || $bankN !== '' || $accNm !== '') { $mkRaw = ['acc_no'=>$accNo,'bank'=>$bankN,'acc_name'=>$accNm]; }
                                    }
                                    if (empty($agRaw) || (empty($agRaw['acc_no']) && empty($agRaw['bank']) && empty($agRaw['acc_name']))) {
                                        $accNo = trim((string)($dsr['agent_account_number'] ?? ($dsr['agent_acc_no'] ?? '')));
                                        $bankN = trim((string)($dsr['agent_bank_name'] ?? ($dsr['agent_bank'] ?? '')));
                                        $accNm = trim((string)($dsr['agent_account_name'] ?? ($dsr['agent_acc_name'] ?? '')));
                                        if ($accNo !== '' || $bankN !== '' || $accNm !== '') { $agRaw = ['acc_no'=>$accNo,'bank'=>$bankN,'acc_name'=>$accNm]; }
                                    }
                                }
                            }
                        }
                    } catch (Throwable $eDSBanks) {}
                }
                $mkBank = [
                    'acc_no' => trim((string)($mkRaw['acc_no'] ?? ($mkRaw['account_number'] ?? ($mkRaw['accountNumber'] ?? ($mkRaw['accNo'] ?? ($meta['marketer_account_number'] ?? ($meta['marketer_acc_no'] ?? ($meta['marketer_acc_number'] ?? '')))))))),
                    'bank' => trim((string)($mkRaw['bank'] ?? ($mkRaw['bank_name'] ?? ($mkRaw['bankName'] ?? ($meta['marketer_bank_name'] ?? ($meta['marketer_bank'] ?? '')))))),
                    'acc_name' => trim((string)($mkRaw['acc_name'] ?? ($mkRaw['account_name'] ?? ($mkRaw['accountName'] ?? ($meta['marketer_account_name'] ?? ($meta['marketer_acc_name'] ?? ''))))))
                ];
                $agBank = [
                    'acc_no' => trim((string)($agRaw['acc_no'] ?? ($agRaw['account_number'] ?? ($agRaw['accountNumber'] ?? ($agRaw['accNo'] ?? ($meta['agent_account_number'] ?? ($meta['agent_acc_no'] ?? ($meta['agent_acc_number'] ?? '')))))))),
                    'bank' => trim((string)($agRaw['bank'] ?? ($agRaw['bank_name'] ?? ($agRaw['bankName'] ?? ($meta['agent_bank_name'] ?? ($meta['agent_bank'] ?? '')))))),
                    'acc_name' => trim((string)($agRaw['acc_name'] ?? ($agRaw['account_name'] ?? ($agRaw['accountName'] ?? ($meta['agent_account_name'] ?? ($meta['agent_acc_name'] ?? ''))))))
                ];
                $transactionsMeta = isset($meta['transactions']) && is_array($meta['transactions']) ? $meta['transactions'] : [];
                $clientEmailView = (string)($meta['client_email'] ?? '');
                if ($clientEmailView === '' && (int)($row['user_id'] ?? 0) > 0 && colExists('users','email')) {
                    try { $qe = $pdo->prepare("SELECT email FROM users WHERE id = ? LIMIT 1"); $qe->execute([(int)$row['user_id']]); $clientEmailView = (string)($qe->fetchColumn() ?: ''); } catch (Throwable $eE) {}
                }
                $paymentRefView = (string)($row['reference'] ?? '');
                $methodCol = colExists('payments','payment_method') ? 'payment_method' : (colExists('payments','method') ? 'method' : null);
                $paymentMethodView = '';
                if ($methodCol) {
                    try { $qp = $pdo->prepare("SELECT {$methodCol} AS method FROM payments WHERE id = ? LIMIT 1"); $qp->execute([(int)$row['id']]); $paymentMethodView = (string)($qp->fetchColumn() ?: ''); } catch (Throwable $eM) {}
                }
                $normalized = [
                    'client_name' => $clientNameMeta,
                    'client_email' => $clientEmailView,
                    'project_desc' => $proj,
                    'deal_source' => $dealSource,
                    'plan_type' => $planType,
                    'amount_offered' => $amountOffered,
                    'amount_paid_so_far' => $amountPaidSoFar,
                    'amount_paid_now' => (float)($row['amount'] ?? 0),
                    'discount_amount' => $discountAmount,
                    'discount_approved_by' => $discountBy,
                    'commission_pct' => $commissionPct,
                    'marketer_comm' => $marketerComm,
                    'agent_comm' => $agentComm,
                    'balance_remaining' => $balanceRem,
                    'client_payment_status' => $statusNotes,
                    'marketer_bank' => $mkBank,
                    'agent_bank' => $agBank,
                    'transactions' => $transactionsMeta,
                    'marketer_name' => $marketerName,
                    'payment_reference' => $paymentRefView,
                    'payment_method' => ($paymentMethodView !== '' ? $paymentMethodView : 'Bank Transfer')
                ];
                $currentMeta = is_array($meta) ? $meta : [];
                foreach ($normalized as $k=>$v) {
                    $hasKey = array_key_exists($k, $currentMeta);
                    $cur = $hasKey ? $currentMeta[$k] : null;
                    $shouldSet = !$hasKey;
                    if (!$shouldSet) {
                        if (is_string($cur)) { $t = trim($cur); $shouldSet = ($t === '' || $t === '-'); }
                        elseif (is_array($cur)) { $shouldSet = empty($cur); }
                        elseif ($cur === null) { $shouldSet = true; }
                    }
                    if ($shouldSet) { $currentMeta[$k] = $v; }
                }
                try {
                    if (colExists('payments','meta_json')) {
                        $newJson = json_encode($currentMeta);
                        if ($newJson) {
                            $up = $pdo->prepare("UPDATE payments SET meta_json = ? WHERE id = ?");
                            $up->execute([$newJson, (int)$row['id']]);
                            $updated++;
                        }
                    }
                } catch (Throwable $eW) {}
                // Also ensure a visible method is saved when column exists but empty
                if ($methodCol) {
                    try {
                        $methodExisting = '';
                        $qm = $pdo->prepare("SELECT {$methodCol} AS m FROM payments WHERE id = ? LIMIT 1"); $qm->execute([(int)$row['id']]);
                        $methodExisting = (string)($qm->fetchColumn() ?: '');
                        if (trim($methodExisting) === '') {
                            $upm = $pdo->prepare("UPDATE payments SET {$methodCol} = ? WHERE id = ?");
                            $upm->execute(['Bank Transfer', (int)$row['id']]);
                        }
                    } catch (Throwable $eWM) {}
                }
            }
            $action_msg = "Backfill complete: {$updated} record(s) updated out of {$scanned} scanned.";
        } catch (Throwable $e) {
            $action_msg = "Backfill failed: " . (string)$e->getMessage();
        }
    }
}
if ($_SERVER['REQUEST_METHOD'] === 'POST' && $canApprovePayments && !isset($_POST['backfill_meta'])) {
    $pid = (int)($_POST['payment_id'] ?? 0);
    if ($pid > 0) {
        try {
            if (isset($_POST['approve'])) {
                $sql = "UPDATE payments SET status = 'approved'";
                $vals = [];
                if (colExists('payments','approved_by')) { $sql .= ", approved_by = ?"; $vals[] = $userId; }
                if (colExists('payments','approval_date')) { $sql .= ", approval_date = NOW()"; }
                elseif (colExists('payments','approved_at')) { $sql .= ", approved_at = NOW()"; }
                if (colExists('payments','verified_by')) { $sql .= ", verified_by = ?"; $vals[] = $userId; }
                if (colExists('payments','verified_at')) { $sql .= ", verified_at = NOW()"; }
                $sql .= " WHERE id = ?";
                $vals[] = $pid;
                $st = $pdo->prepare($sql);
                $st->execute($vals);
                $action_msg = 'Payment approved.';
                try {
                    $qu = $pdo->prepare("SELECT user_id, amount, reference, meta_json FROM payments WHERE id = ?");
                    $qu->execute([$pid]);
                    $pr = $qu->fetch(PDO::FETCH_ASSOC);
                    $uId = (int)($pr['user_id'] ?? 0);
                    $amt = (float)($pr['amount'] ?? 0);
                    $meta = [];
                    if (!empty($pr['meta_json'])) { $meta = json_decode($pr['meta_json'], true) ?: []; }
                    $submittedBy = (int)($meta['submitted_by_user'] ?? 0);
                    $clientEmail = ''; $clientName = '';
                    $submitEmail = ''; $submitName = '';
                    if ($uId > 0 && colExists('users','email')) {
                        $se = $pdo->prepare("SELECT email, " . (colExists('users','name') ? "name" : "email") . " AS display_name FROM users WHERE id = ? LIMIT 1");
                        $se->execute([$uId]); $rowE = $se->fetch(PDO::FETCH_ASSOC);
                        if ($rowE) { $clientEmail = (string)($rowE['email'] ?? ''); $clientName = (string)($rowE['display_name'] ?? 'Client'); }
                    }
                    if ($submittedBy > 0 && colExists('users','email')) {
                        $ss = $pdo->prepare("SELECT email, " . (colExists('users','name') ? "name" : "email") . " AS display_name FROM users WHERE id = ? LIMIT 1");
                        $ss->execute([$submittedBy]); $rowS = $ss->fetch(PDO::FETCH_ASSOC);
                        if ($rowS) { $submitEmail = (string)($rowS['email'] ?? ''); $submitName = (string)($rowS['display_name'] ?? ''); }
                    }
                    $companyName = function_exists('getSetting') ? getSetting('company_name', 'Aiben Properties') : 'Aiben Properties';
                    $noreplyEmail = function_exists('getSetting') ? getSetting('noreply_email', 'no-reply@aibenproperties.local') : 'no-reply@aibenproperties.local';
                    if ($clientEmail !== '') {
                        $subjectC = "Payment approved";
                        $bodyC = "Dear {$clientName},\n\nYour payment of ₦" . number_format($amt,2) . " has been approved.\n\nThank you,\n{$companyName}";
                        $headersC = "From: {$noreplyEmail}\r\n";
                        @mail($clientEmail, $subjectC, $bodyC, $headersC);
                    }
                    if ($submitEmail !== '') {
                        $subjectS = "Client payment approved";
                        $bodyS = "Hello {$submitName},\n\nThe client payment of ₦" . number_format($amt,2) . " has been approved by Finance.\n\nRegards,\n{$companyName}";
                        $headersS = "From: {$noreplyEmail}\r\n";
                        @mail($submitEmail, $subjectS, $bodyS, $headersS);
                    }
                } catch (Throwable $eN) {}
                try {
                    $dealId = 0; $payAmt = 0.0; $clientIdForLedger = 0;
                    $qp = $pdo->prepare("SELECT deal_id, amount, user_id FROM payments WHERE id = ? LIMIT 1");
                    $qp->execute([$pid]);
                    $prow = $qp->fetch(PDO::FETCH_ASSOC) ?: [];
                    if (!empty($prow)) {
                        $dealId = (int)($prow['deal_id'] ?? 0);
                        $payAmt = (float)($prow['amount'] ?? 0);
                        $clientIdForLedger = (int)($prow['user_id'] ?? 0);
                    }
                    try { createReceiptForApprovedPayment($pid); } catch (Throwable $e) {}
                    try {
                        if (file_exists(__DIR__ . '/includes/charges.php')) { require_once __DIR__ . '/includes/charges.php'; }
                        if (function_exists('applyPaymentToClientCharges')) { applyPaymentToClientCharges($pdo, (int)$pid, (int)$companyId); }
                    } catch (Throwable $e) {}
                    if ($dealId > 0 && $payAmt > 0) {
                        $curPaid = 0.0; $curBal = null; $total = null;
                        if (colExists('deals_submit','amount_paid_so_far')) {
                            $qp2 = $pdo->prepare("SELECT " . (colExists('deals_submit','amount_offered') ? "amount_offered" : "NULL") . " AS amount_offered, amount_paid_so_far" . (colExists('deals_submit','balance_remaining') ? ", balance_remaining" : "") . " FROM deals_submit WHERE id = ? LIMIT 1");
                            $qp2->execute([$dealId]);
                            $dr = $qp2->fetch(PDO::FETCH_ASSOC) ?: [];
                            if (!empty($dr)) {
                                $curPaid = (float)($dr['amount_paid_so_far'] ?? 0);
                                if (isset($dr['balance_remaining'])) { $curBal = (float)$dr['balance_remaining']; }
                                if (isset($dr['amount_offered'])) { $total = (float)$dr['amount_offered']; }
                            }
                            $up1 = $pdo->prepare("UPDATE deals_submit SET amount_paid_so_far = COALESCE(amount_paid_so_far,0) + ? WHERE id = ?");
                            $up1->execute([$payAmt, $dealId]);
                            $newBal = $curBal;
                            if ($newBal !== null) { $newBal = max(0.0, $curBal - $payAmt); }
                            elseif ($total !== null) { $newBal = max(0.0, ($total - ($curPaid + $payAmt))); }
                            if ($newBal !== null && colExists('deals_submit','balance_remaining')) {
                                $up2 = $pdo->prepare("UPDATE deals_submit SET balance_remaining = ? WHERE id = ?");
                                $up2->execute([$newBal, $dealId]);
                            }
                            if (function_exists('updateInvoice')) { updateInvoice($dealId); }
                            if (function_exists('createInvoiceIfNotExists')) { createInvoiceIfNotExists($dealId); }
                            if (function_exists('ensureLedgerTable')) { ensureLedgerTable(); }
                            if ($clientIdForLedger > 0 && function_exists('tableHasColumn')) {
                                $balAfter = null;
                                if (colExists('deals_submit','balance_remaining')) {
                                    $qba = $pdo->prepare("SELECT balance_remaining FROM deals_submit WHERE id = ? LIMIT 1");
                                    $qba->execute([$dealId]);
                                    $balAfter = $qba->fetchColumn();
                                    if ($balAfter !== false) { $balAfter = (float)$balAfter; } else { $balAfter = null; }
                                }
                                $insLed = $pdo->prepare("INSERT INTO ledger (client_id, deal_id, type, amount, balance_after) VALUES (?, ?, 'payment', ?, ?)");
                                $insLed->execute([$clientIdForLedger, $dealId, $payAmt, $balAfter]);
                            }
                        }
                    }
                } catch (Throwable $eRc) {}
                // Update onboarding form status to PAYMENT_VERIFIED for this client
                try {
                    $uId = 0;
                    if (colExists('payments','user_id')) {
                        $qu = $pdo->prepare("SELECT user_id FROM payments WHERE id = ?");
                        $qu->execute([$pid]);
                        $uId = (int)($qu->fetchColumn() ?: 0);
                    }
                    if ($uId > 0) {
                        $updF = $pdo->prepare("UPDATE client_forms SET status = 'payment_verified', updated_at = NOW() WHERE client_id = ?");
                        $updF->execute([$uId]);
                    }
                } catch (Throwable $e) {}
                try {
                    $uId = 0;
                    if (colExists('payments','user_id')) {
                        $qu = $pdo->prepare("SELECT user_id FROM payments WHERE id = ?");
                        $qu->execute([$pid]);
                        $uId = (int)($qu->fetchColumn() ?: 0);
                    }
                    if ($uId > 0 && colExists('deals','eligible_for_offer_letter')) {
                        $cnt = 0;
                        if (colExists('payments','status') && colExists('payments','user_id')) {
                            $qc = $pdo->prepare("SELECT COUNT(*) FROM payments WHERE user_id = ? AND status = 'approved'");
                            $qc->execute([$uId]);
                            $cnt = (int)($qc->fetchColumn() ?: 0);
                        }
                        if ($cnt > 0) {
                            $upd = $pdo->prepare("UPDATE deals SET eligible_for_offer_letter = 1 WHERE user_id = ?");
                            $upd->execute([$uId]);
                        }
                    }
                } catch (Throwable $e) {}
            } elseif (isset($_POST['reject'])) {
                $reason = trim($_POST['rejection_reason'] ?? '');
                $sql = "UPDATE payments SET status = 'rejected'";
                $vals = [];
                if (colExists('payments','rejection_reason')) { $sql .= ", rejection_reason = ?"; $vals[] = $reason; }
                $sql .= " WHERE id = ?";
                $vals[] = $pid;
                $st = $pdo->prepare($sql);
                $st->execute($vals);
                $action_msg = 'Payment rejected.';
                try {
                    $qu = $pdo->prepare("SELECT user_id, amount, meta_json FROM payments WHERE id = ?");
                    $qu->execute([$pid]);
                    $pr = $qu->fetch(PDO::FETCH_ASSOC);
                    $uId = (int)($pr['user_id'] ?? 0);
                    $amt = (float)($pr['amount'] ?? 0);
                    $meta = [];
                    if (!empty($pr['meta_json'])) { $meta = json_decode($pr['meta_json'], true) ?: []; }
                    $submittedBy = (int)($meta['submitted_by_user'] ?? 0);
                    $clientEmail = ''; $clientName = '';
                    $submitEmail = ''; $submitName = '';
                    if ($uId > 0 && colExists('users','email')) {
                        $se = $pdo->prepare("SELECT email, " . (colExists('users','name') ? "name" : "email") . " AS display_name FROM users WHERE id = ? LIMIT 1");
                        $se->execute([$uId]); $rowE = $se->fetch(PDO::FETCH_ASSOC);
                        if ($rowE) { $clientEmail = (string)($rowE['email'] ?? ''); $clientName = (string)($rowE['display_name'] ?? 'Client'); }
                    }
                    if ($submittedBy > 0 && colExists('users','email')) {
                        $ss = $pdo->prepare("SELECT email, " . (colExists('users','name') ? "name" : "email") . " AS display_name FROM users WHERE id = ? LIMIT 1");
                        $ss->execute([$submittedBy]); $rowS = $ss->fetch(PDO::FETCH_ASSOC);
                        if ($rowS) { $submitEmail = (string)($rowS['email'] ?? ''); $submitName = (string)($rowS['display_name'] ?? ''); }
                    }
                    $companyName = function_exists('getSetting') ? getSetting('company_name', 'Aiben Properties') : 'Aiben Properties';
                    $noreplyEmail = function_exists('getSetting') ? getSetting('noreply_email', 'no-reply@aibenproperties.local') : 'no-reply@aibenproperties.local';
                    if ($clientEmail !== '') {
                        $subjectC = "Payment rejected";
                        $bodyC = "Dear {$clientName},\n\nYour payment of ₦" . number_format($amt,2) . " was rejected. Please contact support for details.\n\nRegards,\n{$companyName}";
                        $headersC = "From: {$noreplyEmail}\r\n";
                        @mail($clientEmail, $subjectC, $bodyC, $headersC);
                    }
                    if ($submitEmail !== '') {
                        $subjectS = "Client payment rejected";
                        $bodyS = "Hello {$submitName},\n\nThe client payment of ₦" . number_format($amt,2) . " was rejected by Finance.\n\nRegards,\n{$companyName}";
                        $headersS = "From: {$noreplyEmail}\r\n";
                        @mail($submitEmail, $subjectS, $bodyS, $headersS);
                    }
                } catch (Throwable $eN2) {}
            } elseif (isset($_POST['duplicate'])) {
                $st = $pdo->prepare("UPDATE payments SET status = 'duplicate' WHERE id = ?");
                $st->execute([$pid]);
                $action_msg = 'Payment marked as duplicate.';
            }
        } catch (Throwable $e) {
            $action_msg = 'Action failed.';
        }
    }
}

$tx_response_sent = false;
if ($_SERVER['REQUEST_METHOD'] === 'POST' && isset($_POST['tx_action'])) {
    header('Content-Type: application/json');
    if (!$canApprovePayments) { echo json_encode(['success' => false, 'message' => 'Not allowed']); exit; }
    $tid = isset($_POST['tx_id']) ? (int)$_POST['tx_id'] : 0;
    $act = $_POST['tx_action'] ?? '';
    try {
        if ($tid > 0 && in_array($act, ['approve','reject'], true)) {
            if ($act === 'approve') {
                $stmt = $pdo->prepare("UPDATE transactions SET status = 'approved' WHERE id = ?");
                $stmt->execute([$tid]);
                try {
                    if (colExists('transactions','verified_at')) {
                        $pdo->prepare("UPDATE transactions SET verified_at = NOW() WHERE id = ? AND verified_at IS NULL")->execute([$tid]);
                    }
                    if (colExists('transactions','verified_by')) {
                        $pdo->prepare("UPDATE transactions SET verified_by = ? WHERE id = ? AND (verified_by IS NULL OR verified_by = 0)")->execute([$userId, $tid]);
                    }
                } catch (Throwable $eTMeta) {}
                try {
                    $uStmt = $pdo->prepare("SELECT user_id, transaction_type FROM transactions WHERE id = ?");
                    $uStmt->execute([$tid]);
                    $rowU = $uStmt->fetch(PDO::FETCH_ASSOC);
                    $uId = (int)($rowU['user_id'] ?? 0);
                    $tType = (string)($rowU['transaction_type'] ?? '');
                    if ($uId > 0 && $tType === 'form_fee') {
                        $cf = $pdo->prepare("UPDATE client_forms SET status = 'payment_verified', updated_at = NOW() WHERE client_id = ?");
                        $cf->execute([$uId]);
                    }
                } catch (Throwable $e) {}
                try {
                    if ($pdo->query("SHOW TABLES LIKE 'payments'")->rowCount() > 0 && colExists('payments','reference') && colExists('payments','status')) {
                        $refLike = '%-TX-' . (string)$tid;
                        $sqlP = "UPDATE payments SET status = 'approved'";
                        $valsP = [];
                        if (colExists('payments','approved_by')) { $sqlP .= ", approved_by = ?"; $valsP[] = $userId; }
                        if (colExists('payments','approval_date')) { $sqlP .= ", approval_date = NOW()"; }
                        $sqlP .= " WHERE reference LIKE ? AND LOWER(TRIM(status)) IN " . $queueStatusesSql;
                        $valsP[] = $refLike;
                        $pdo->prepare($sqlP)->execute($valsP);
                    }
                } catch (Throwable $eSyncPm) {}
            } else {
                $stmt = $pdo->prepare("UPDATE transactions SET status = 'rejected' WHERE id = ?");
                $stmt->execute([$tid]);
            }
            echo json_encode(['success' => true]);
        } else {
            echo json_encode(['success' => false, 'message' => 'Invalid request']);
        }
    } catch (Throwable $e) {
        echo json_encode(['success' => false, 'message' => 'DB error']);
    }
    $tx_response_sent = true;
}
if ($tx_response_sent) { exit; }

$pm_response_sent = false;
if ($_SERVER['REQUEST_METHOD'] === 'POST' && isset($_POST['pm_action'])) {
    header('Content-Type: application/json');
    if (!$canApprovePayments) { echo json_encode(['success' => false, 'message' => 'Not allowed']); exit; }
    $pid = isset($_POST['pm_id']) ? (int)$_POST['pm_id'] : 0;
    $act = $_POST['pm_action'] ?? '';
    try {
        if ($pid > 0 && in_array($act, ['approve','reject','reverse'], true)) {
            $oldRow = null;
            $newRow = null;
            $revId = 0;
            $pdo->beginTransaction();
            $lock = $pdo->prepare("SELECT * FROM payments WHERE id = ? FOR UPDATE");
            $lock->execute([$pid]);
            $oldRow = $lock->fetch(PDO::FETCH_ASSOC) ?: null;
            if (!$oldRow) {
                $pdo->rollBack();
                echo json_encode(['success' => false, 'message' => 'Not found']);
                $pm_response_sent = true;
            } else {
                $statusLower = strtolower(trim((string)($oldRow['status'] ?? '')));
                $isReversed = (int)($oldRow['is_reversed'] ?? 0);
                if ($isReversed === 1) {
                    $pdo->rollBack();
                    echo json_encode(['success' => false, 'message' => 'Already reversed']);
                    $pm_response_sent = true;
                } else {
            if ($act === 'approve') {
                if (in_array($statusLower, ['approved','paid','reversed','duplicate'], true)) {
                    $pdo->rollBack();
                    echo json_encode(['success' => true, 'message' => 'Already approved']);
                    $pm_response_sent = true;
                } else {
                try {
                    $receiptColDup = null;
                    if (colExists('payments','receipt_file')) { $receiptColDup = 'receipt_file'; }
                    elseif (colExists('payments','proof_file')) { $receiptColDup = 'proof_file'; }
                    $rcpDup = ($receiptColDup && isset($oldRow[$receiptColDup])) ? trim((string)$oldRow[$receiptColDup]) : '';
                    if ($receiptColDup && $rcpDup !== '') {
                        $final = function_exists('kpiPaymentFinalizedStatuses') ? array_map('strtolower', (array)kpiPaymentFinalizedStatuses()) : ['verified','approved','paid','completed','success'];
                        $ph = implode(',', array_fill(0, count($final), '?'));
                        $qDup = "SELECT id FROM payments WHERE id <> ? AND user_id = ? AND {$receiptColDup} = ? AND LOWER(TRIM(status)) IN ($ph) ORDER BY id DESC LIMIT 1";
                        $pDup = [$pid, (int)($oldRow['user_id'] ?? 0), $rcpDup];
                        foreach ($final as $s) { $pDup[] = strtolower(trim((string)$s)); }
                        $stDup = $pdo->prepare($qDup);
                        $stDup->execute($pDup);
                        $dupId = (int)($stDup->fetchColumn() ?: 0);
                        if ($dupId > 0) {
                            $pdo->prepare("UPDATE payments SET status = 'duplicate' WHERE id = ?")->execute([$pid]);
                            try {
                                if ($pdo->query("SHOW TABLES LIKE 'transactions'")->rowCount() > 0 && colExists('payments','reference') && colExists('transactions','status')) {
                                    $ref0 = (string)($oldRow['reference'] ?? '');
                                    $txId = 0;
                                    if ($ref0 !== '' && preg_match('/-TX-(\\d+)/i', $ref0, $mTx)) { $txId = (int)($mTx[1] ?? 0); }
                                    if ($txId > 0) {
                                        $pdo->prepare("UPDATE transactions SET status = 'approved' WHERE id = ?")->execute([$txId]);
                                        if (colExists('transactions','verified_at')) { $pdo->prepare("UPDATE transactions SET verified_at = NOW() WHERE id = ? AND verified_at IS NULL")->execute([$txId]); }
                                        if (colExists('transactions','verified_by')) { $pdo->prepare("UPDATE transactions SET verified_by = ? WHERE id = ? AND (verified_by IS NULL OR verified_by = 0)")->execute([$userId, $txId]); }
                                    }
                                }
                            } catch (Throwable $eTxDup) {}
                            $selNew = $pdo->prepare("SELECT * FROM payments WHERE id = ? LIMIT 1");
                            $selNew->execute([$pid]);
                            $newRow = $selNew->fetch(PDO::FETCH_ASSOC) ?: null;
                            $pdo->commit();
                            $pm_response_sent = true;
                            echo json_encode(['success' => true, 'message' => 'This receipt was already approved as Payment #' . $dupId . '. Marked this entry as duplicate so it will not count twice.']);
                            exit;
                        }
                    }
                } catch (Throwable $eDup) {}
                try {
                    $dealId = 0; $uid = 0; $rcp = ''; $dt = '';
                    $receiptCol = 'receipt_file';
                    if (!colExists('payments','receipt_file') && colExists('payments','proof_file')) { $receiptCol = 'proof_file'; }
                    $dateCol = colExists('payments','created_at') ? 'created_at' : (colExists('payments','date') ? 'date' : null);
                    $sel = "deal_id, user_id, {$receiptCol} AS receipt";
                    if ($dateCol) { $sel .= ", {$dateCol} AS created_at"; }
                    if (colExists('payments','reference')) { $sel .= ", reference"; }
                    if (colExists('payments','allocation_id')) { $sel .= ", allocation_id"; }
                    if (colExists('payments','property_id')) { $sel .= ", property_id"; }
                    $qp = $pdo->prepare("SELECT {$sel} FROM payments WHERE id = ? LIMIT 1");
                    $qp->execute([$pid]);
                    $rowP = $qp->fetch(PDO::FETCH_ASSOC) ?: [];
                    $dealId = (int)($rowP['deal_id'] ?? 0);
                    $uid = (int)($rowP['user_id'] ?? 0);
                    $rcp = (string)($rowP['receipt'] ?? '');
                    $dt = (string)($rowP['created_at'] ?? '');
                    $allocId = (int)($rowP['allocation_id'] ?? 0);
                    $propId = (int)($rowP['property_id'] ?? 0);
                    if ($dealId <= 0) {
                        $found = 0;
                        if ($found <= 0 && $allocId > 0 && colExists('deals','allocation_id')) {
                            $qd = $pdo->prepare("SELECT id FROM deals WHERE allocation_id = ? ORDER BY id DESC LIMIT 1");
                            $qd->execute([$allocId]); $found = (int)($qd->fetchColumn() ?: 0);
                        }
                        if ($found <= 0 && $propId > 0 && colExists('deals','property_id')) {
                            if ($uid > 0 && colExists('deals','user_id')) {
                                $qd = $pdo->prepare("SELECT id FROM deals WHERE user_id = ? AND property_id = ? ORDER BY id DESC LIMIT 1");
                                $qd->execute([$uid, $propId]); $found = (int)($qd->fetchColumn() ?: 0);
                            } else {
                                $qd = $pdo->prepare("SELECT id FROM deals WHERE property_id = ? ORDER BY id DESC LIMIT 1");
                                $qd->execute([$propId]); $found = (int)($qd->fetchColumn() ?: 0);
                            }
                        }
                        if ($rcp !== '') {
                            if (colExists('deals','receipt_file')) {
                                $qd = $pdo->prepare("SELECT id FROM deals WHERE receipt_file = ? LIMIT 1");
                                $qd->execute([$rcp]); $found = (int)($qd->fetchColumn() ?: 0);
                                if ($found <= 0) {
                                    $base = basename($rcp);
                                    if ($base !== '') {
                                        $qd = $pdo->prepare("SELECT id FROM deals WHERE receipt_file LIKE ? LIMIT 1");
                                        $qd->execute(['%'.$base]); $found = (int)($qd->fetchColumn() ?: 0);
                                    }
                                }
                            } elseif (colExists('deals','proof_file')) {
                                $qd = $pdo->prepare("SELECT id FROM deals WHERE proof_file = ? LIMIT 1");
                                $qd->execute([$rcp]); $found = (int)($qd->fetchColumn() ?: 0);
                                if ($found <= 0) {
                                    $base = basename($rcp);
                                    if ($base !== '') {
                                        $qd = $pdo->prepare("SELECT id FROM deals WHERE proof_file LIKE ? LIMIT 1");
                                        $qd->execute(['%'.$base]); $found = (int)($qd->fetchColumn() ?: 0);
                                    }
                                }
                            }
                        }
                        if ($found <= 0 && $uid > 0 && colExists('deals','user_id')) {
                            if ($dt !== '' && colExists('deals','created_at')) {
                                $qd = $pdo->prepare("SELECT id FROM deals WHERE user_id = ? AND created_at BETWEEN DATE_SUB(?, INTERVAL 1 DAY) AND DATE_ADD(?, INTERVAL 1 DAY) ORDER BY created_at DESC LIMIT 1");
                                $qd->execute([$uid, $dt, $dt]); $found = (int)($qd->fetchColumn() ?: 0);
                            }
                            if ($found <= 0) {
                                $qd = $pdo->prepare("SELECT id FROM deals WHERE user_id = ? ORDER BY id DESC LIMIT 1");
                                $qd->execute([$uid]); $found = (int)($qd->fetchColumn() ?: 0);
                            }
                        }
                        if ($found <= 0 && !empty($rowP['reference']) && colExists('deals','created_at')) {
                            $ref = (string)$rowP['reference'];
                            $ts = null;
                            if (preg_match('/(\d{14})/', $ref, $m)) { $ts = DateTime::createFromFormat('YmdHis', $m[1]); }
                            if ($ts) {
                                $w = $ts->format('Y-m-d H:i:s');
                                if ($uid > 0 && colExists('deals','user_id')) {
                                    $qrf = $pdo->prepare("SELECT id FROM deals WHERE user_id = ? AND created_at BETWEEN DATE_SUB(?, INTERVAL 1 DAY) AND DATE_ADD(?, INTERVAL 1 DAY) ORDER BY created_at DESC LIMIT 1");
                                    $qrf->execute([$uid, $w, $w]); $found = (int)($qrf->fetchColumn() ?: 0);
                                } else {
                                    $qrf = $pdo->prepare("SELECT id FROM deals WHERE created_at BETWEEN DATE_SUB(?, INTERVAL 1 DAY) AND DATE_ADD(?, INTERVAL 1 DAY) ORDER BY created_at DESC LIMIT 1");
                                    $qrf->execute([$w, $w]); $found = (int)($qrf->fetchColumn() ?: 0);
                                }
                            }
                        }
                        if ($found > 0 && colExists('payments','deal_id')) {
                            $up = $pdo->prepare("UPDATE payments SET deal_id = ? WHERE id = ?");
                            $up->execute([$found, $pid]);
                        }
                    }
                } catch (Throwable $eDealLink) {}
                $sql = "UPDATE payments SET status = 'approved'";
                $vals = [];
                if (colExists('payments','approved_by')) { $sql .= ", approved_by = ?"; $vals[] = $userId; }
                if (colExists('payments','approval_date')) { $sql .= ", approval_date = NOW()"; }
                elseif (colExists('payments','approved_at')) { $sql .= ", approved_at = NOW()"; }
                if (colExists('payments','verified_by')) { $sql .= ", verified_by = ?"; $vals[] = $userId; }
                if (colExists('payments','verified_at')) { $sql .= ", verified_at = NOW()"; }
                $sql .= " WHERE id = ?";
                $vals[] = $pid;
                $st = $pdo->prepare($sql);
                $st->execute($vals);
                $selNew = $pdo->prepare("SELECT * FROM payments WHERE id = ? LIMIT 1");
                $selNew->execute([$pid]);
                $newRow = $selNew->fetch(PDO::FETCH_ASSOC) ?: null;

                $newStatusLower = strtolower(trim((string)($newRow['status'] ?? '')));
                if ($newStatusLower !== 'approved') {
                    $pdo->rollBack();
                    echo json_encode(['success' => false, 'message' => 'Approval failed: payment is still pending. Please refresh and try again.']);
                    $pm_response_sent = true;
                } else {
                    try {
                        if ($pdo->query("SHOW TABLES LIKE 'transactions'")->rowCount() > 0 && colExists('payments','reference') && colExists('transactions','status')) {
                            $ref0 = (string)($newRow['reference'] ?? ($oldRow['reference'] ?? ''));
                            $txId = 0;
                            if ($ref0 !== '' && preg_match('/-TX-(\\d+)/i', $ref0, $mTx)) { $txId = (int)($mTx[1] ?? 0); }
                            if ($txId > 0) {
                                $pdo->prepare("UPDATE transactions SET status = 'approved' WHERE id = ?")->execute([$txId]);
                                if (colExists('transactions','verified_at')) { $pdo->prepare("UPDATE transactions SET verified_at = NOW() WHERE id = ? AND verified_at IS NULL")->execute([$txId]); }
                                if (colExists('transactions','verified_by')) { $pdo->prepare("UPDATE transactions SET verified_by = ? WHERE id = ? AND (verified_by IS NULL OR verified_by = 0)")->execute([$userId, $txId]); }
                            }
                        }
                    } catch (Throwable $eTxSync) {}
                $pdo->commit();
                if (function_exists('log_audit')) { log_audit('approve', 'payments', $pid, $oldRow, $newRow); }
                try {
                    $qu = $pdo->prepare("SELECT user_id, reference FROM payments WHERE id = ?");
                    $qu->execute([$pid]);
                    $pr = $qu->fetch(PDO::FETCH_ASSOC);
                    $uId = (int)($pr['user_id'] ?? 0);
                    $ref = strtolower((string)($pr['reference'] ?? ''));
                    if ($uId > 0 && strpos($ref, 'form_fee') === 0) {
                        $updF = $pdo->prepare("UPDATE client_forms SET status = 'payment_verified', updated_at = NOW() WHERE client_id = ?");
                        $updF->execute([$uId]);
                    }
                } catch (Throwable $e) {}
                try {
                    $qu = $pdo->prepare("SELECT user_id, amount, meta_json FROM payments WHERE id = ?");
                    $qu->execute([$pid]);
                    $pr = $qu->fetch(PDO::FETCH_ASSOC);
                    $uId = (int)($pr['user_id'] ?? 0);
                    $amt = (float)($pr['amount'] ?? 0);
                    $meta = [];
                    if (!empty($pr['meta_json'])) { $meta = json_decode($pr['meta_json'], true) ?: []; }
                    $submittedBy = (int)($meta['submitted_by_user'] ?? 0);
                    $clientEmail = ''; $clientName = '';
                    $submitEmail = ''; $submitName = '';
                    if ($uId > 0 && colExists('users','email')) {
                        $se = $pdo->prepare("SELECT email, " . (colExists('users','name') ? "name" : "email") . " AS display_name FROM users WHERE id = ? LIMIT 1");
                        $se->execute([$uId]); $rowE = $se->fetch(PDO::FETCH_ASSOC);
                        if ($rowE) { $clientEmail = (string)($rowE['email'] ?? ''); $clientName = (string)($rowE['display_name'] ?? 'Client'); }
                    }
                    if ($submittedBy > 0 && colExists('users','email')) {
                        $ss = $pdo->prepare("SELECT email, " . (colExists('users','name') ? "name" : "email") . " AS display_name FROM users WHERE id = ? LIMIT 1");
                        $ss->execute([$submittedBy]); $rowS = $ss->fetch(PDO::FETCH_ASSOC);
                        if ($rowS) { $submitEmail = (string)($rowS['email'] ?? ''); $submitName = (string)($rowS['display_name'] ?? ''); }
                    }
                    $companyName = function_exists('getSetting') ? getSetting('company_name', 'Aiben Properties') : 'Aiben Properties';
                    $noreplyEmail = function_exists('getSetting') ? getSetting('noreply_email', 'no-reply@aibenproperties.local') : 'no-reply@aibenproperties.local';
                    if ($clientEmail !== '') {
                        $subjectC = "Payment approved";
                        $bodyC = "Dear {$clientName},\n\nYour payment of ₦" . number_format($amt,2) . " has been approved.\n\nThank you,\n{$companyName}";
                        $headersC = "From: {$noreplyEmail}\r\n";
                        @mail($clientEmail, $subjectC, $bodyC, $headersC);
                    }
                    if ($submitEmail !== '') {
                        $subjectS = "Client payment approved";
                        $bodyS = "Hello {$submitName},\n\nThe client payment of ₦" . number_format($amt,2) . " has been approved by Finance.\n\nRegards,\n{$companyName}";
                        $headersS = "From: {$noreplyEmail}\r\n";
                        @mail($submitEmail, $subjectS, $bodyS, $headersS);
                    }
                } catch (Throwable $eN) {}
                $pm_response_sent = true;
                echo json_encode(['success' => true]);
                }
                }
            } else {
                if ($act === 'reject') {
                    if (in_array($statusLower, ['approved','paid','reversed'], true)) {
                        $pdo->rollBack();
                        echo json_encode(['success' => false, 'message' => 'Status locked']);
                        $pm_response_sent = true;
                    } else {
                        $st = $pdo->prepare("UPDATE payments SET status = 'rejected' WHERE id = ?");
                        $st->execute([$pid]);
                        $selNew = $pdo->prepare("SELECT * FROM payments WHERE id = ? LIMIT 1");
                        $selNew->execute([$pid]);
                        $newRow = $selNew->fetch(PDO::FETCH_ASSOC) ?: null;
                        $pdo->commit();
                        if (function_exists('log_audit')) { log_audit('reject', 'payments', $pid, $oldRow, $newRow); }
                try {
                    $qu = $pdo->prepare("SELECT user_id, amount, meta_json FROM payments WHERE id = ?");
                    $qu->execute([$pid]);
                    $pr = $qu->fetch(PDO::FETCH_ASSOC);
                    $uId = (int)($pr['user_id'] ?? 0);
                    $amt = (float)($pr['amount'] ?? 0);
                    $meta = [];
                    if (!empty($pr['meta_json'])) { $meta = json_decode($pr['meta_json'], true) ?: []; }
                    $submittedBy = (int)($meta['submitted_by_user'] ?? 0);
                    $clientEmail = ''; $clientName = '';
                    $submitEmail = ''; $submitName = '';
                    if ($uId > 0 && colExists('users','email')) {
                        $se = $pdo->prepare("SELECT email, " . (colExists('users','name') ? "name" : "email") . " AS display_name FROM users WHERE id = ? LIMIT 1");
                        $se->execute([$uId]); $rowE = $se->fetch(PDO::FETCH_ASSOC);
                        if ($rowE) { $clientEmail = (string)($rowE['email'] ?? ''); $clientName = (string)($rowE['display_name'] ?? 'Client'); }
                    }
                    if ($submittedBy > 0 && colExists('users','email')) {
                        $ss = $pdo->prepare("SELECT email, " . (colExists('users','name') ? "name" : "email") . " AS display_name FROM users WHERE id = ? LIMIT 1");
                        $ss->execute([$submittedBy]); $rowS = $ss->fetch(PDO::FETCH_ASSOC);
                        if ($rowS) { $submitEmail = (string)($rowS['email'] ?? ''); $submitName = (string)($rowS['display_name'] ?? ''); }
                    }
                    $companyName = function_exists('getSetting') ? getSetting('company_name', 'Aiben Properties') : 'Aiben Properties';
                    $noreplyEmail = function_exists('getSetting') ? getSetting('noreply_email', 'no-reply@aibenproperties.local') : 'no-reply@aibenproperties.local';
                    if ($clientEmail !== '') {
                        $subjectC = "Payment rejected";
                        $bodyC = "Dear {$clientName},\n\nYour payment of ₦" . number_format($amt,2) . " was rejected. Please contact support for details.\n\nRegards,\n{$companyName}";
                        $headersC = "From: {$noreplyEmail}\r\n";
                        @mail($clientEmail, $subjectC, $bodyC, $headersC);
                    }
                    if ($submitEmail !== '') {
                        $subjectS = "Client payment rejected";
                        $bodyS = "Hello {$submitName},\n\nThe client payment of ₦" . number_format($amt,2) . " was rejected by Finance.\n\nRegards,\n{$companyName}";
                        $headersS = "From: {$noreplyEmail}\r\n";
                        @mail($submitEmail, $subjectS, $bodyS, $headersS);
                    }
                } catch (Throwable $eN2) {}
                        $pm_response_sent = true;
                        echo json_encode(['success' => true]);
                    }
                } else {
                    $amt0 = (float)($oldRow['amount'] ?? 0);
                    $now = date('Y-m-d H:i:s');
                    $cols = [];
                    $vals = [];
                    $add = function($col, $val) use (&$cols, &$vals) { $cols[] = $col; $vals[] = $val; };
                    if (colExists('payments','user_id')) { $add('user_id', (int)($oldRow['user_id'] ?? 0)); }
                    if (colExists('payments','company_id') && array_key_exists('company_id', $oldRow)) { $add('company_id', $oldRow['company_id']); }
                    if (colExists('payments','deal_id') && array_key_exists('deal_id', $oldRow)) { $add('deal_id', $oldRow['deal_id']); }
                    if (colExists('payments','allocation_id') && array_key_exists('allocation_id', $oldRow)) { $add('allocation_id', $oldRow['allocation_id']); }
                    if (colExists('payments','property_id') && array_key_exists('property_id', $oldRow)) { $add('property_id', $oldRow['property_id']); }
                    if (colExists('payments','invoice_id') && array_key_exists('invoice_id', $oldRow)) { $add('invoice_id', $oldRow['invoice_id']); }
                    if (colExists('payments','amount')) { $add('amount', 0 - abs($amt0)); }
                    if (colExists('payments','status')) { $add('status', 'reversed'); }
                    if (colExists('payments','reference')) { $add('reference', 'reversal_of_' . $pid); }
                    if (colExists('payments','payment_method')) { $add('payment_method', 'reversal'); }
                    elseif (colExists('payments','method')) { $add('method', 'reversal'); }
                    if (colExists('payments','meta_json')) {
                        $meta = [];
                        if (!empty($oldRow['meta_json'])) {
                            try { $meta = json_decode((string)$oldRow['meta_json'], true) ?: []; } catch (Throwable $eM) { $meta = []; }
                        }
                        $meta['reversal_of_id'] = $pid;
                        $meta['reversed_by'] = $userId;
                        $meta['reversed_at'] = $now;
                        $add('meta_json', json_encode($meta, JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES));
                    }
                    if (colExists('payments','created_at')) { $add('created_at', $now); }
                    if (colExists('payments','updated_at')) { $add('updated_at', $now); }
                    if (count($cols) < 2) {
                        $pdo->rollBack();
                        echo json_encode(['success' => false, 'message' => 'Cannot reverse']);
                        $pm_response_sent = true;
                    } else {
                        $ins = "INSERT INTO payments (" . implode(',', $cols) . ") VALUES (" . implode(',', array_fill(0, count($cols), '?')) . ")";
                        $pdo->prepare($ins)->execute($vals);
                        $revId = (int)$pdo->lastInsertId();
                        $sets = [];
                        $p = [];
                        if (colExists('payments','is_reversed')) { $sets[] = "is_reversed = 1"; }
                        if (colExists('payments','reversed_by')) { $sets[] = "reversed_by = ?"; $p[] = $userId; }
                        if (colExists('payments','reversed_at')) { $sets[] = "reversed_at = NOW()"; }
                        if (colExists('payments','reversal_record_id')) { $sets[] = "reversal_record_id = ?"; $p[] = $revId; }
                        if (colExists('payments','status')) { $sets[] = "status = 'reversed'"; }
                        $p[] = $pid;
                        $pdo->prepare("UPDATE payments SET " . implode(', ', $sets) . " WHERE id = ?")->execute($p);
                        $selNew = $pdo->prepare("SELECT * FROM payments WHERE id = ? LIMIT 1");
                        $selNew->execute([$pid]);
                        $newRow = $selNew->fetch(PDO::FETCH_ASSOC) ?: null;
                        $pdo->commit();
                        if (function_exists('log_audit')) {
                            log_audit('reverse', 'payments', $pid, $oldRow, $newRow);
                            if ($revId > 0) { log_audit('create', 'payments', $revId, null, ['reversal_of_id' => $pid]); }
                        }
                        $pm_response_sent = true;
                        echo json_encode(['success' => true]);
                    }
                }
            }
                }
            }
        } else {
            echo json_encode(['success' => false, 'message' => 'Invalid request']);
        }
    } catch (Throwable $e) {
        try { if ($pdo && $pdo->inTransaction()) { $pdo->rollBack(); } } catch (Throwable $e2) {}
        echo json_encode(['success' => false, 'message' => 'DB error']);
    }
    $pm_response_sent = true;
}
if ($pm_response_sent) { exit; }

if ($_SERVER['REQUEST_METHOD'] === 'POST' && isset($_POST['modal_payload'])) {
    header('Content-Type: application/json');
    $pid = isset($_POST['payment_id']) ? (int)$_POST['payment_id'] : 0;
    $res = ['success' => false];
    try {
        if ($pid > 0) {
            $row = [];
            if (colExists('payments','deal_id')) {
                $st = $pdo->prepare("SELECT p.*,
                                             d.meta_json AS d_meta_json,
                                             d.marketer_name AS d_marketer_name,
                                             d.deal_source AS d_deal_source,
                                             d.payment_plan AS d_payment_plan,
                                             d.project_desc AS d_project_desc,
                                             d.property_estate AS d_property_estate,
                                             " . (colExists('deals','marketer_bank') ? "d.marketer_bank" : "NULL") . " AS d_marketer_bank,
                                             " . (colExists('deals','agent_bank') ? "d.agent_bank" : "NULL") . " AS d_agent_bank
                                      FROM payments p
                                      LEFT JOIN deals d ON p.deal_id = d.id
                                      WHERE p.id = ?
                                      LIMIT 1");
                $st->execute([$pid]); $row = $st->fetch(PDO::FETCH_ASSOC) ?: [];
            } else {
                $st = $pdo->prepare("SELECT * FROM payments WHERE id = ? LIMIT 1");
                $st->execute([$pid]); $row = $st->fetch(PDO::FETCH_ASSOC) ?: [];
            }
            if (!empty($row)) {
                $meta = [];
                $dealMeta = [];
                if (isset($row['meta_json']) && is_string($row['meta_json']) && $row['meta_json'] !== '') {
                    $m = json_decode($row['meta_json'], true); if (is_array($m)) { $meta = $m; }
                }
                if (empty($dealMeta) && isset($row['d_meta_json']) && is_string($row['d_meta_json']) && $row['d_meta_json'] !== '') {
                    $m2 = json_decode($row['d_meta_json'], true); if (is_array($m2)) { $dealMeta = $m2; }
                }
                $metaEff = is_array($dealMeta) ? $dealMeta : [];
                if (is_array($meta) && !empty($meta)) { foreach ($meta as $k => $v) { $metaEff[$k] = $v; } }
                $clientId = (int)($row['user_id'] ?? 0);
                if ($clientId <= 0 && colExists('payments','client_id')) { $clientId = (int)($row['client_id'] ?? 0); }
                if ($clientId <= 0 && isset($metaEff['client_id'])) { $clientId = (int)($metaEff['client_id'] ?? 0); }
                if ($clientId <= 0 && isset($metaEff['user_id'])) { $clientId = (int)($metaEff['user_id'] ?? 0); }
                $clientEmailView = (string)($row['client_email'] ?? ($metaEff['client_email'] ?? ''));
                $clientNameMeta = (string)($row['client_name'] ?? ($metaEff['client_name'] ?? ''));
                if (($clientNameMeta === '' || $clientEmailView === '') && $clientId > 0 && colExists('users','id')) {
                    try {
                        $selName = colExists('users','name') ? "name" : (colExists('users','full_name') ? "full_name" : (colExists('users','first_name') && colExists('users','last_name') ? "CONCAT(first_name,' ',last_name)" : "''"));
                        $selEmail = colExists('users','email') ? "email" : "''";
                        $qu = $pdo->prepare("SELECT {$selName} AS nm, {$selEmail} AS em FROM users WHERE id = ? LIMIT 1");
                        $qu->execute([$clientId]);
                        $urow = $qu->fetch(PDO::FETCH_ASSOC) ?: [];
                        if ($clientNameMeta === '' && !empty($urow['nm'])) { $clientNameMeta = (string)$urow['nm']; }
                        if ($clientEmailView === '' && !empty($urow['em'])) { $clientEmailView = (string)$urow['em']; }
                    } catch (Throwable $e0) {}
                }
                if ($clientNameMeta === '' && $clientEmailView !== '' && colExists('users','email')) {
                    try { $qu = $pdo->prepare("SELECT " . (colExists('users','name') ? "name" : (colExists('users','full_name') ? "full_name" : (colExists('users','first_name') && colExists('users','last_name') ? "CONCAT(first_name,' ',last_name)" : "''"))) . " AS nm FROM users WHERE email = ? LIMIT 1"); $qu->execute([$clientEmailView]); $nm = (string)($qu->fetchColumn() ?: ''); if ($nm !== '') { $clientNameMeta = $nm; } } catch (Throwable $e0) {}
                }
                $cfjson = '';
                if ($clientId > 0 && colExists('client_forms','client_id') && colExists('client_forms','form_data')) {
                    try {
                        $qf = $pdo->prepare("SELECT form_data FROM client_forms WHERE client_id = ? ORDER BY updated_at DESC, created_at DESC LIMIT 1");
                        $qf->execute([$clientId]);
                        $cfjson = (string)($qf->fetchColumn() ?: '');
                    } catch (Throwable $e) {}
                }
                if ($cfjson === '' && $clientEmailView !== '' && colExists('client_forms','form_data')) {
                    try { $qf = $pdo->prepare("SELECT form_data FROM client_forms WHERE form_data LIKE ? ORDER BY created_at DESC LIMIT 1"); $qf->execute(['%"email":"'.$clientEmailView.'"%']); $cfjson = (string)($qf->fetchColumn() ?: ''); } catch (Throwable $e) {}
                    if ($cfjson === '') { try { $qf = $pdo->prepare("SELECT form_data FROM client_forms WHERE form_data LIKE ? ORDER BY created_at DESC LIMIT 1"); $qf->execute(['%"Client Email (for dashboard)":"'.$clientEmailView.'"%']); $cfjson = (string)($qf->fetchColumn() ?: ''); } catch (Throwable $e) {} }
                }
                $cf = $cfjson ? (json_decode($cfjson, true) ?: []) : [];
                $proj = (string)($meta['project_desc'] ?? ($dealMeta['project_desc'] ?? ($meta['property'] ?? ($meta['property_estate'] ?? ($dealMeta['property_estate'] ?? '')))));
                if ($proj === '' && !empty($row['d_project_desc'])) { $proj = (string)$row['d_project_desc']; }
                if ($proj === '' && !empty($row['project_desc'])) { $proj = (string)$row['project_desc']; }
                if ($proj === '' && isset($row['d_property_estate']) && (string)$row['d_property_estate'] !== '') { $proj = (string)$row['d_property_estate']; }
                if ($proj === '' && isset($row['property_estate']) && (string)$row['property_estate'] !== '') { $proj = (string)$row['property_estate']; }
                if ($proj === '' && isset($row['property']) && (string)$row['property'] !== '') { $proj = (string)$row['property']; }
                if ($proj === '' && $cf) {
                    $keys = ['project_desc','Project / Property Description','Project / Property','Property / Estate','Property/Estate','Estate / Property','project_or_property','preferred_property','preferred property','estate_name','property_estate','estate_property','property','estate','project_property','project','property_title','property_name','project_title','Project Name'];
                    foreach ($keys as $k){ if (isset($cf[$k]) && trim((string)$cf[$k])!==''){ $proj = trim((string)$cf[$k]); break; } }
                }
                $dealSource = (string)($meta['deal_source'] ?? ($dealMeta['deal_source'] ?? ($row['deal_source'] ?? ($row['d_deal_source'] ?? ''))));
                if ($dealSource === '' && $cf) {
                    $keys = ['deal_source','Deal Source','source','deal_source_type','lead_source','referral_source','referral source','referrer','referral','ref','submitted_by_role','Submitted By Role','department','team','channel','source_of_deal','source of deal','how did you hear about us','how you heard about us','where did you hear about us','where heard'];
                    foreach ($keys as $k){ if (isset($cf[$k]) && trim((string)$cf[$k])!==''){ $dealSource = trim((string)$cf[$k]); break; } }
                }
                if ($dealSource === '' || $dealSource === '-') { $dealSource = 'Marketing'; }
                $planType = (string)($meta['plan_type'] ?? ($dealMeta['plan_type'] ?? ($row['payment_plan'] ?? ($row['d_payment_plan'] ?? ''))));
                if ($planType === '' && $cf) {
                    $keys = ['plan_type','Payment Plan','plan','payment_plan','plan_name','installment_plan','installment','payment_mode','payment mode'];
                    foreach ($keys as $k){ if (isset($cf[$k]) && trim((string)$cf[$k])!==''){ $planType = trim((string)$cf[$k]); break; } }
                }
                $marketerName = (string)($row['marketer_name'] ?? ($meta['marketer_name'] ?? ($dealMeta['marketer_name'] ?? ($row['d_marketer_name'] ?? ''))));
                if ($marketerName === '' && $cf) {
                    $keys = ['marketer_name','Marketer Name','Marketer or Contact Centre Name','Marketer or Contact Center Name','Contact Centre Name','Contact Center Name','Marketer’s Name','Marketer\'s Name','marketer','sales_agent','sales_rep','contact_rep','uploaded_by_name','submitted_by_name','uploaded_by','created_by_name','agent_name','marketer_full_name','marketer full name'];
                    foreach ($keys as $k){ if (isset($cf[$k]) && trim((string)$cf[$k])!==''){ $marketerName = trim((string)$cf[$k]); break; } }
                    if ($marketerName === '') {
                        foreach ($cf as $kk=>$vv) {
                            if (!is_string($vv) || trim($vv)==='') continue;
                            $lk = strtolower(preg_replace('/[^a-z]/','', (string)$kk));
                            if (strpos($lk,'submittedby')!==false || strpos($lk,'marketername')!==false || strpos($lk,'marketer')!==false || strpos($lk,'contactcentre')!==false || strpos($lk,'contactcenter')!==false) { $marketerName = trim((string)$vv); break; }
                        }
                    }
                }
                $statusNotes = (string)($meta['client_payment_status'] ?? ($meta['notes'] ?? ($row['notes'] ?? '')));
                if ($statusNotes === '' && $cf) {
                    if (isset($cf['client_payment_status']) && trim((string)$cf['client_payment_status']) !== '') { $statusNotes = trim((string)$cf['client_payment_status']); }
                    elseif (isset($cf['Client Payment Status / Notes']) && trim((string)$cf['Client Payment Status / Notes']) !== '') { $statusNotes = trim((string)$cf['Client Payment Status / Notes']); }
                    elseif (isset($cf['Client Payment Status']) && trim((string)$cf['Client Payment Status']) !== '') { $statusNotes = trim((string)$cf['Client Payment Status']); }
                    elseif (isset($cf['notes']) && trim((string)$cf['notes']) !== '') { $statusNotes = trim((string)$cf['notes']); }
                }
                $mkRaw = isset($metaEff['marketer_bank']) && is_array($metaEff['marketer_bank']) ? $metaEff['marketer_bank'] : (isset($meta['marketer_bank']) && is_array($meta['marketer_bank']) ? $meta['marketer_bank'] : []);
                $agRaw = isset($metaEff['agent_bank']) && is_array($metaEff['agent_bank']) ? $metaEff['agent_bank'] : (isset($meta['agent_bank']) && is_array($meta['agent_bank']) ? $meta['agent_bank'] : []);
                if (empty($mkRaw) && isset($row['d_marketer_bank']) && is_string($row['d_marketer_bank']) && trim((string)$row['d_marketer_bank']) !== '') {
                    try { $tmp = json_decode((string)$row['d_marketer_bank'], true); if (is_array($tmp)) { $mkRaw = $tmp; } } catch (Throwable $e) {}
                }
                if (empty($agRaw) && isset($row['d_agent_bank']) && is_string($row['d_agent_bank']) && trim((string)$row['d_agent_bank']) !== '') {
                    try { $tmp = json_decode((string)$row['d_agent_bank'], true); if (is_array($tmp)) { $agRaw = $tmp; } } catch (Throwable $e) {}
                }
                $mkAccNo = (string)($mkRaw['acc_no'] ?? ($mkRaw['account_number'] ?? ($mkRaw['accountNumber'] ?? ($mkRaw['accNo'] ?? ($metaEff['marketer_account_number'] ?? ($metaEff['marketer_acc_no'] ?? ($metaEff['marketer_acc_number'] ?? ($meta['marketer_account_number'] ?? ($meta['marketer_acc_no'] ?? ($meta['marketer_acc_number'] ?? ''))))))))));
                $mkBankName = (string)($mkRaw['bank'] ?? ($mkRaw['bank_name'] ?? ($mkRaw['bankName'] ?? ($metaEff['marketer_bank_name'] ?? ($metaEff['marketer_bank'] ?? ($meta['marketer_bank_name'] ?? ($meta['marketer_bank'] ?? '')))))));
                $mkAccName = (string)($mkRaw['acc_name'] ?? ($mkRaw['account_name'] ?? ($mkRaw['accountName'] ?? ($metaEff['marketer_account_name'] ?? ($metaEff['marketer_acc_name'] ?? ($meta['marketer_account_name'] ?? ($meta['marketer_acc_name'] ?? '')))))));
                $agAccNo = (string)($agRaw['acc_no'] ?? ($agRaw['account_number'] ?? ($agRaw['accountNumber'] ?? ($agRaw['accNo'] ?? ($metaEff['agent_account_number'] ?? ($metaEff['agent_acc_no'] ?? ($metaEff['agent_acc_number'] ?? ($meta['agent_account_number'] ?? ($meta['agent_acc_no'] ?? ($meta['agent_acc_number'] ?? ''))))))))));
                $agBankName = (string)($agRaw['bank'] ?? ($agRaw['bank_name'] ?? ($agRaw['bankName'] ?? ($metaEff['agent_bank_name'] ?? ($metaEff['agent_bank'] ?? ($meta['agent_bank_name'] ?? ($meta['agent_bank'] ?? '')))))));
                $agAccName = (string)($agRaw['acc_name'] ?? ($agRaw['account_name'] ?? ($agRaw['accountName'] ?? ($metaEff['agent_account_name'] ?? ($metaEff['agent_acc_name'] ?? ($meta['agent_account_name'] ?? ($meta['agent_acc_name'] ?? '')))))));
                if (((trim($mkAccNo) === '' && trim($mkBankName) === '' && trim($mkAccName) === '') || (trim($agAccNo) === '' && trim($agBankName) === '' && trim($agAccName) === '')) && (colExists('deals_submit','marketer_bank') || colExists('deals_submit','agent_bank'))) {
                    try {
                        $dsIdLocal = 0;
                        if (isset($metaEff['deal_submit_id']) && (int)$metaEff['deal_submit_id'] > 0) { $dsIdLocal = (int)$metaEff['deal_submit_id']; }
                        if ($dsIdLocal <= 0) {
                            $refTry = (string)($row['reference'] ?? ($row['reference_number'] ?? ($row['ref'] ?? '')));
                            if ($refTry !== '' && preg_match('/-(\d+)\s*$/', $refTry, $mm)) { $dsIdLocal = (int)($mm[1] ?? 0); }
                        }
                        $dsBank = [];
                        if ($dsIdLocal > 0 && colExists('deals_submit','id')) {
                            $qs = $pdo->prepare("SELECT " . (colExists('deals_submit','marketer_bank') ? "marketer_bank" : "NULL") . " AS marketer_bank, " . (colExists('deals_submit','agent_bank') ? "agent_bank" : "NULL") . " AS agent_bank FROM deals_submit WHERE id = ? LIMIT 1");
                            $qs->execute([$dsIdLocal]);
                            $dsBank = $qs->fetch(PDO::FETCH_ASSOC) ?: [];
                        } elseif ($clientId > 0 && colExists('deals_submit','user_id')) {
                            $qs = $pdo->prepare("SELECT " . (colExists('deals_submit','marketer_bank') ? "marketer_bank" : "NULL") . " AS marketer_bank, " . (colExists('deals_submit','agent_bank') ? "agent_bank" : "NULL") . " AS agent_bank FROM deals_submit WHERE user_id = ? ORDER BY created_at DESC, id DESC LIMIT 1");
                            $qs->execute([$clientId]);
                            $dsBank = $qs->fetch(PDO::FETCH_ASSOC) ?: [];
                        }
                        if (!empty($dsBank)) {
                            if ((trim($mkAccNo) === '' && trim($mkBankName) === '' && trim($mkAccName) === '') && !empty($dsBank['marketer_bank'])) {
                                $tmp = is_string($dsBank['marketer_bank']) ? (json_decode((string)$dsBank['marketer_bank'], true) ?: []) : (is_array($dsBank['marketer_bank']) ? $dsBank['marketer_bank'] : []);
                                if (is_array($tmp)) {
                                    $mkAccNo = (string)($tmp['acc_no'] ?? ($tmp['account_number'] ?? ($tmp['accountNumber'] ?? ($tmp['accNo'] ?? $mkAccNo))));
                                    $mkBankName = (string)($tmp['bank'] ?? ($tmp['bank_name'] ?? ($tmp['bankName'] ?? $mkBankName)));
                                    $mkAccName = (string)($tmp['acc_name'] ?? ($tmp['account_name'] ?? ($tmp['accountName'] ?? $mkAccName)));
                                }
                            }
                            if ((trim($agAccNo) === '' && trim($agBankName) === '' && trim($agAccName) === '') && !empty($dsBank['agent_bank'])) {
                                $tmp = is_string($dsBank['agent_bank']) ? (json_decode((string)$dsBank['agent_bank'], true) ?: []) : (is_array($dsBank['agent_bank']) ? $dsBank['agent_bank'] : []);
                                if (is_array($tmp)) {
                                    $agAccNo = (string)($tmp['acc_no'] ?? ($tmp['account_number'] ?? ($tmp['accountNumber'] ?? ($tmp['accNo'] ?? $agAccNo))));
                                    $agBankName = (string)($tmp['bank'] ?? ($tmp['bank_name'] ?? ($tmp['bankName'] ?? $agBankName)));
                                    $agAccName = (string)($tmp['acc_name'] ?? ($tmp['account_name'] ?? ($tmp['accountName'] ?? $agAccName)));
                                }
                            }
                        }
                    } catch (Throwable $eDSB) {}
                }
                $mkBank = ['acc_no' => trim($mkAccNo), 'bank' => trim($mkBankName), 'acc_name' => trim($mkAccName)];
                $agBank = ['acc_no' => trim($agAccNo), 'bank' => trim($agBankName), 'acc_name' => trim($agAccName)];
                $cfReceipt = '';
                if (colExists('client_forms','receipt_path')) {
                    try {
                        if ($clientId > 0 && colExists('client_forms','client_id')) {
                            $qr = $pdo->prepare("SELECT receipt_path FROM client_forms WHERE client_id = ? ORDER BY updated_at DESC, created_at DESC LIMIT 1");
                            $qr->execute([$clientId]); $cfReceipt = (string)($qr->fetchColumn() ?: '');
                        }
                    } catch (Throwable $e) {}
                    if ($cfReceipt === '' && isset($row['receipt_file'])) { $cfReceipt = (string)$row['receipt_file']; }
                    if ($cfReceipt === '' && isset($row['proof_file'])) { $cfReceipt = (string)$row['proof_file']; }
                }
                $instStart = (string)($metaEff['installment_start_date'] ?? '');
                if ($instStart === '' && isset($metaEff['installmentStartDate'])) { $instStart = (string)$metaEff['installmentStartDate']; }
                if ($instStart === '' && isset($metaEff['start_date'])) { $instStart = (string)$metaEff['start_date']; }
                if ($instStart === '' && isset($metaEff['startDate'])) { $instStart = (string)$metaEff['startDate']; }
                if ($instStart === '' && isset($metaEff['deal_submit_id']) && (int)$metaEff['deal_submit_id'] > 0 && colExists('deals_submit','installment_start_date')) {
                    try {
                        $stS = $pdo->prepare("SELECT installment_start_date FROM deals_submit WHERE id = ? LIMIT 1");
                        $stS->execute([(int)$metaEff['deal_submit_id']]);
                        $instStart = (string)($stS->fetchColumn() ?: '');
                    } catch (Throwable $e) {}
                }
                if ($instStart === '' && $clientId > 0 && colExists('deals_submit','installment_start_date') && colExists('deals_submit','user_id')) {
                    try {
                        $stS = $pdo->prepare("SELECT installment_start_date FROM deals_submit WHERE user_id = ? ORDER BY created_at DESC, id DESC LIMIT 1");
                        $stS->execute([$clientId]);
                        $instStart = (string)($stS->fetchColumn() ?: '');
                    } catch (Throwable $e) {}
                }
                $sqmVal = null;
                if (isset($metaEff['sqm']) && is_numeric($metaEff['sqm'])) { $sqmVal = (float)$metaEff['sqm']; }
                elseif (isset($metaEff['sqm_size']) && is_numeric($metaEff['sqm_size'])) { $sqmVal = (float)$metaEff['sqm_size']; }
                elseif (isset($metaEff['plot_size']) && is_numeric($metaEff['plot_size'])) { $sqmVal = (float)$metaEff['plot_size']; }
                elseif (isset($metaEff['size_sqm']) && is_numeric($metaEff['size_sqm'])) { $sqmVal = (float)$metaEff['size_sqm']; }
                elseif (isset($row['sqm']) && is_numeric($row['sqm'])) { $sqmVal = (float)$row['sqm']; }
                $dsId = 0;
                if (isset($metaEff['deal_submit_id']) && (int)$metaEff['deal_submit_id'] > 0) { $dsId = (int)$metaEff['deal_submit_id']; }
                if ($dsId <= 0) {
                    $refTry = (string)($row['reference'] ?? ($row['reference_number'] ?? ($row['ref'] ?? '')));
                    if ($refTry !== '') {
                        if (preg_match('/-(\d+)\s*$/', $refTry, $mm)) { $dsId = (int)($mm[1] ?? 0); }
                    }
                }
                if ($dsId > 0 && (colExists('deals_submit','id'))) {
                    $startCol = colExists('deals_submit','installment_start_date') ? 'installment_start_date' : (colExists('deals_submit','start_date') ? 'start_date' : null);
                    $sqmCol = colExists('deals_submit','sqm') ? 'sqm' : (colExists('deals_submit','area_sqm') ? 'area_sqm' : (colExists('deals_submit','total_sqm') ? 'total_sqm' : null));
                    if ($startCol || $sqmCol) {
                        try {
                            $sel = [];
                            if ($startCol) { $sel[] = "{$startCol} AS installment_start_date"; }
                            if ($sqmCol) { $sel[] = "{$sqmCol} AS sqm"; }
                            $qds = $pdo->prepare("SELECT " . implode(', ', $sel) . " FROM deals_submit WHERE id = ? LIMIT 1");
                            $qds->execute([$dsId]);
                            $dsRow = $qds->fetch(PDO::FETCH_ASSOC) ?: [];
                            if ($instStart === '' && isset($dsRow['installment_start_date']) && is_string($dsRow['installment_start_date'])) { $instStart = (string)$dsRow['installment_start_date']; }
                            if (($sqmVal === null || $sqmVal <= 0) && isset($dsRow['sqm']) && is_numeric($dsRow['sqm'])) { $sqmVal = (float)$dsRow['sqm']; }
                        } catch (Throwable $e) {}
                    }
                    if (($instStart === '' || $sqmVal === null || $sqmVal <= 0) && colExists('deals_submit','meta_json')) {
                        try {
                            $qdm = $pdo->prepare("SELECT meta_json FROM deals_submit WHERE id = ? LIMIT 1");
                            $qdm->execute([$dsId]);
                            $mjRaw = (string)($qdm->fetchColumn() ?: '');
                            if ($mjRaw !== '') {
                                $mj = json_decode($mjRaw, true);
                                if (is_array($mj)) {
                                    if ($instStart === '' && isset($mj['installment_start_date'])) { $instStart = (string)$mj['installment_start_date']; }
                                    if ($instStart === '' && isset($mj['installmentStartDate'])) { $instStart = (string)$mj['installmentStartDate']; }
                                    if ($instStart === '' && isset($mj['start_date'])) { $instStart = (string)$mj['start_date']; }
                                    if ($instStart === '' && isset($mj['startDate'])) { $instStart = (string)$mj['startDate']; }
                                    if (($sqmVal === null || $sqmVal <= 0) && isset($mj['sqm']) && is_numeric($mj['sqm'])) { $sqmVal = (float)$mj['sqm']; }
                                    if (($sqmVal === null || $sqmVal <= 0) && isset($mj['sqm_size']) && is_numeric($mj['sqm_size'])) { $sqmVal = (float)$mj['sqm_size']; }
                                    if (($sqmVal === null || $sqmVal <= 0) && isset($mj['plot_size']) && is_numeric($mj['plot_size'])) { $sqmVal = (float)$mj['plot_size']; }
                                }
                            }
                        } catch (Throwable $e) {}
                    }
                }
                if (($sqmVal === null || $sqmVal <= 0) && isset($metaEff['property_id']) && (int)$metaEff['property_id'] > 0 && colExists('properties','id')) {
                    $pidProp = (int)$metaEff['property_id'];
                    $sqmCol = colExists('properties','area_sqm') ? 'area_sqm' : (colExists('properties','total_sqm') ? 'total_sqm' : null);
                    if ($sqmCol) {
                        try {
                            $sp = $pdo->prepare("SELECT {$sqmCol} FROM properties WHERE id = ? LIMIT 1");
                            $sp->execute([$pidProp]);
                            $v = $sp->fetchColumn();
                            if (is_numeric($v)) { $sqmVal = (float)$v; }
                        } catch (Throwable $e) {}
                    }
                }
                $paymentDate = '';
                try {
                    $cands = [];
                    foreach (['created_at','date','payment_date','approved_at','approval_date','verified_at','updated_at'] as $c) {
                        if (isset($row[$c]) && is_string($row[$c]) && trim($row[$c]) !== '') { $cands[] = trim((string)$row[$c]); }
                    }
                    if (!empty($cands)) { $paymentDate = (string)$cands[0]; }
                } catch (Throwable $e) { $paymentDate = ''; }

                $pmSubmission = [];
                try {
                    $allow = [
                        'allocation_id','property_id','client_charge_id',
                        'payment_reference','reference','ref','reference_number',
                        'payment_method','method','payment_type',
                        'plan_type','payment_plan','custom_months','installment_start_date','sqm',
                        'marketer_bank','agent_bank','marketer_account_number','marketer_bank_name','marketer_account_name','agent_account_number','agent_bank_name','agent_account_name',
                        'submitted_by_user','submitted_by_role','submitted_by_name','marketer_name',
                        'deal_id','deal_submit_id','transactions'
                    ];
                    foreach ($allow as $k) {
                        if (array_key_exists($k, $metaEff)) { $pmSubmission[$k] = $metaEff[$k]; }
                    }
                    if (!isset($pmSubmission['marketer_bank']) || !is_array($pmSubmission['marketer_bank'])) { $pmSubmission['marketer_bank'] = $mkBank; }
                    if (!isset($pmSubmission['agent_bank']) || !is_array($pmSubmission['agent_bank'])) { $pmSubmission['agent_bank'] = $agBank; }
                    if (!isset($pmSubmission['client_id']) && $clientId > 0) { $pmSubmission['client_id'] = $clientId; }
                    $pmSubmission['payment_id'] = $pid;
                    $pmSubmission['payment_amount'] = (float)($row['amount'] ?? 0);
                    $pmSubmission['payment_status'] = (string)($row['status'] ?? '');
                    $pmSubmission['payment_date'] = $paymentDate;
                    if (!isset($pmSubmission['payment_reference']) || trim((string)$pmSubmission['payment_reference']) === '') {
                        $pmSubmission['payment_reference'] = (string)($row['reference'] ?? ($row['reference_number'] ?? ($row['ref'] ?? ($meta['reference'] ?? ($meta['ref'] ?? '')))));
                    }
                    if (!isset($pmSubmission['payment_method']) || trim((string)$pmSubmission['payment_method']) === '') {
                        $pmSubmission['payment_method'] = (string)($row['payment_method'] ?? ($row['method'] ?? ($meta['payment_method'] ?? '')));
                    }
                    if (!isset($pmSubmission['plan_type']) || trim((string)$pmSubmission['plan_type']) === '') {
                        $pmSubmission['plan_type'] = (string)($metaEff['plan_type'] ?? ($row['plan_type'] ?? ($row['payment_plan'] ?? '')));
                    }
                    if (!isset($pmSubmission['installment_start_date']) || trim((string)$pmSubmission['installment_start_date']) === '') {
                        $pmSubmission['installment_start_date'] = $instStart;
                    }
                    if (!isset($pmSubmission['sqm']) || (is_numeric($pmSubmission['sqm']) && (float)$pmSubmission['sqm'] <= 0)) {
                        if ($sqmVal !== null) { $pmSubmission['sqm'] = $sqmVal; }
                    }
                    if ((!isset($pmSubmission['submitted_by_name']) || trim((string)$pmSubmission['submitted_by_name']) === '') && isset($row['submitted_by_name']) && is_string($row['submitted_by_name'])) {
                        $pmSubmission['submitted_by_name'] = (string)$row['submitted_by_name'];
                    }
                    if ((!isset($pmSubmission['submitted_by_role']) || trim((string)$pmSubmission['submitted_by_role']) === '') && isset($row['submitted_by_role']) && is_string($row['submitted_by_role'])) {
                        $pmSubmission['submitted_by_role'] = (string)$row['submitted_by_role'];
                    }
                    if ((!isset($pmSubmission['submitted_by_user']) || (int)$pmSubmission['submitted_by_user'] <= 0) && isset($row['submitted_by_user']) && is_numeric($row['submitted_by_user'])) {
                        $pmSubmission['submitted_by_user'] = (int)$row['submitted_by_user'];
                    }
                    if (!isset($pmSubmission['transactions']) || !is_array($pmSubmission['transactions'])) {
                        $pmSubmission['transactions'] = [[
                            'date' => $paymentDate,
                            'amount' => (float)($row['amount'] ?? 0),
                            'type' => (string)($row['payment_method'] ?? ($row['method'] ?? 'property_payment')),
                            'status' => (string)($row['status'] ?? '')
                        ]];
                    }
                } catch (Throwable $e) { $pmSubmission = []; }
                $history = [];
                $histLimit = 20;
                $allocId = (int)($row['allocation_id'] ?? ($meta['allocation_id'] ?? 0));
                $propId = (int)($row['property_id'] ?? ($meta['property_id'] ?? 0));
                $dealIdForHistory = isset($row['deal_id']) ? (int)$row['deal_id'] : 0;
                $dateExpr = (colExists('payments','created_at') ? "created_at" : (colExists('payments','date') ? "date" : (colExists('payments','updated_at') ? "updated_at" : "NOW()")));
                $typeExpr = (colExists('payments','payment_type') ? "payment_type" : (colExists('payments','type') ? "type" : (colExists('payments','payment_method') ? "payment_method" : "'Payment'")));
                $statusExpr = (colExists('payments','status') ? "status" : (colExists('payments','payment_status') ? "payment_status" : (colExists('payments','client_payment_status') ? "client_payment_status" : "NULL")));
                $amountExpr = (colExists('payments','amount') ? "amount" : (colExists('payments','paid_amount') ? "paid_amount" : (colExists('payments','amount_paid') ? "amount_paid" : "0")));
                $companyClause = '';
                $companyParams = [];
                if ($applyCompanyFilter && colExists('payments','company_id')) { $companyClause = " AND (company_id = ? OR company_id IS NULL OR company_id = 0)"; $companyParams[] = $companyId; }
                $clientFilterSql = '';
                $clientFilterParams = [];
                if ($clientId > 0) {
                    $parts = [];
                    if (colExists('payments','user_id')) { $parts[] = "user_id = ?"; $clientFilterParams[] = $clientId; }
                    if (colExists('payments','client_id')) { $parts[] = "client_id = ?"; $clientFilterParams[] = $clientId; }
                    if (!empty($parts)) { $clientFilterSql = " AND (" . implode(' OR ', $parts) . ")"; }
                }
                if ($allocId > 0 && colExists('payments','allocation_id')) {
                    try {
                        $qh = $pdo->prepare("SELECT id, {$amountExpr} AS amount, {$typeExpr} AS payment_type, {$statusExpr} AS status, {$dateExpr} AS created_at FROM payments WHERE allocation_id = ?{$clientFilterSql}{$companyClause} ORDER BY created_at DESC LIMIT {$histLimit}");
                        $qh->execute(array_merge([$allocId], $clientFilterParams, $companyParams));
                        $history = $qh->fetchAll(PDO::FETCH_ASSOC) ?: [];
                    } catch (Throwable $e) {}
                } elseif ($dealIdForHistory > 0 && colExists('payments','deal_id')) {
                    try {
                        $qh = $pdo->prepare("SELECT id, {$amountExpr} AS amount, {$typeExpr} AS payment_type, {$statusExpr} AS status, {$dateExpr} AS created_at FROM payments WHERE deal_id = ?{$clientFilterSql}{$companyClause} ORDER BY created_at DESC LIMIT {$histLimit}");
                        $qh->execute(array_merge([$dealIdForHistory], $clientFilterParams, $companyParams));
                        $history = $qh->fetchAll(PDO::FETCH_ASSOC) ?: [];
                    } catch (Throwable $e) {}
                } elseif ($propId > 0 && colExists('payments','property_id') && $clientId > 0) {
                    try {
                        $ucl = [];
                        $prm = [$propId];
                        if (colExists('payments','user_id')) { $ucl[] = "user_id = ?"; $prm[] = $clientId; }
                        if (colExists('payments','client_id')) { $ucl[] = "client_id = ?"; $prm[] = $clientId; }
                        if (!empty($ucl)) {
                            $qh = $pdo->prepare("SELECT id, {$amountExpr} AS amount, {$typeExpr} AS payment_type, {$statusExpr} AS status, {$dateExpr} AS created_at FROM payments WHERE property_id = ? AND (" . implode(' OR ', $ucl) . "){$companyClause} ORDER BY created_at DESC LIMIT {$histLimit}");
                            $qh->execute(array_merge($prm, $companyParams));
                            $history = $qh->fetchAll(PDO::FETCH_ASSOC) ?: [];
                        }
                    } catch (Throwable $e) {}
                }
                if (empty($history)) {
                    $history = [[
                        'id' => $pid,
                        'amount' => (float)($row['amount'] ?? 0),
                        'payment_type' => (string)($row['payment_type'] ?? ($row['type'] ?? ($row['payment_method'] ?? ($row['method'] ?? 'Payment')))),
                        'status' => (string)($row['status'] ?? ''),
                        'created_at' => $paymentDate
                    ]];
                }
                if (!empty($history)) {
                    $seenH = [];
                    $uniqH = [];
                    foreach ($history as $h) {
                        $kid = (string)($h['id'] ?? '');
                        $kdt = (string)($h['created_at'] ?? '');
                        $kam = (string)($h['amount'] ?? '');
                        $k = $kid . '|' . $kdt . '|' . $kam;
                        if (isset($seenH[$k])) { continue; }
                        $seenH[$k] = true;
                        $uniqH[] = $h;
                    }
                    $history = $uniqH;
                }
                $pm = [
                    'payment_id' => $pid,
                    'payment_amount' => (float)($row['amount'] ?? 0),
                    'payment_status' => (string)($row['status'] ?? ''),
                    'payment_reference' => (string)($meta['payment_reference'] ?? ($meta['reference'] ?? ($row['reference'] ?? ($row['reference_number'] ?? ($row['ref'] ?? ''))))),
                    'payment_method' => (string)($meta['payment_method'] ?? ($row['payment_method'] ?? ($row['method'] ?? ''))),
                    'payment_date' => $paymentDate,
                    'allocation_id' => $allocId,
                    'property_id' => $propId,
                    'sqm' => $sqmVal,
                    'installment_start_date' => $instStart,
                    'project_desc' => $proj,
                    'project_name' => (string)($row['project_name'] ?? ($meta['project_name'] ?? '')),
                    'property_estate' => (string)($row['property_estate'] ?? ($meta['property_estate'] ?? '')),
                    'deal_source' => $dealSource,
                    'plan_type' => $planType,
                    'payment_plan' => (string)($row['payment_plan'] ?? ($meta['payment_plan'] ?? '')),
                    'marketer_name' => $marketerName,
                    'client_payment_status' => $statusNotes,
                    'notes' => (string)($row['notes'] ?? ($meta['notes'] ?? '')),
                    'amount_offered' => (float)($meta['amount_offered'] ?? ($row['amount_offered'] ?? 0)),
                    'amount_paid_so_far' => (float)($meta['amount_paid_so_far'] ?? ($row['amount_paid_so_far'] ?? 0)),
                    'amount_paid_now' => (float)($row['amount'] ?? ($meta['amount_now'] ?? 0)),
                    'discount_amount' => (float)($meta['discount_amount'] ?? ($row['discount_amount'] ?? 0)),
                    'discount_approved_by' => (string)($meta['discount_approved_by'] ?? ($row['discount_approved_by'] ?? '')),
                    'commission_pct' => (float)($meta['commission_pct'] ?? ($row['commission_percent'] ?? 0)),
                    'marketer_comm' => (float)($meta['marketer_comm'] ?? ($row['marketer_commission'] ?? 0)),
                    'agent_comm' => (float)($meta['agent_comm'] ?? ($row['agent_commission'] ?? 0)),
                    'balance_remaining' => (float)($meta['balance_remaining'] ?? ($row['balance_remaining'] ?? 0)),
                    'submitted_by_role' => (string)($meta['submitted_by_role'] ?? ($row['submitted_by_role'] ?? '')),
                    'marketer_bank' => $mkBank,
                    'agent_bank' => $agBank,
                    'transactions' => isset($meta['transactions']) && is_array($meta['transactions']) ? $meta['transactions'] : []
                ];
                $inv = null; $rcAuto = null;
                if (isset($row['deal_id']) && (int)$row['deal_id'] > 0) {
                    $dealIdX = (int)$row['deal_id'];
                    if (function_exists('updateInvoice')) { @updateInvoice($dealIdX); }
                    if (function_exists('createInvoiceIfNotExists')) { @createInvoiceIfNotExists($dealIdX); }
                    try {
                        $qi = $pdo->prepare("SELECT invoice_number, total_amount, amount_paid, balance, status, due_date, created_at FROM invoices WHERE deal_id = ? LIMIT 1");
                        $qi->execute([$dealIdX]); $invRow = $qi->fetch(PDO::FETCH_ASSOC) ?: [];
                        if (!empty($invRow)) { $inv = $invRow; }
                    } catch (Throwable $e) {}
                    try {
                        $qrn = $pdo->prepare("SELECT receipt_number FROM receipts WHERE deal_id = ? ORDER BY id DESC LIMIT 1");
                        $qrn->execute([$dealIdX]); $rcAuto = (string)($qrn->fetchColumn() ?: '');
                    } catch (Throwable $e) {}
                }
                $res = [
                    'success' => true,
                    'deal_id' => isset($row['deal_id']) ? (int)$row['deal_id'] : 0,
                    'pm' => $pm,
                    'pm_submission' => $pmSubmission,
                    'data' => $cf,
                    'history' => $history,
                    'receipt' => $cfReceipt,
                    'invoice' => $inv,
                    'auto_receipt_number' => $rcAuto,
                    'status' => (string)($meta['form_status'] ?? ''),
                    'submitter' => (string)($meta['submitted_by_name'] ?? ''),
                    'client' => $clientNameMeta,
                    'email' => $clientEmailView
                ];
            }
        }
    } catch (Throwable $e) {
        $res = ['success' => false];
    }
    echo json_encode($res);
    exit;
}

if ($_SERVER['REQUEST_METHOD'] === 'POST' && isset($_POST['history_action'])) {
    header('Content-Type: application/json');
    $action = (string)($_POST['history_action'] ?? '');
    if ($action === 'approved_history') {
        try {
            $uid = isset($_POST['user_id']) ? (int)$_POST['user_id'] : 0;
            $pmid = isset($_POST['payment_id']) ? (int)$_POST['payment_id'] : 0;
            $cname = isset($_POST['client_name']) ? (string)$_POST['client_name'] : '';
            $cemail = isset($_POST['client_email']) ? (string)$_POST['client_email'] : '';
            $items = [];
            $limit = 20;
            $dateExprP0 = (colExists('payments','created_at') ? "created_at" : (colExists('payments','date') ? "date" : (colExists('payments','updated_at') ? "updated_at" : (colExists('payments','verified_at') ? "verified_at" : "NOW()"))));
            $statusExprP0 = (colExists('payments','status') ? "status" : (colExists('payments','payment_status') ? "payment_status" : (colExists('payments','client_payment_status') ? "client_payment_status" : "NULL")));
            $typeExprP0 = (colExists('payments','payment_type') ? "payment_type" : (colExists('payments','type') ? "type" : (colExists('payments','payment_method') ? "payment_method" : "'Payment'")));
            $amountExprP0 = (colExists('payments','amount') ? "amount" : (colExists('payments','paid_amount') ? "paid_amount" : (colExists('payments','amount_paid') ? "amount_paid" : "0")));
            $companyClause = '';
            $companyParams = [];
            if ($applyCompanyFilter && colExists('payments','company_id')) { $companyClause = " AND (company_id = ? OR company_id IS NULL OR company_id = 0)"; $companyParams[] = $companyId; }
            if ($pmid <= 0) {
                $params = [];
                $where = [];
                if ($uid > 0 && colExists('payments','user_id')) { $where[] = "user_id = ?"; $params[] = $uid; }
                if ($uid > 0 && colExists('payments','client_id')) { $where[] = "client_id = ?"; $params[] = $uid; }
                if ($cname !== '' && colExists('payments','client_name')) { $where[] = "client_name = ?"; $params[] = $cname; }
                if ($cemail !== '' && colExists('payments','client_email')) { $where[] = "client_email = ?"; $params[] = $cemail; }
                if (!empty($where)) {
                    $sql = "SELECT id, ".$amountExprP0." AS amount, ".$typeExprP0." AS payment_type, ".$statusExprP0." AS status, ".$dateExprP0." AS created_at FROM payments WHERE (" . implode(' OR ', $where) . ")" . $companyClause . " ORDER BY created_at DESC LIMIT ".$limit;
                    $st = $pdo->prepare($sql); $st->execute(array_merge($params, $companyParams));
                    $rows = $st->fetchAll(PDO::FETCH_ASSOC) ?: [];
                    foreach ($rows as $r) { $items[] = $r; }
                }
            }
            if ($pmid > 0 && colExists('payments','id')) {
                $qp = $pdo->prepare("SELECT id, " . (colExists('payments','user_id') ? "user_id" : "NULL AS user_id") . ", " . (colExists('payments','client_id') ? "client_id" : "NULL AS client_id") . ", " . (colExists('payments','client_name') ? "client_name" : "NULL AS client_name") . ", " . (colExists('payments','client_email') ? "client_email" : "NULL AS client_email") . ", " . (colExists('payments','deal_id') ? "deal_id" : "NULL AS deal_id") . ", " . (colExists('payments','allocation_id') ? "allocation_id" : "NULL AS allocation_id") . ", " . (colExists('payments','property_id') ? "property_id" : "NULL AS property_id") . ", " . (colExists('payments','receipt_file') ? "receipt_file" : (colExists('payments','proof_file') ? "proof_file AS receipt_file" : "NULL AS receipt_file")) . " FROM payments WHERE id = ? LIMIT 1");
                $qp->execute([$pmid]); $base = $qp->fetch(PDO::FETCH_ASSOC) ?: [];
                $uid2 = (int)($base['user_id'] ?? 0);
                if ($uid2 <= 0) { $uid2 = (int)($base['client_id'] ?? 0); }
                $cname2 = (string)($base['client_name'] ?? '');
                $cemail2 = (string)($base['client_email'] ?? '');
                $deal2 = (int)($base['deal_id'] ?? 0);
                $alloc2 = (int)($base['allocation_id'] ?? 0);
                $prop2 = (int)($base['property_id'] ?? 0);
                $rcp2 = (string)($base['receipt_file'] ?? '');
                $dateExpr2 = (colExists('payments','created_at') ? "created_at" : (colExists('payments','date') ? "date" : (colExists('payments','updated_at') ? "updated_at" : (colExists('payments','verified_at') ? "verified_at" : "NOW()"))));
                $statusExpr2 = (colExists('payments','status') ? "status" : (colExists('payments','payment_status') ? "payment_status" : (colExists('payments','client_payment_status') ? "client_payment_status" : "NULL")));
                $typeExpr2 = (colExists('payments','payment_type') ? "payment_type" : (colExists('payments','type') ? "type" : (colExists('payments','payment_method') ? "payment_method" : "'Payment'")));
                $amountExpr2 = (colExists('payments','amount') ? "amount" : (colExists('payments','paid_amount') ? "paid_amount" : (colExists('payments','amount_paid') ? "amount_paid" : "0")));
                $prefix = "SELECT id, ".$amountExpr2." AS amount, ".$typeExpr2." AS payment_type, ".$statusExpr2." AS status, ".$dateExpr2." AS created_at FROM payments WHERE 1=1 ";
                $sqlU = '';
                $pU = [];
                $clientFilterSql = '';
                $clientFilterParams = [];
                if ($uid2 > 0) {
                    $parts = [];
                    if (colExists('payments','user_id')) { $parts[] = "user_id = ?"; $clientFilterParams[] = $uid2; }
                    if (colExists('payments','client_id')) { $parts[] = "client_id = ?"; $clientFilterParams[] = $uid2; }
                    if (!empty($parts)) { $clientFilterSql = " AND (" . implode(' OR ', $parts) . ")"; }
                }
                if ($alloc2 > 0 && colExists('payments','allocation_id')) {
                    $sqlU = $prefix . "AND allocation_id = ?" . $clientFilterSql . $companyClause . " ORDER BY created_at DESC LIMIT ".$limit;
                    $pU = array_merge([$alloc2], $clientFilterParams, $companyParams);
                } elseif ($deal2 > 0 && colExists('payments','deal_id')) {
                    $sqlU = $prefix . "AND deal_id = ?" . $clientFilterSql . $companyClause . " ORDER BY created_at DESC LIMIT ".$limit;
                    $pU = array_merge([$deal2], $clientFilterParams, $companyParams);
                } elseif ($prop2 > 0 && colExists('payments','property_id') && $uid2 > 0) {
                    $uParts = [];
                    $pU = [$prop2];
                    if (colExists('payments','user_id')) { $uParts[] = "user_id = ?"; $pU[] = $uid2; }
                    if (colExists('payments','client_id')) { $uParts[] = "client_id = ?"; $pU[] = $uid2; }
                    if (!empty($uParts)) {
                        $sqlU = $prefix . "AND property_id = ? AND (" . implode(' OR ', $uParts) . ")" . $companyClause . " ORDER BY created_at DESC LIMIT ".$limit;
                        $pU = array_merge($pU, $companyParams);
                    }
                } elseif ($uid2 > 0) {
                    $uParts = [];
                    $pU = [];
                    if (colExists('payments','user_id')) { $uParts[] = "user_id = ?"; $pU[] = $uid2; }
                    if (colExists('payments','client_id')) { $uParts[] = "client_id = ?"; $pU[] = $uid2; }
                    if (!empty($uParts)) {
                        $sqlU = "SELECT id, ".$amountExpr2." AS amount, ".$typeExpr2." AS payment_type, ".$statusExpr2." AS status, ".$dateExpr2." AS created_at FROM payments WHERE (" . implode(' OR ', $uParts) . ")" . $companyClause . " ORDER BY created_at DESC LIMIT ".$limit;
                        $pU = array_merge($pU, $companyParams);
                    }
                }
                if ($sqlU !== '') {
                    try { $stU = $pdo->prepare($sqlU); $stU->execute($pU); $rowsU = $stU->fetchAll(PDO::FETCH_ASSOC) ?: []; foreach ($rowsU as $r) { $items[] = $r; } } catch (Throwable $e) {}
                }
                if (empty($items) && $pmid > 0) {
                    $items[] = [
                        'id' => $pmid,
                        'amount' => null,
                        'payment_type' => null,
                        'status' => null,
                        'created_at' => null
                    ];
                }
            }
            $seen = []; $uniq = [];
            foreach ($items as $it) {
                $key = ((string)($it['id'] ?? '')) . '|' . ((string)($it['created_at'] ?? ''));
                if (!isset($seen[$key])) { $seen[$key] = true; $uniq[] = $it; }
            }
            usort($uniq, function($a,$b){ return strcmp((string)($b['created_at'] ?? ''),(string)($a['created_at'] ?? '')); });
            if (count($uniq) > $limit) { $uniq = array_slice($uniq, 0, $limit); }
            echo json_encode(['success' => true, 'items' => $uniq]);
        } catch (Throwable $e) {
            echo json_encode(['success' => false]);
        }
        exit;
    }
}

if ($_SERVER['REQUEST_METHOD'] === 'POST' && isset($_POST['verify_action'])) {
    header('Content-Type: application/json');
    $id = isset($_POST['verify_id']) ? (int)$_POST['verify_id'] : 0;
    $action = $_POST['verify_action'] ?? '';
    try {
        if ($id > 0 && in_array($action, ['approve','reject'], true)) {
            if ($action === 'approve') {
                $sql = "UPDATE payments SET status = 'approved'";
                $vals = [];
                if (colExists('payments','approved_by')) { $sql .= ", approved_by = ?"; $vals[] = $userId; }
                if (colExists('payments','approval_date')) { $sql .= ", approval_date = NOW()"; }
                elseif (colExists('payments','approved_at')) { $sql .= ", approved_at = NOW()"; }
                if (colExists('payments','verified_by')) { $sql .= ", verified_by = ?"; $vals[] = $userId; }
                if (colExists('payments','verified_at')) { $sql .= ", verified_at = NOW()"; }
                $sql .= " WHERE id = ?";
                $vals[] = $id;
                $sp = $pdo->prepare($sql);
                $sp->execute($vals);
            } else {
                $sp = $pdo->prepare("UPDATE payments SET status = 'rejected' WHERE id = ?");
                $sp->execute([$id]);
            }
            if ($sp->rowCount() > 0) {
                if ($action === 'approve') { try { createReceiptForApprovedPayment($id); } catch (Throwable $e) {} }
                if ($action === 'approve') {
                    try {
                        if (file_exists(__DIR__ . '/includes/charges.php')) { require_once __DIR__ . '/includes/charges.php'; }
                        if (function_exists('applyPaymentToClientCharges')) { applyPaymentToClientCharges($pdo, (int)$id, (int)$companyId); }
                    } catch (Throwable $e) {}
                }
                try {
                    $uStmt = $pdo->prepare("SELECT user_id, reference FROM payments WHERE id = ?");
                    $uStmt->execute([$id]);
                    $rowP = $uStmt->fetch(PDO::FETCH_ASSOC);
                    $uId = (int)($rowP['user_id'] ?? 0);
                    if ($uId > 0 && $action === 'approve') {
                        $cf = $pdo->prepare("UPDATE client_forms SET status = 'payment_verified', updated_at = NOW() WHERE client_id = ?");
                        $cf->execute([$uId]);
                    }
                } catch (Throwable $e) {}
                try {
                    $qr = $pdo->prepare("SELECT user_id, amount, meta_json FROM payments WHERE id = ?");
                    $qr->execute([$id]);
                    $pr = $qr->fetch(PDO::FETCH_ASSOC);
                    $uId = (int)($pr['user_id'] ?? 0);
                    $amt = (float)($pr['amount'] ?? 0);
                    $meta = [];
                    if (!empty($pr['meta_json'])) { $meta = json_decode($pr['meta_json'], true) ?: []; }
                    $submittedBy = (int)($meta['submitted_by_user'] ?? 0);
                    $clientEmail = ''; $clientName = '';
                    $submitEmail = ''; $submitName = '';
                    if ($uId > 0 && colExists('users','email')) {
                        $se = $pdo->prepare("SELECT email, " . (colExists('users','name') ? "name" : "email") . " AS display_name FROM users WHERE id = ? LIMIT 1");
                        $se->execute([$uId]); $rowE = $se->fetch(PDO::FETCH_ASSOC);
                        if ($rowE) { $clientEmail = (string)($rowE['email'] ?? ''); $clientName = (string)($rowE['display_name'] ?? 'Client'); }
                    }
                    if ($submittedBy > 0 && colExists('users','email')) {
                        $ss = $pdo->prepare("SELECT email, " . (colExists('users','name') ? "name" : "email") . " AS display_name FROM users WHERE id = ? LIMIT 1");
                        $ss->execute([$submittedBy]); $rowS = $ss->fetch(PDO::FETCH_ASSOC);
                        if ($rowS) { $submitEmail = (string)($rowS['email'] ?? ''); $submitName = (string)($rowS['display_name'] ?? ''); }
                    }
                    $companyName = function_exists('getSetting') ? getSetting('company_name', 'Aiben Properties') : 'Aiben Properties';
                    $noreplyEmail = function_exists('getSetting') ? getSetting('noreply_email', 'no-reply@aibenproperties.local') : 'no-reply@aibenproperties.local';
                    if ($clientEmail !== '') {
                        $subjectC = $action === 'approve' ? "Payment approved" : "Payment rejected";
                        $bodyC = $action === 'approve'
                            ? "Dear {$clientName},\n\nYour payment of ₦" . number_format($amt,2) . " has been approved.\n\nThank you,\n{$companyName}"
                            : "Dear {$clientName},\n\nYour payment of ₦" . number_format($amt,2) . " was rejected. Please contact support for details.\n\nRegards,\n{$companyName}";
                        $headersC = "From: {$noreplyEmail}\r\n";
                        @mail($clientEmail, $subjectC, $bodyC, $headersC);
                    }
                    if ($submitEmail !== '') {
                        $subjectS = $action === 'approve' ? "Client payment approved" : "Client payment rejected";
                        $bodyS = $action === 'approve'
                            ? "Hello {$submitName},\n\nThe client payment of ₦" . number_format($amt,2) . " has been approved by Finance.\n\nRegards,\n{$companyName}"
                            : "Hello {$submitName},\n\nThe client payment of ₦" . number_format($amt,2) . " was rejected by Finance.\n\nRegards,\n{$companyName}";
                        $headersS = "From: {$noreplyEmail}\r\n";
                        @mail($submitEmail, $subjectS, $bodyS, $headersS);
                    }
                } catch (Throwable $eN) {}
                echo json_encode(['success'=>true]);
            } else {
                echo json_encode(['success'=>false, 'message'=>'Not found']);
            }
        } else {
            echo json_encode(['success'=>false, 'message'=>'Invalid request']);
        }
    } catch (Throwable $e) {
        echo json_encode(['success'=>false, 'message'=>'DB error']);
    }
    exit;
}

if (!isset($queueStatuses)) { $queueStatuses = ['pending_verification','pending_confirmation','pending_gateway','payment_verification','awaiting_verification','pending','submitted']; }
if (!isset($queueStatusesSql)) { $queueStatusesSql = "('" . implode("','", $queueStatuses) . "')"; }
$metrics = ['pending'=>0,'approved_today'=>0,'rejected'=>0,'volume'=>0.0];
try {
    $hasPayments = $pdo->query("SHOW TABLES LIKE 'payments'")->rowCount() > 0;
    if ($hasPayments) {
        $params = [];
        $companyClause = '';
        if ($applyCompanyFilter && colExists('payments','company_id')) {
            $companyClause = " AND ((company_id = ? OR company_id IS NULL)" . (colExists('payments','reference') ? " OR UPPER(COALESCE(reference,'')) LIKE 'FORM_FEE%'" : "") . ")";
            $params[] = $companyId;
        }
        $pendingSet = $queueStatusesSql;
        $st = $pdo->prepare("SELECT COUNT(*) FROM payments WHERE status IN $pendingSet" . $companyClause);
        $st->execute($params); $metrics['pending'] = (int)($st->fetchColumn() ?: 0);
        $st = $pdo->prepare("SELECT COUNT(*) FROM payments WHERE status IN ('rejected','failed')" . $companyClause);
        $st->execute($params); $metrics['rejected'] = (int)($st->fetchColumn() ?: 0);
        $dateCol = colExists('payments','approval_date') ? 'approval_date' : (colExists('payments','updated_at') ? 'updated_at' : (colExists('payments','created_at') ? 'created_at' : 'date'));
        $st = $pdo->prepare("SELECT COUNT(*) FROM payments WHERE status = 'approved' AND DATE($dateCol) = CURDATE()" . $companyClause);
        $st->execute($params); $metrics['approved_today'] = (int)($st->fetchColumn() ?: 0);
        $st = $pdo->prepare("SELECT COALESCE(SUM(amount),0) FROM payments WHERE status = 'approved'" . $companyClause);
        $st->execute($params); $metrics['volume'] = (float)($st->fetchColumn() ?: 0.0);
    } else {
        if ($applyCompanyFilter) {
            $stmt = $pdo->prepare("SELECT COUNT(*) FROM transactions WHERE status = 'pending_verification' AND (company_id = ? OR company_id IS NULL)");
            $stmt->execute([$companyId]); $metrics['pending'] = (int)($stmt->fetchColumn() ?: 0);
            $stmt = $pdo->prepare("SELECT COUNT(*) FROM transactions WHERE status = 'rejected' AND (company_id = ? OR company_id IS NULL)");
            $stmt->execute([$companyId]); $metrics['rejected'] = (int)($stmt->fetchColumn() ?: 0);
            $stmt = $pdo->prepare("SELECT COUNT(*) FROM transactions WHERE status = 'approved' AND DATE(verified_at) = CURDATE() AND (company_id = ? OR company_id IS NULL)");
            $stmt->execute([$companyId]); $metrics['approved_today'] = (int)($stmt->fetchColumn() ?: 0);
            $stmt = $pdo->prepare("SELECT COALESCE(SUM(amount),0) FROM transactions WHERE status = 'approved' AND (company_id = ? OR company_id IS NULL)");
            $stmt->execute([$companyId]); $metrics['volume'] = (float)($stmt->fetchColumn() ?: 0.0);
        } else {
            $metrics['pending'] = (int)$pdo->query("SELECT COUNT(*) FROM transactions WHERE status = 'pending_verification'")->fetchColumn();
            $metrics['rejected'] = (int)$pdo->query("SELECT COUNT(*) FROM transactions WHERE status = 'rejected'")->fetchColumn();
            $metrics['approved_today'] = (int)$pdo->query("SELECT COUNT(*) FROM transactions WHERE status = 'approved' AND DATE(verified_at) = CURDATE()")->fetchColumn();
            $metrics['volume'] = (float)$pdo->query("SELECT COALESCE(SUM(amount),0) FROM transactions WHERE status = 'approved'")->fetchColumn();
        }
    }
} catch (Throwable $e) {}

$filterProjectId = isset($_GET['project_id']) ? (int)$_GET['project_id'] : 0;
$filterProperty = isset($_GET['property']) ? trim($_GET['property']) : '';
$filterPaidFor = isset($_GET['paid_for']) ? strtolower(trim($_GET['paid_for'])) : 'all';
$filterUploadedBy = isset($_GET['uploaded_by']) ? strtolower(trim($_GET['uploaded_by'])) : 'all';
$projectOptions = [];
$propertyOptions = [];
try {
    if ($pdo->query("SHOW TABLES LIKE 'projects'")->rowCount() > 0) {
        $paramsProj = [];
        $companyClauseProj = '';
        if ($applyCompanyFilter && colExists('projects','company_id')) { $companyClauseProj = " WHERE (company_id = ? OR company_id IS NULL)"; $paramsProj[] = $companyId; }
        $spj = $pdo->prepare("SELECT id, name, type FROM projects{$companyClauseProj} ORDER BY name ASC LIMIT 500");
        $spj->execute($paramsProj); $projectOptions = $spj->fetchAll(PDO::FETCH_ASSOC) ?: [];
    }
    if ($pdo->query("SHOW TABLES LIKE 'properties'")->rowCount() > 0) {
        $titleCol = colExists('properties','title') ? 'title' : (colExists('properties','name') ? 'name' : null);
        if ($titleCol) {
            $paramsProps = [];
            $companyClauseProps = '';
            if ($applyCompanyFilter && colExists('properties','company_id')) { $companyClauseProps = " WHERE (company_id = ? OR company_id IS NULL)"; $paramsProps[] = $companyId; }
            $sp = $pdo->prepare("SELECT id, {$titleCol} AS title FROM properties{$companyClauseProps} ORDER BY {$titleCol} ASC LIMIT 200");
            $sp->execute($paramsProps); $propertyOptions = $sp->fetchAll(PDO::FETCH_ASSOC) ?: [];
        }
    }
} catch (Throwable $e) {}

$transactions = [];
try {
    $hasUsersTbl = $pdo->query("SHOW TABLES LIKE 'users'")->rowCount() > 0;
    $nameExprU = ($hasUsersTbl && colExists('users','name')) ? 'u.name' : 'NULL';
    $joinUsers = $hasUsersTbl ? " LEFT JOIN users u ON p.user_id = u.id " : " ";
    $companyClause = '';
    $params = [];
    if ($applyCompanyFilter && colExists('payments','company_id')) {
        $companyClause = " AND ((p.company_id = ? OR p.company_id IS NULL OR p.company_id = 0)" . (colExists('payments','reference') ? " OR UPPER(COALESCE(p.reference,'')) LIKE 'FORM_FEE%'" : "") . ")";
        $params[] = $companyId;
    }
    $receiptExpr = colExists('payments','receipt_file') ? 'p.receipt_file' : (colExists('payments','proof_file') ? 'p.proof_file' : "NULL");
    $dateExpr = colExists('payments','created_at') ? 'p.created_at' : (colExists('payments','date') ? 'p.date' : (colExists('payments','updated_at') ? 'p.updated_at' : "NOW()"));
    $orderSortExpr = "CASE WHEN {$dateExpr} > DATE_ADD(NOW(), INTERVAL 1 DAY) THEN 0 ELSE UNIX_TIMESTAMP({$dateExpr}) END";
    $paymentTypeExpr = colExists('payments','reference')
        ? "CASE WHEN UPPER(COALESCE(p.reference,'')) LIKE 'FORM_FEE%' THEN 'Form Fee' ELSE 'Property Payment' END AS payment_type"
        : "'Property Payment' AS payment_type";
    $paymentTypeRawExpr = colExists('payments','payment_type') ? "p.payment_type AS payment_type_raw" : "NULL AS payment_type_raw";
    $submittedByNameExpr = colExists('payments','submitted_by_name') ? "p.submitted_by_name" : "NULL";
    $submittedByRoleExpr = colExists('payments','submitted_by_role') ? "p.submitted_by_role" : "NULL";
    $sql = "
        SELECT 
            p.id,
            p.user_id,
            $nameExprU AS client_name,
            " . (colExists('payments','deal_id') ? "p.deal_id" : "NULL AS deal_id") . ",
            " . (colExists('payments','allocation_id') ? "p.allocation_id" : "NULL AS allocation_id") . ",
            " . (colExists('payments','project_id') ? "p.project_id" : "NULL AS project_id") . ",
            $paymentTypeExpr,
            $paymentTypeRawExpr,
            p.amount,
            $receiptExpr AS receipt_file,
            $dateExpr AS created_at,
            p.status,
            {$submittedByNameExpr} AS submitted_by_name,
            {$submittedByRoleExpr} AS submitted_by_role
            " . (colExists('payments','meta_json') ? ", p.meta_json AS meta_json" : ", NULL AS meta_json") . "
        FROM payments p
        ".$joinUsers."
        WHERE p.status IN $queueStatusesSql".$companyClause."
        ORDER BY p.id DESC
    ";
    $stmt = $pdo->prepare($sql);
    $stmt->execute($params);
    $transactions = $stmt->fetchAll(PDO::FETCH_ASSOC) ?: [];
    if (!empty($transactions) && ($filterProjectId > 0 || $filterProperty !== '' || $filterPaidFor !== 'all' || $filterUploadedBy !== 'all')) {
        $allocProjectMap = [];
        if ($filterProjectId > 0 && colExists('payments','allocation_id') && colExists('payments','project_id')) {
            try {
                if ($pdo->query("SHOW TABLES LIKE 'allocations'")->rowCount() > 0 && $pdo->query("SHOW TABLES LIKE 'properties'")->rowCount() > 0 && $pdo->query("SHOW TABLES LIKE 'projects'")->rowCount() > 0) {
                    $allocIds = [];
                    foreach ($transactions as $r0) {
                        $pid0 = (int)($r0['project_id'] ?? 0);
                        $aid0 = (int)($r0['allocation_id'] ?? 0);
                        if ($pid0 <= 0 && $aid0 > 0) { $allocIds[$aid0] = true; }
                    }
                    $allocIds = array_keys($allocIds);
                    if (!empty($allocIds)) {
                        $ph = implode(',', array_fill(0, count($allocIds), '?'));
                        $cmpJoin = '';
                        $cmpParams = [];
                        if ($applyCompanyFilter && colExists('projects','company_id') && colExists('payments','company_id')) { $cmpJoin = " AND (prj.company_id = ? OR prj.company_id IS NULL)"; $cmpParams[] = $companyId; }
                        $sqlMap = "
                            SELECT a.id AS allocation_id, prj.id AS project_id
                            FROM allocations a
                            JOIN properties pr ON pr.id = a.property_id
                            JOIN projects prj ON prj.ref_table = 'properties' AND prj.ref_id = pr.id$cmpJoin
                            WHERE a.id IN ($ph)
                        ";
                        $stM = $pdo->prepare($sqlMap);
                        $stM->execute(array_merge($allocIds, $cmpParams));
                        $rowsM = $stM->fetchAll(PDO::FETCH_ASSOC) ?: [];
                        foreach ($rowsM as $rm) {
                            $aid = (int)($rm['allocation_id'] ?? 0);
                            $pid = (int)($rm['project_id'] ?? 0);
                            if ($aid > 0 && $pid > 0) { $allocProjectMap[$aid] = $pid; }
                        }
                    }
                }
            } catch (Throwable $e) { $allocProjectMap = []; }
        }
        $filtered = [];
        foreach ($transactions as $r) {
            if ($filterProjectId > 0) {
                $effPid = (int)($r['project_id'] ?? 0);
                if ($effPid <= 0) {
                    $aid = (int)($r['allocation_id'] ?? 0);
                    if ($aid > 0 && isset($allocProjectMap[$aid])) { $effPid = (int)$allocProjectMap[$aid]; }
                }
                if ($effPid !== (int)$filterProjectId) { continue; }
            }
            $propText = '';
            $subRole = '';
            $subUid = 0;
            try {
                if (colExists('payments','meta_json')) {
                    $qpm = $pdo->prepare("SELECT meta_json FROM payments WHERE id = ? LIMIT 1");
                    $qpm->execute([(int)$r['id']]);
                    $mjRaw = (string)($qpm->fetchColumn() ?: '');
                    if ($mjRaw !== '') {
                        $m = json_decode($mjRaw, true) ?: [];
                        $propText = (string)($m['project_desc'] ?? ($m['property'] ?? ''));
                        $subRole = strtolower((string)($m['submitted_by_role'] ?? ''));
                        $subUid = (int)($m['submitted_by_user'] ?? 0);
                        if (isset($m['submitted_by_name']) && trim((string)$m['submitted_by_name']) !== '') { $r['submitted_by_name'] = (string)$m['submitted_by_name']; }
                        if (isset($m['marketer_name']) && trim((string)$m['marketer_name']) !== '') { $r['marketer_name'] = (string)$m['marketer_name']; }
                    } elseif (colExists('payments','deal_id') && colExists('deals','meta_json') && isset($r['deal_id']) && (int)$r['deal_id'] > 0) {
                        $qd = $pdo->prepare("SELECT meta_json FROM deals WHERE id = ? LIMIT 1");
                        $qd->execute([(int)$r['deal_id']]);
                        $dm = (string)($qd->fetchColumn() ?: '');
                        if ($dm !== '') {
                            $m = json_decode($dm, true) ?: [];
                            $propText = (string)($m['project_desc'] ?? ($m['property'] ?? ($m['property_estate'] ?? '')));
                            $subRole = strtolower((string)($m['submitted_by_role'] ?? ''));
                            $subUid = (int)($m['submitted_by_user'] ?? 0);
                            if (isset($m['submitted_by_name']) && trim((string)$m['submitted_by_name']) !== '') { $r['submitted_by_name'] = (string)$m['submitted_by_name']; }
                            if (isset($m['marketer_name']) && trim((string)$m['marketer_name']) !== '') { $r['marketer_name'] = (string)$m['marketer_name']; }
                        }
                    }
                }
            } catch (Throwable $eM) {}
            $uploaderGroup = '';
            if (in_array($subRole, ['marketing','sales','sales_agent','agent'], true)) { $uploaderGroup = 'marketing'; }
            elseif (in_array($subRole, ['contact_rep','customer_rep','contact_centre','contact_center','customer_care'], true)) { $uploaderGroup = 'contact'; }
            elseif ($subUid === 0) { $uploaderGroup = 'client'; }
            else { $uploaderGroup = 'client'; }
            if ($filterProperty !== '' && ($propText === '' || stripos($propText, $filterProperty) === false)) { continue; }
            if ($filterPaidFor === 'form_fee' && strtolower((string)$r['payment_type']) !== 'form fee') { continue; }
            if ($filterPaidFor === 'property' && strtolower((string)$r['payment_type']) !== 'property payment') { continue; }
            if ($filterUploadedBy !== 'all' && $uploaderGroup !== $filterUploadedBy) { continue; }
            $r['property_text'] = $propText;
            $r['submitted_group'] = $uploaderGroup;
            $filtered[] = $r;
        }
        $transactions = $filtered;
    }
    if (!empty($transactions)) {
        $hasClientsTbl = $pdo->query("SHOW TABLES LIKE 'clients'")->rowCount() > 0;
        foreach ($transactions as &$r) {
            if (empty($r['client_name'])) {
                $uid = (int)($r['user_id'] ?? 0);
                $nm = '';
                if ($hasUsersTbl && $uid > 0) {
                    if (colExists('users','name')) {
                        $qs = $pdo->prepare("SELECT name FROM users WHERE id = ?");
                        $qs->execute([$uid]); $nm = (string)($qs->fetchColumn() ?: '');
                    }
                    if ($nm === '' && colExists('users','first_name') && colExists('users','last_name')) {
                        $qs = $pdo->prepare("SELECT CONCAT(first_name,' ',last_name) FROM users WHERE id = ?");
                        $qs->execute([$uid]); $nm = (string)($qs->fetchColumn() ?: '');
                    }
                    if ($nm === '' && colExists('users','full_name')) {
                        $qs = $pdo->prepare("SELECT full_name FROM users WHERE id = ?");
                        $qs->execute([$uid]); $nm = (string)($qs->fetchColumn() ?: '');
                    }
                }
                if ($nm === '' && $uid > 0) { $nm = 'Client #'.$uid; }
                $r['client_name'] = $nm !== '' ? $nm : ($r['client_name'] ?? '');
            }
        }
        unset($r);
    }
} catch (Throwable $e) {}
// Ensure metric pending count matches the visible queue exactly
$metrics['pending'] = is_array($transactions) ? count($transactions) : 0;
$perPage = isset($_GET['per_page']) ? (int)$_GET['per_page'] : 50;
$perPage = max(10, min(200, $perPage));
$page = isset($_GET['page']) ? (int)$_GET['page'] : 1;
$page = max(1, $page);
$totalRows = is_array($transactions) ? count($transactions) : 0;
$totalPages = $perPage > 0 ? (int)ceil($totalRows / $perPage) : 1;
if ($totalPages <= 0) { $totalPages = 1; }
if ($page > $totalPages) { $page = $totalPages; }
$offset = ($page - 1) * $perPage;
$transactionsPage = is_array($transactions) ? array_slice($transactions, $offset, $perPage) : [];
?>
<div class="container-fluid px-4">
    <div class="d-flex justify-content-between align-items-center mt-4 mb-3">
        <h1 class="h3 mb-0"><i class="fa-solid fa-list-check me-2"></i>Finance Payment Approvals</h1>
        <div class="d-flex align-items-center gap-2">
            <?php if ($canVerify): ?>
                <span class="badge bg-primary">Role: <?= htmlspecialchars($role) ?></span>
            <?php else: ?>
                <span class="badge bg-secondary">Read-only</span>
            <?php endif; ?>
        </div>
    </div>
    <?php if ($canVerify && isset($_GET['debug']) && $_GET['debug'] === '1'): ?>
    <div class="card mt-3">
        <div class="card-header">Debug</div>
        <div class="card-body">
            <?php
            $pid = isset($_GET['pid']) ? (int)$_GET['pid'] : 0;
            if ($pid > 0) {
                try {
                    $refExprDbg = colExists('payments','reference') ? 'reference' : (colExists('payments','ref') ? 'ref' : "''");
                    $pmExprDbg = colExists('payments','payment_method') ? 'payment_method' : (colExists('payments','method') ? 'method' : "''");
                    $mjExprDbg = colExists('payments','meta_json') ? 'meta_json' : 'NULL';
                    $sqlDbg = "SELECT id, user_id, amount, {$refExprDbg} AS reference, {$pmExprDbg} AS pm, {$mjExprDbg} AS meta_json FROM payments WHERE id = ? LIMIT 1";
                    $stp = $pdo->prepare($sqlDbg);
                    $stp->execute([$pid]);
                    $prow = $stp->fetch(PDO::FETCH_ASSOC) ?: null;
                    if ($prow) {
                        $meta = [];
                        if (!empty($prow['meta_json'])) { $t = json_decode((string)$prow['meta_json'], true); if (is_array($t)) { $meta = $t; } }
                        $clientEmail = (string)($meta['client_email'] ?? '');
                        if ($clientEmail === '' && (int)$prow['user_id'] > 0 && colExists('users','email')) { try { $qe = $pdo->prepare("SELECT email FROM users WHERE id = ? LIMIT 1"); $qe->execute([(int)$prow['user_id']]); $clientEmail = (string)($qe->fetchColumn() ?: ''); } catch (Throwable $e) {} }
                        $dealSource = (string)($meta['deal_source'] ?? '');
                        $marketerName = (string)($meta['marketer_name'] ?? '');
                        $clientPhone = '';
                        if ((int)$prow['user_id'] > 0 && colExists('users','phone')) {
                            try { $qp = $pdo->prepare("SELECT phone FROM users WHERE id = ? LIMIT 1"); $qp->execute([(int)$prow['user_id']]); $clientPhone = (string)($qp->fetchColumn() ?: ''); } catch (Throwable $e) {}
                        }
                        if ($clientPhone === '') {
                            $phoneKeys = ['phone','Phone','mobile','Mobile','company_contact','Company Contact','contact','Contact'];
                            foreach ($phoneKeys as $pk) { if (!empty($meta[$pk]) && is_string($meta[$pk]) && trim($meta[$pk]) !== '') { $clientPhone = trim((string)$meta[$pk]); break; } }
                        }
                        $mkAccNo = is_array($meta['marketer_bank'] ?? null) ? (string)($meta['marketer_bank']['acc_no'] ?? '') : '';
                        $mkBank = is_array($meta['marketer_bank'] ?? null) ? (string)($meta['marketer_bank']['bank'] ?? '') : '';
                        $mkAccName = is_array($meta['marketer_bank'] ?? null) ? (string)($meta['marketer_bank']['acc_name'] ?? '') : '';
                        $agAccNo = is_array($meta['agent_bank'] ?? null) ? (string)($meta['agent_bank']['acc_no'] ?? '') : '';
                        $agBank = is_array($meta['agent_bank'] ?? null) ? (string)($meta['agent_bank']['bank'] ?? '') : '';
                        $agAccName = is_array($meta['agent_bank'] ?? null) ? (string)($meta['agent_bank']['acc_name'] ?? '') : '';
                        $notes = is_string($meta['client_payment_status'] ?? null) ? (string)$meta['client_payment_status'] : '';
                        if ($notes === '' && colExists('payments','deal_id') && colExists('deals','notes') && !empty($prow['deal_id'])) {
                            try { $qn = $pdo->prepare("SELECT notes FROM deals WHERE id = ? LIMIT 1"); $qn->execute([(int)$prow['deal_id']]); $notes = (string)($qn->fetchColumn() ?: ''); } catch (Throwable $e) {}
                        }
                        $submittedBy = '';
                        $sbCandidates = [
                            $meta['marketer_name'] ?? null,
                            $meta['contact_rep'] ?? null,
                            $meta['contact_centre_name'] ?? null,
                            $meta['submitted_by_name'] ?? null,
                            $meta['Submitted By'] ?? null,
                            $meta['submitted_by'] ?? null,
                            $meta['SUBMITTED BY'] ?? null,
                            $meta['created_by_name'] ?? null,
                            $meta['sales_agent'] ?? null,
                            $meta['sales_rep'] ?? null,
                            $meta['uploaded_by_name'] ?? null,
                            $meta['agent_name'] ?? null,
                        ];
                        foreach ($sbCandidates as $cand) {
                            $val = is_string($cand) ? trim($cand) : '';
                            if ($val !== '') { $submittedBy = $val; break; }
                        }
                        if ($submittedBy === '' && isset($meta['submitted_by_user'])) {
                            $subUidFull = (int)$meta['submitted_by_user'];
                            if ($subUidFull > 0 && colExists('users','name')) {
                                try { $qn = $pdo->prepare("SELECT name FROM users WHERE id = ? LIMIT 1"); $qn->execute([$subUidFull]); $n = (string)($qn->fetchColumn() ?: ''); if ($n !== '') { $submittedBy = $n; } } catch (Throwable $e) {}
                            }
                        }
                        echo '<div class="table-responsive"><table class="table table-sm table-bordered w-auto">';
                        echo '<tr><th>Payment ID</th><td>'.(int)$prow['id'].'</td></tr>';
                        echo '<tr><th>User ID</th><td>'.(int)$prow['user_id'].'</td></tr>';
                        echo '<tr><th>Reference</th><td>'.htmlspecialchars((string)$prow['reference']).'</td></tr>';
                        echo '<tr><th>Payment Method</th><td>'.htmlspecialchars((string)$prow['pm']).'</td></tr>';
                        echo '<tr><th>Client Email</th><td>'.htmlspecialchars($clientEmail).'</td></tr>';
                        echo '<tr><th>Client Phone</th><td>'.htmlspecialchars($clientPhone).'</td></tr>';
                        echo '<tr><th>Marketer or Contact Centre Name</th><td>'.htmlspecialchars($marketerName).'</td></tr>';
                        // Deal Source intentionally hidden
                        echo '<tr><th>Submitted By</th><td>'.htmlspecialchars($submittedBy).'</td></tr>';
                        if ($mkAccNo !== '' || $mkBank !== '' || $mkAccName !== '') {
                            echo '<tr><th>Marketer Account</th><td>'.htmlspecialchars(trim(($mkAccName?:'').' — '.($mkBank?:'').' — '.($mkAccNo?:''))).'</td></tr>';
                        }
                        if ($agAccNo !== '' || $agBank !== '' || $agAccName !== '') {
                            echo '<tr><th>Agent Account</th><td>'.htmlspecialchars(trim(($agAccName?:'').' — '.($agBank?:'').' — '.($agAccNo?:''))).'</td></tr>';
                        }
                        if ($notes !== '') {
                            echo '<tr><th>Notes</th><td>'.htmlspecialchars($notes).'</td></tr>';
                        }
                        echo '</table></div>';
                    } else {
                        echo '<div class="alert alert-warning">Payment not found.</div>';
                    }
                } catch (Throwable $e) {
                    echo '<div class="alert alert-danger">Error fetching payment.</div>';
                }
            }
            $lookupMatches = [];
            $pendingPreview = [];
            $q = isset($_GET['q']) ? trim($_GET['q']) : '';
            $uidLookup = isset($_GET['uid']) ? (int)$_GET['uid'] : 0;
            try {
                // Build pending preview (limited union)
                $hasUsersTbl = $pdo->query("SHOW TABLES LIKE 'users'")->rowCount() > 0;
                $nameExprU = ($hasUsersTbl && colExists('users','name')) ? 'u.name' : 'NULL';
                $joinUsersTx = $hasUsersTbl ? " LEFT JOIN users u ON t.user_id = u.id " : " ";
                $joinUsersPm = $hasUsersTbl ? " LEFT JOIN users u ON p.user_id = u.id " : " ";
                $txCompanyClause = '';
                $pmCompanyClause = '';
                $paramsPreview = [];
                if ($applyCompanyFilter && colExists('transactions','company_id')) { $txCompanyClause = " AND (t.company_id = ? OR t.company_id IS NULL)"; $paramsPreview[] = $companyId; }
                if ($applyCompanyFilter && colExists('payments','company_id')) { $pmCompanyClause = " AND (p.company_id = ? OR p.company_id IS NULL)"; $paramsPreview[] = $companyId; }
                $receiptExpr = colExists('payments','receipt_file') ? 'p.receipt_file' : (colExists('payments','proof_file') ? 'p.proof_file' : "NULL");
                $dateExpr = colExists('payments','created_at') ? 'p.created_at' : (colExists('payments','date') ? 'p.date' : (colExists('payments','updated_at') ? 'p.updated_at' : "NOW()"));
                $uidFilterTx = $uidLookup > 0 ? " AND t.user_id = ?" : "";
                $uidFilterPm = $uidLookup > 0 ? " AND p.user_id = ?" : "";
                if ($uidLookup > 0) { $paramsPreview[] = $uidLookup; $paramsPreview[] = $uidLookup; }
                $sqlPreview = "
                    SELECT t.id, t.user_id, $nameExprU AS client_name, t.amount, t.receipt_file AS receipt_file, t.created_at, t.status, 'transactions' AS source
                    FROM transactions t
                    $joinUsersTx
                    WHERE t.status IN ('pending_verification','pending_confirmation')$txCompanyClause$uidFilterTx
                    UNION
                    SELECT p.id, p.user_id, $nameExprU AS client_name, p.amount, $receiptExpr AS receipt_file, $dateExpr AS created_at, p.status, 'payments' AS source
                    FROM payments p
                    $joinUsersPm
                    WHERE p.status IN $queueStatusesSql$pmCompanyClause$uidFilterPm
                    ORDER BY created_at DESC
                    LIMIT 50
                ";
                $stPr = $pdo->prepare($sqlPreview);
                $stPr->execute($paramsPreview);
                $pendingPreview = $stPr->fetchAll(PDO::FETCH_ASSOC) ?: [];
            } catch (Throwable $e) {}
            try {
                // User/client lookup by name
                if ($q !== '') {
                    $like = '%' . $q . '%';
                    // users table
                    if ($pdo->query("SHOW TABLES LIKE 'users'")->rowCount() > 0) {
                        $sqlU = "SELECT id, 
                                 " . (colExists('users','name') ? "name" : (colExists('users','full_name') ? "full_name" : (colExists('users','first_name') && colExists('users','last_name') ? "CONCAT(first_name,' ',last_name)" : "''"))) . " AS display_name,
                                 " . (colExists('users','email') ? "email" : "''") . " AS email,
                                 " . (colExists('users','role') ? "role" : "''") . " AS role
                                 FROM users
                                 WHERE " . (colExists('users','name') ? "name LIKE ?" : (colExists('users','full_name') ? "full_name LIKE ?" : (colExists('users','first_name') && colExists('users','last_name') ? "CONCAT(first_name,' ',last_name) LIKE ?" : "1=0"))) . "
                                 LIMIT 20";
                        $su = $pdo->prepare($sqlU); $su->execute([$like]);
                        $lookupMatches = array_merge($lookupMatches, $su->fetchAll(PDO::FETCH_ASSOC) ?: []);
                    }
                    // clients table
                    if ($pdo->query("SHOW TABLES LIKE 'clients'")->rowCount() > 0) {
                        $sqlC = "SELECT id,
                                 " . (colExists('clients','name') ? "name" : (colExists('clients','full_name') ? "full_name" : (colExists('clients','first_name') && colExists('clients','last_name') ? "CONCAT(first_name,' ',last_name)" : "''"))) . " AS display_name
                                 FROM clients
                                 WHERE " . (colExists('clients','name') ? "name LIKE ?" : (colExists('clients','full_name') ? "full_name LIKE ?" : (colExists('clients','first_name') && colExists('clients','last_name') ? "CONCAT(first_name,' ',last_name) LIKE ?" : "1=0"))) . "
                                 LIMIT 20";
                        $sc = $pdo->prepare($sqlC); $sc->execute([$like]);
                        $rowsC = $sc->fetchAll(PDO::FETCH_ASSOC) ?: [];
                        foreach ($rowsC as $rc) { $lookupMatches[] = ['id'=>$rc['id'],'display_name'=>$rc['display_name'],'email'=>'','role'=>'client']; }
                    }
                }
            } catch (Throwable $e) {}
            $txCounts = [];
            $pmCounts = [];
            try {
                $sqlD = "SELECT status, COUNT(*) AS cnt FROM transactions GROUP BY status";
                $stD = $pdo->query($sqlD);
                $txCounts = $stD ? $stD->fetchAll(PDO::FETCH_ASSOC) : [];
            } catch (Throwable $e) {}
            try {
                if ($pdo->query("SHOW TABLES LIKE 'payments'")->rowCount() > 0) {
                    $sqlP = "SELECT status, COUNT(*) AS cnt FROM payments GROUP BY status";
                    $stP = $pdo->query($sqlP);
                    $pmCounts = $stP ? $stP->fetchAll(PDO::FETCH_ASSOC) : [];
                }
            } catch (Throwable $e) {}
            ?>
            <form method="get" class="mb-3 d-flex gap-2">
                <input type="hidden" name="debug" value="1" />
                <input type="text" name="q" class="form-control" placeholder="Search client name (e.g., Andrew Ezekiel)" value="<?= htmlspecialchars($q) ?>" />
                <input type="number" name="uid" class="form-control" placeholder="User ID (optional)" value="<?= (int)$uidLookup ?>" />
                <button class="btn btn-outline-dark" type="submit">Lookup</button>
            </form>
            <div class="row">
                <div class="col-md-6">
                    <div class="small text-muted mb-1">Transactions by status</div>
                    <ul class="list-group list-group-flush">
                        <?php foreach ($txCounts as $c): ?>
                        <li class="list-group-item d-flex justify-content-between"><span><?= htmlspecialchars($c['status'] ?? '-') ?></span><strong><?= (int)($c['cnt'] ?? 0) ?></strong></li>
                        <?php endforeach; ?>
                        <?php if (empty($txCounts)): ?><li class="list-group-item text-muted">No data</li><?php endif; ?>
                    </ul>
                </div>
                <div class="col-md-6">
                    <div class="small text-muted mb-1">Payments by status</div>
                    <ul class="list-group list-group-flush">
                        <?php foreach ($pmCounts as $c): ?>
                        <li class="list-group-item d-flex justify-content-between"><span><?= htmlspecialchars($c['status'] ?? '-') ?></span><strong><?= (int)($c['cnt'] ?? 0) ?></strong></li>
                        <?php endforeach; ?>
                        <?php if (empty($pmCounts)): ?><li class="list-group-item text-muted">No data</li><?php endif; ?>
                    </ul>
                </div>
            </div>
            <hr class="my-3" />
            <div class="small text-muted mb-1">Pending preview (latest 50)</div>
            <div class="table-responsive mb-3">
                <table class="table table-sm">
                    <thead>
                        <tr>
                            <th>Source</th>
                            <th>ID</th>
                            <th>User ID</th>
                            <th>Client</th>
                            <th>Amount</th>
                            <th>Status</th>
                            <th>Date</th>
                        </tr>
                    </thead>
                    <tbody>
                        <?php foreach ($pendingPreview as $pp): ?>
                        <tr>
                            <td class="text-muted"><?= htmlspecialchars($pp['source'] ?? '-') ?></td>
                            <td>#<?= (int)$pp['id'] ?></td>
                            <td><?= (int)$pp['user_id'] ?></td>
                            <td><?= htmlspecialchars($pp['client_name'] ?? '') ?></td>
                            <td>₦<?= number_format((float)($pp['amount'] ?? 0)) ?></td>
                            <td><?= htmlspecialchars($pp['status'] ?? '') ?></td>
                            <td><?= htmlspecialchars($pp['created_at'] ?? '') ?></td>
                        </tr>
                        <?php endforeach; ?>
                        <?php if (empty($pendingPreview)): ?>
                        <tr><td colspan="7" class="text-muted text-center">No pending entries found.</td></tr>
                        <?php endif; ?>
                    </tbody>
                </table>
            </div>
            <div class="small text-muted mb-1">User lookup</div>
            <div class="table-responsive">
                <table class="table table-sm">
                    <thead>
                        <tr>
                            <th>User ID</th>
                            <th>Name</th>
                            <th>Email</th>
                            <th>Role</th>
                        </tr>
                    </thead>
                    <tbody>
                        <?php foreach ($lookupMatches as $m): ?>
                        <tr>
                            <td><?= (int)($m['id'] ?? 0) ?></td>
                            <td><?= htmlspecialchars($m['display_name'] ?? '') ?></td>
                            <td><?= htmlspecialchars($m['email'] ?? '') ?></td>
                            <td><span class="badge bg-light text-dark"><?= htmlspecialchars($m['role'] ?? '') ?></span></td>
                        </tr>
                        <?php endforeach; ?>
                        <?php if (empty($lookupMatches)): ?>
                        <tr><td colspan="4" class="text-muted text-center">No matches</td></tr>
                        <?php endif; ?>
                    </tbody>
                </table>
            </div>
        </div>
    </div>
    <?php endif; ?>
    <?php if (!empty($action_msg)): ?><div class="alert alert-info"><?= htmlspecialchars($action_msg) ?></div><?php endif; ?>
    <div class="row g-3">
        <div class="col-md-3"><div class="card p-3"><div class="text-muted small">Pending Payments</div><div class="fw-bold fs-5"><?= (int)$metrics['pending'] ?></div></div></div>
        <div class="col-md-3"><div class="card p-3"><div class="text-muted small">Approved Today</div><div class="fw-bold fs-5"><?= (int)$metrics['approved_today'] ?></div></div></div>
        <div class="col-md-3"><div class="card p-3"><div class="text-muted small">Rejected Payments</div><div class="fw-bold fs-5"><?= (int)$metrics['rejected'] ?></div></div></div>
        <div class="col-md-3"><div class="card p-3"><div class="text-muted small">Total Payment Volume</div><div class="fw-bold fs-5">₦<?= number_format((float)$metrics['volume']) ?></div></div></div>
    </div>
    <div class="card mt-4">
        <div class="card-header">
            <div class="fw-semibold fs-5">Verification Queue</div>
            <div class="text-muted small">Review and approve incoming payment submissions.</div>
        </div>

        <?php
            $countPending = 0;
            $countApproved = 0;
            $countRejected = 0;
            foreach (($transactions ?? []) as $__r) {
                $stx = strtolower((string)($__r['status'] ?? ''));
                $isPendingX = in_array($stx, $queueStatuses, true);
                if ($isPendingX) { $countPending++; }
                if ($stx === 'approved') { $countApproved++; }
                if ($stx === 'rejected') { $countRejected++; }
            }
        ?>
        <div class="p-3 border-bottom bg-white">
            <style>
                .fin-filter-card { width: 100%; background: #ffffff; border: 1px solid #e9ecef; border-radius: 16px; padding: 10px 12px; box-shadow: 0 10px 22px rgba(0,0,0,.04); }
                .fin-filter-tabs .nav-link { border-radius: 999px; padding: .4rem .75rem; }
                .fin-filter-tabs .nav-link .badge { margin-left: .4rem; }
                .fin-bulk-bar { border: 1px solid #e9ecef; background: #ffffff; border-radius: 999px; padding: 6px 10px; }
                .verification-table-wrap { display: block; width: 100%; max-width: 100%; min-width: 0; overflow-x: auto; overflow-y: visible; -webkit-overflow-scrolling: touch; }
                .verification-table-wrap .table-responsive { display: block; width: 100%; max-width: 100%; min-width: 0; overflow: visible; }
                .fin-verify-table { min-width: 1180px; }
                .fin-verify-table thead th { position: sticky; top: 0; z-index: 3; background: #ffffff; }
                .fin-verify-table thead th { box-shadow: inset 0 -1px 0 rgba(0,0,0,.08); }
                .fin-verify-table th, .fin-verify-table td { padding: .85rem .75rem; }
                .fin-verify-table tbody tr.verif-row { transition: transform .12s ease, box-shadow .12s ease; }
                .fin-verify-table tbody tr.verif-row:hover { transform: translateY(-1px); box-shadow: 0 10px 22px rgba(0,0,0,.06); }
                .fin-verify-table tbody tr.verif-row:hover td { box-shadow: inset 0 0 0 1px rgba(13,110,253,.12); }
                .fin-status-badge { font-weight: 700; letter-spacing: .2px; }
                .badge-status-pending { background: #fd7e14; color: #1f2d3d; }
                .badge-status-approved { background: #198754; color: #ffffff; }
                .badge-status-rejected { background: #dc3545; color: #ffffff; }
                .fin-verify-table th:nth-child(9), .fin-verify-table td:nth-child(9) { width: 140px; }
                .fin-verify-table th:nth-child(10), .fin-verify-table td:nth-child(10) { width: 120px; }
                .fin-verify-table td:nth-child(9), .fin-verify-table td:nth-child(10) { white-space: nowrap; }
                #verificationTable th:last-child, #verificationTable td:last-child { min-width: 220px; white-space: nowrap; }
                .fin-action-buttons { display: flex; align-items: center; justify-content: flex-end; gap: .5rem; flex-wrap: nowrap; white-space: nowrap; }
                .fin-action-buttons .btn { min-width: 92px; padding: .25rem .5rem; }
                .fin-verify-table .reject-btn { font-weight: 800; }
                @media (max-width: 1199.98px) {
                    .verification-table-wrap { overflow-x: visible; }
                    .verification-table-wrap table { min-width: 0 !important; width: 100%; }
                    .fin-verify-table thead { display: none; }
                    .fin-verify-table, .fin-verify-table tbody, .fin-verify-table tr, .fin-verify-table td { display: block; width: 100%; }
                    .fin-verify-table tbody tr.verif-row { background: #ffffff; border: 1px solid #e9ecef; border-radius: 16px; overflow: hidden; margin-bottom: 12px; box-shadow: 0 10px 22px rgba(0,0,0,.04); }
                    .fin-verify-table tbody tr.verif-row:hover { transform: none; box-shadow: 0 10px 22px rgba(0,0,0,.04); }
                    .fin-verify-table tbody tr.verif-row:hover td { box-shadow: none; }
                    .fin-verify-table tbody tr.verif-row td { padding: .6rem .85rem; border-top: 1px solid #eef0f2; display: flex; align-items: center; justify-content: space-between; gap: .75rem; }
                    .fin-verify-table tbody tr.verif-row td:first-child { border-top: 0; }
                    .fin-verify-table tbody tr.verif-row td::before { content: attr(data-label); font-weight: 800; color: #64748b; flex: 0 0 42%; }
                    .fin-verify-table tbody tr.verif-row td[data-label="Select"] { justify-content: flex-end; }
                    .fin-verify-table tbody tr.verif-row td[data-label="Select"]::before { display: none; }
                    .fin-action-buttons { width: 100%; justify-content: flex-end; flex-wrap: wrap; }
                    .fin-action-buttons .btn { width: auto; }
                    .fin-verify-table tr.verif-collapse-row { margin: -8px 0 12px; }
                    .fin-verify-table tr.verif-collapse-row td { padding: 0; border: 0; display: block; }
                    .fin-verify-table tr.verif-collapse-row td::before { display: none; }
                }
            </style>
            <div class="fin-filter-card mb-3">
                <div class="small fw-semibold mb-2">Filter Verification Queue</div>
                <form method="get" class="d-flex align-items-center gap-2 flex-wrap">
                    <select name="project_id" class="form-select form-select-sm" style="min-width: 220px;">
                        <option value="0">All Projects</option>
                        <?php foreach ($projectOptions as $pj): ?>
                            <?php $pid = (int)($pj['id'] ?? 0); if ($pid <= 0) continue; ?>
                            <?php $label = (string)($pj['name'] ?? ''); $t = trim((string)($pj['type'] ?? '')); if ($t !== '') { $label .= " (" . $t . ")"; } ?>
                            <option value="<?= $pid ?>" <?= $filterProjectId === $pid ? 'selected' : '' ?>><?= htmlspecialchars($label) ?></option>
                        <?php endforeach; ?>
                    </select>
                    <input list="properties-list" name="property" class="form-control form-control-sm" placeholder="Property" value="<?= htmlspecialchars($filterProperty) ?>" style="min-width: 200px;" />
                    <datalist id="properties-list">
                        <?php foreach ($propertyOptions as $po): ?>
                            <option value="<?= htmlspecialchars($po['title'] ?? '') ?>"></option>
                        <?php endforeach; ?>
                    </datalist>
                    <select name="paid_for" class="form-select form-select-sm">
                        <option value="all" <?= $filterPaidFor==='all'?'selected':'' ?>>All Types</option>
                        <option value="form_fee" <?= $filterPaidFor==='form_fee'?'selected':'' ?>>Form Fee</option>
                        <option value="property" <?= $filterPaidFor==='property'?'selected':'' ?>>Property Payment</option>
                    </select>
                    <select name="uploaded_by" class="form-select form-select-sm">
                        <option value="all" <?= $filterUploadedBy==='all'?'selected':'' ?>>Any Uploader</option>
                        <option value="marketing" <?= $filterUploadedBy==='marketing'?'selected':'' ?>>Marketing/Sales</option>
                        <option value="contact" <?= $filterUploadedBy==='contact'?'selected':'' ?>>Contact Centre</option>
                        <option value="client" <?= $filterUploadedBy==='client'?'selected':'' ?>>Client</option>
                    </select>
                    <button class="btn btn-sm btn-primary" type="submit">Filter</button>
                    <a class="btn btn-sm btn-outline-secondary" href="finance-payments.php">Reset</a>
                </form>
            </div>
            <div class="d-flex align-items-center justify-content-between flex-wrap gap-2">
                <div class="nav nav-pills fin-filter-tabs" id="verifyTabs">
                    <button type="button" class="nav-link active" data-filter="all">All <span class="badge bg-light text-dark border"><?= number_format((int)count($transactions ?? [])) ?></span></button>
                    <button type="button" class="nav-link" data-filter="pending">Pending <span class="badge bg-light text-dark border"><?= number_format($countPending) ?></span></button>
                    <button type="button" class="nav-link" data-filter="approved">Approved <span class="badge bg-light text-dark border"><?= number_format($countApproved) ?></span></button>
                    <button type="button" class="nav-link" data-filter="rejected">Rejected <span class="badge bg-light text-dark border"><?= number_format($countRejected) ?></span></button>
                </div>
                <div class="fin-bulk-bar d-none" id="bulkBar">
                    <div class="d-flex align-items-center gap-2">
                        <span class="text-muted small"><span id="bulkSelectedCount">0</span> selected</span>
                        <div class="btn-group btn-group-sm" role="group">
                            <button type="button" class="btn btn-success" id="bulkApproveBtn" disabled>Approve selected</button>
                            <button type="button" class="btn btn-outline-danger" id="bulkRejectBtn" disabled>Reject selected</button>
                        </div>
                    </div>
                </div>
            </div>
        </div>

        <div class="verification-table-wrap table-wrapper">
        <div class="table-responsive">
            <table class="table table-hover align-middle fin-verify-table" id="verificationTable">
                <thead>
                    <tr>
                        <th class="px-2"><input type="checkbox" class="form-check-input" id="selectAllRows" /></th>
                        <th>Payment ID</th>
                        <th>Client Name</th>
                        <th>Submitted By</th>
                        <th>Payment Type</th>
                        <th>Plan</th>
                        <th>Amount</th>
                        <th>Receipt</th>
                        <th>Upload Date</th>
                        <th>Status</th>
                        <th>View Details</th>
                        <th>Actions</th>
                    </tr>
                </thead>
                <tbody>
                    <?php foreach ($transactionsPage as $row): ?>
                    <?php
                        $meta = [];
                        $modalMetaJson = '';
                        $dealIdRef = (int)($row['deal_id'] ?? 0);
                        $payTypeDb = (string)($row['payment_type_raw'] ?? '');
                        $subNameDb = (string)($row['submitted_by_name'] ?? '');
                        $subRoleDb = (string)($row['submitted_by_role'] ?? '');
                        if (colExists('payments','meta_json') && isset($row['meta_json']) && is_string($row['meta_json']) && trim($row['meta_json']) !== '') {
                            try {
                                $m0 = json_decode((string)$row['meta_json'], true);
                                if (is_array($m0) && !empty($m0)) {
                                    $meta = $m0;
                                    $modalMetaJson = (string)$row['meta_json'];
                                }
                            } catch (Throwable $ePm0) {}
                        }
                        if ((empty($meta) || !is_array($meta)) && $dealIdRef > 0 && colExists('deals','meta_json')) {
                            try {
                                $qd = $pdo->prepare("SELECT meta_json FROM deals WHERE id = ? LIMIT 1");
                                $qd->execute([$dealIdRef]);
                                $dmj = $qd->fetchColumn();
                                if ($dmj) { $meta = json_decode($dmj, true) ?: []; }
                            } catch (Throwable $eDeal) {}
                        }
                        if (empty($meta) || !is_array($meta)) {
                            try {
                                $rcp = (string)($row['receipt_file'] ?? '');
                                if ($rcp !== '') {
                                    if (colExists('deals','receipt_file') && colExists('deals','meta_json')) {
                                        $qd = $pdo->prepare("SELECT meta_json FROM deals WHERE receipt_file = ? LIMIT 1");
                                        $qd->execute([$rcp]);
                                        $dmj = $qd->fetchColumn();
                                        if ($dmj) { $meta = json_decode($dmj, true) ?: []; }
                                        if (empty($meta)) {
                                            $base = basename($rcp);
                                            if ($base !== '') {
                                                $qd = $pdo->prepare("SELECT meta_json FROM deals WHERE receipt_file LIKE ? LIMIT 1");
                                                $qd->execute(['%'.$base]);
                                                $dmj = $qd->fetchColumn();
                                                if ($dmj) { $meta = json_decode($dmj, true) ?: []; }
                                            }
                                        }
                                    } elseif (colExists('deals','proof_file') && colExists('deals','meta_json')) {
                                        $qd = $pdo->prepare("SELECT meta_json FROM deals WHERE proof_file = ? LIMIT 1");
                                        $qd->execute([$rcp]);
                                        $dmj = $qd->fetchColumn();
                                        if ($dmj) { $meta = json_decode($dmj, true) ?: []; }
                                        if (empty($meta)) {
                                            $base = basename($rcp);
                                            if ($base !== '') {
                                                $qd = $pdo->prepare("SELECT meta_json FROM deals WHERE proof_file LIKE ? LIMIT 1");
                                                $qd->execute(['%'.$base]);
                                                $dmj = $qd->fetchColumn();
                                                if ($dmj) { $meta = json_decode($dmj, true) ?: []; }
                                            }
                                        }
                                    }
                                }
                            } catch (Throwable $eRcp) {}
                        }
                        if (empty($meta) || !is_array($meta)) {
                            try {
                                $uid = (int)($row['user_id'] ?? 0);
                                if ($uid > 0 && colExists('deals','user_id') && colExists('deals','meta_json')) {
                                    $qd = $pdo->prepare("SELECT meta_json FROM deals WHERE user_id = ? ORDER BY id DESC LIMIT 1");
                                    $qd->execute([$uid]);
                                    $dmj = $qd->fetchColumn();
                                    if ($dmj) { $meta = json_decode($dmj, true) ?: []; }
                                    if (empty($meta)) {
                                        $dt = (string)($row['created_at'] ?? '');
                                        if ($dt !== '' && colExists('deals','created_at')) {
                                            $qdt = $pdo->prepare("SELECT meta_json FROM deals WHERE user_id = ? AND created_at BETWEEN DATE_SUB(?, INTERVAL 1 DAY) AND DATE_ADD(?, INTERVAL 1 DAY) ORDER BY created_at DESC LIMIT 1");
                                            $qdt->execute([$uid, $dt, $dt]);
                                            $dmj = $qdt->fetchColumn();
                                            if ($dmj) { $meta = json_decode($dmj, true) ?: []; }
                                        }
                                    }
                                }
                            } catch (Throwable $eUid) {}
                        }
                        if (empty($meta) || !is_array($meta)) {
                            try {
                                $ref = (string)($row['reference'] ?? '');
                                if ($ref !== '' && colExists('deals','created_at') && colExists('deals','meta_json')) {
                                    $ts = null;
                                    if (preg_match('/(\d{14})/', $ref, $m)) { $ts = DateTime::createFromFormat('YmdHis', $m[1]); }
                                    if ($ts) {
                                        $windowStart = $ts->format('Y-m-d H:i:s');
                                        $windowEnd = $ts->format('Y-m-d H:i:s');
                                        $uid = (int)($row['user_id'] ?? 0);
                                        if ($uid > 0 && colExists('deals','user_id')) {
                                            $qrf = $pdo->prepare("SELECT meta_json FROM deals WHERE user_id = ? AND created_at BETWEEN DATE_SUB(?, INTERVAL 1 DAY) AND DATE_ADD(?, INTERVAL 1 DAY) ORDER BY created_at DESC LIMIT 1");
                                            $qrf->execute([$uid, $windowStart, $windowEnd]);
                                        } else {
                                            $qrf = $pdo->prepare("SELECT meta_json FROM deals WHERE created_at BETWEEN DATE_SUB(?, INTERVAL 1 DAY) AND DATE_ADD(?, INTERVAL 1 DAY) ORDER BY created_at DESC LIMIT 1");
                                            $qrf->execute([$windowStart, $windowEnd]);
                                        }
                                        $dmj = $qrf->fetchColumn();
                                        if ($dmj) { $meta = json_decode($dmj, true) ?: []; }
                                    }
                                }
                            } catch (Throwable $eRef) {}
                        }
                        /* removed non-onboarding extras */
                        $collapseId = 'meta'.(int)$row['id'];
                        $proj = $meta['project_desc'] ?? '-';
                        $planType = isset($meta['plan_type']) ? (string)$meta['plan_type'] : '';
                        $dealSource = isset($meta['deal_source']) ? (string)$meta['deal_source'] : '';
                        $clientNameMeta = isset($meta['client_name']) ? (string)$meta['client_name'] : '';
                        $marketerName = isset($meta['marketer_name']) ? (string)$meta['marketer_name'] : '';
                        if (is_string($proj) && trim($proj) === '-') { $proj = ''; }
                        if (is_string($planType) && trim($planType) === '-') { $planType = ''; }
                        if (is_string($dealSource) && trim($dealSource) === '-') { $dealSource = ''; }
                        if (is_string($marketerName) && trim($marketerName) === '-') { $marketerName = ''; }
                        $amountOffered = isset($meta['amount_offered']) ? (float)$meta['amount_offered'] : 0;
                        $amountPaidSoFar = isset($meta['amount_paid_so_far']) ? (float)$meta['amount_paid_so_far'] : 0;
                        $discountAmount = isset($meta['discount_amount']) ? (float)$meta['discount_amount'] : 0;
                        $discountBy = isset($meta['discount_approved_by']) ? (string)$meta['discount_approved_by'] : '';
                        if (is_string($discountBy) && trim($discountBy) === '-') { $discountBy = ''; }
                        $commissionPct = isset($meta['commission_pct']) ? (float)$meta['commission_pct'] : 0;
                        $marketerComm = isset($meta['marketer_comm']) ? (float)$meta['marketer_comm'] : 0;
                        $agentComm = isset($meta['agent_comm']) ? (float)$meta['agent_comm'] : 0;
                        $balanceRem = isset($meta['balance_remaining']) ? (float)$meta['balance_remaining'] : 0;
                        $statusNotes = isset($meta['client_payment_status']) ? (string)$meta['client_payment_status'] : '';
                        $paidNow = (float)($row['amount'] ?? 0);
                        if ($amountPaidSoFar <= 0 && $paidNow > 0) { $amountPaidSoFar = $paidNow; }
                        if ($balanceRem <= 0 && $amountOffered > 0) { $balanceRem = max(0.0, $amountOffered - $amountPaidSoFar); }
                        if ($commissionPct <= 0 && $marketerComm > 0) {
                            $baseAmt = $paidNow > 0 ? $paidNow : ($amountPaidSoFar > 0 ? $amountPaidSoFar : 0);
                            if ($baseAmt > 0) { $commissionPct = round(($marketerComm / $baseAmt) * 100, 2); }
                        }
                        if ((!is_string($dealSource) || trim($dealSource) === '' || $dealSource === '-') && isset($subRoleFull) && $subRoleFull !== '') { $dealSource = ucfirst(strtolower($subRoleFull)); }
                        $mkRaw = isset($meta['marketer_bank']) && is_array($meta['marketer_bank']) ? $meta['marketer_bank'] : [];
                        $agRaw = isset($meta['agent_bank']) && is_array($meta['agent_bank']) ? $meta['agent_bank'] : [];
                        $mkAccNo = (string)($mkRaw['acc_no'] ?? ($mkRaw['account_number'] ?? ($mkRaw['accountNumber'] ?? ($mkRaw['accNo'] ?? ($meta['marketer_account_number'] ?? ($meta['marketer_acc_no'] ?? ($meta['marketer_acc_number'] ?? '')))))));
                        $mkBankName = (string)($mkRaw['bank'] ?? ($mkRaw['bank_name'] ?? ($mkRaw['bankName'] ?? ($meta['marketer_bank_name'] ?? ($meta['marketer_bank'] ?? '')))));
                        $mkAccName = (string)($mkRaw['acc_name'] ?? ($mkRaw['account_name'] ?? ($mkRaw['accountName'] ?? ($meta['marketer_account_name'] ?? ($meta['marketer_acc_name'] ?? '')))));
                        $agAccNo = (string)($agRaw['acc_no'] ?? ($agRaw['account_number'] ?? ($agRaw['accountNumber'] ?? ($agRaw['accNo'] ?? ($meta['agent_account_number'] ?? ($meta['agent_acc_no'] ?? ($meta['agent_acc_number'] ?? '')))))));
                        $agBankName = (string)($agRaw['bank'] ?? ($agRaw['bank_name'] ?? ($agRaw['bankName'] ?? ($meta['agent_bank_name'] ?? ($meta['agent_bank'] ?? '')))));
                        $agAccName = (string)($agRaw['acc_name'] ?? ($agRaw['account_name'] ?? ($agRaw['accountName'] ?? ($meta['agent_account_name'] ?? ($meta['agent_acc_name'] ?? '')))));
                        $mkBank = ['acc_no' => trim($mkAccNo), 'bank' => trim($mkBankName), 'acc_name' => trim($mkAccName)];
                        $agBank = ['acc_no' => trim($agAccNo), 'bank' => trim($agBankName), 'acc_name' => trim($agAccName)];
                        $transactionsMeta = isset($meta['transactions']) && is_array($meta['transactions']) ? $meta['transactions'] : [];
                        $quickProperty = isset($meta['property']) ? (string)$meta['property'] : '';
                        if ($quickProperty === '' && isset($meta['property_estate'])) { $quickProperty = (string)$meta['property_estate']; }
                        $quickNotes = isset($meta['notes']) ? (string)$meta['notes'] : '';
                        $submittedBy = '';
                        $subName = trim($subNameDb !== '' ? $subNameDb : (string)($meta['submitted_by_name'] ?? ''));
                        if ($subName === '') { $subName = trim((string)($meta['marketer_name'] ?? '')); }
                        $subRole = trim($subRoleDb !== '' ? $subRoleDb : (string)($meta['submitted_by_role'] ?? ''));
                        if ($subRole === '') { $subRole = trim((string)($meta['deal_source'] ?? '')); }
                        if ($subName !== '') { $submittedBy = $subName . ($subRole !== '' ? ' / ' . strtoupper($subRole) : ''); }
                        elseif (!empty($meta['submitted_by_user'])) {
                            $subUidInit = (int)$meta['submitted_by_user'];
                            $subRoleInit = (string)($meta['submitted_by_role'] ?? '');
                            $subNameInit = '';
                            try {
                                if ($subUidInit > 0 && colExists('users','name')) {
                                    $qs = $pdo->prepare("SELECT name FROM users WHERE id = ? LIMIT 1");
                                    $qs->execute([$subUidInit]); $subNameInit = (string)($qs->fetchColumn() ?: '');
                                }
                            } catch (Throwable $eN0) {}
                            $submittedBy = '#'.$subUidInit . ($subNameInit !== '' ? ' '.$subNameInit : '') . ($subRoleInit !== '' ? ' / '.strtoupper($subRoleInit) : '');
                        }
                        $displayPaymentType = '';
                        $pt = strtolower(trim($payTypeDb !== '' ? $payTypeDb : (string)($meta['payment_type'] ?? '')));
                        if ($pt === '' && isset($meta['Payment Type'])) { $pt = strtolower(trim((string)$meta['Payment Type'])); }
                        if (is_string($row['payment_type'] ?? null) && strtolower(trim((string)$row['payment_type'])) === 'form fee') {
                            $displayPaymentType = 'Form Fee';
                        } elseif ($pt === 'infrastructure' || $pt === 'infra') {
                            $displayPaymentType = 'Infrastructure Fee';
                        } elseif ($pt === 'excavation' || $pt === 'excav') {
                            $displayPaymentType = 'Excavation Fee';
                        } elseif ($pt === 'land') {
                            $displayPaymentType = 'Land Payment';
                        } elseif ($pt !== '') {
                            $displayPaymentType = ucfirst($pt);
                        } else {
                            $displayPaymentType = 'Property Payment';
                        }
                        if ($dealIdRef > 0) {
                            try {
                                $sel = [];
                                if (colExists('deals','property_estate')) { $sel[] = 'property_estate'; }
                                if (colExists('deals','project_desc')) { $sel[] = 'project_desc'; }
                                if (colExists('deals','amount_offered')) { $sel[] = 'amount_offered'; }
                                if (colExists('deals','amount_paid_now')) { $sel[] = 'amount_paid_now'; }
                                if (colExists('deals','discount_amount')) { $sel[] = 'discount_amount'; }
                                if (colExists('deals','discount_approved_by')) { $sel[] = 'discount_approved_by'; }
                                if (colExists('deals','balance_remaining')) { $sel[] = 'balance_remaining'; }
                                if (colExists('deals','plan_type')) { $sel[] = 'plan_type'; }
                                if (colExists('deals','deal_source')) { $sel[] = 'deal_source'; }
                                if (colExists('deals','marketer_name')) { $sel[] = 'marketer_name'; }
                                if (colExists('deals','submitted_by_user')) { $sel[] = 'submitted_by_user'; }
                                if (colExists('deals','created_by')) { $sel[] = 'created_by'; }
                                if (colExists('deals','created_by_user')) { $sel[] = 'created_by_user'; }
                                if (colExists('deals','marketer_id')) { $sel[] = 'marketer_id'; }
                                if (colExists('deals','agent_id')) { $sel[] = 'agent_id'; }
                                if (colExists('deals','contact_rep_id')) { $sel[] = 'contact_rep_id'; }
                                if (!empty($sel)) {
                                    $qd2 = $pdo->prepare("SELECT ".implode(',', $sel)." FROM deals WHERE id = ? LIMIT 1");
                                    $qd2->execute([$dealIdRef]);
                                    $dr = $qd2->fetch(PDO::FETCH_ASSOC) ?: [];
                                    $pEst = (string)($dr['property_estate'] ?? ($dr['property'] ?? ($dr['estate'] ?? '')));
                                    $pDesc = (string)($dr['project_desc'] ?? ($dr['project'] ?? ($dr['property_title'] ?? ($dr['property_name'] ?? ''))));
                                    $pName = isset($dr['project_name']) ? (string)$dr['project_name'] : '';
                                    $proj = ((is_string($proj) && trim($proj) !== '' && $proj !== '-') ? $proj : ($pName ?: ($pDesc ?: ($pEst ?: $proj))));
                                    if (isset($dr['amount_offered'])) { $amountOffered = (float)$dr['amount_offered']; }
                                    if (isset($dr['amount_paid_now']) && $amountPaidSoFar <= 0) { $amountPaidSoFar = (float)$dr['amount_paid_now']; }
                                    if (isset($dr['discount_amount'])) { $discountAmount = (float)$dr['discount_amount']; }
                                    if (isset($dr['discount_approved_by'])) { $discountBy = (string)$dr['discount_approved_by']; }
                                    if (isset($dr['balance_remaining'])) { $balanceRem = (float)$dr['balance_remaining']; }
                                    if (isset($dr['plan_type']) && !$planType) { $planType = (string)$dr['plan_type']; }
                                    if (isset($dr['deal_source']) && !$dealSource) { $dealSource = (string)$dr['deal_source']; }
                                    if (isset($dr['marketer_name']) && (!is_string($marketerName) || trim($marketerName)==='')) { $marketerName = (string)$dr['marketer_name']; }
                                    if ((!is_string($marketerName) || trim($marketerName)==='')) {
                                        $sid = 0;
                                        if (isset($dr['submitted_by_user']) && (int)$dr['submitted_by_user'] > 0) { $sid = (int)$dr['submitted_by_user']; }
                                        elseif (isset($dr['created_by_user']) && (int)$dr['created_by_user'] > 0) { $sid = (int)$dr['created_by_user']; }
                                        elseif (isset($dr['created_by']) && (int)$dr['created_by'] > 0) { $sid = (int)$dr['created_by']; }
                                        elseif (isset($dr['marketer_id']) && (int)$dr['marketer_id'] > 0) { $sid = (int)$dr['marketer_id']; }
                                        elseif (isset($dr['agent_id']) && (int)$dr['agent_id'] > 0) { $sid = (int)$dr['agent_id']; }
                                        elseif (isset($dr['contact_rep_id']) && (int)$dr['contact_rep_id'] > 0) { $sid = (int)$dr['contact_rep_id']; }
                                        if ($sid > 0) {
                                            try { 
                                                $n = '';
                                                if (colExists('users','name')) { $qs = $pdo->prepare("SELECT name FROM users WHERE id = ? LIMIT 1"); $qs->execute([$sid]); $n = (string)($qs->fetchColumn() ?: ''); }
                                                if ($n === '' && colExists('users','full_name')) { $qs = $pdo->prepare("SELECT full_name FROM users WHERE id = ? LIMIT 1"); $qs->execute([$sid]); $n = (string)($qs->fetchColumn() ?: ''); }
                                                if ($n === '' && colExists('users','first_name') && colExists('users','last_name')) { $qs = $pdo->prepare("SELECT CONCAT(first_name,' ',last_name) FROM users WHERE id = ? LIMIT 1"); $qs->execute([$sid]); $n = (string)($qs->fetchColumn() ?: ''); }
                                                if ($n !== '') { $marketerName = $n; }
                                            } catch (Throwable $eS) {}
                                        }
                                    }
                                    $quickProperty = $quickProperty ?: ($pEst ?: $pDesc);
                                }
                            } catch (Throwable $eX) {}
                        } else {
                            try {
                                $dealGuess = 0;
                                $rcpG = (string)($row['receipt_file'] ?? '');
                                $uidG = (int)($row['user_id'] ?? 0);
                                $dtG = (string)($row['created_at'] ?? '');
                                if ($dealGuess <= 0 && $rcpG !== '') {
                                    if (colExists('deals','receipt_file')) {
                                        $qg = $pdo->prepare("SELECT id FROM deals WHERE receipt_file = ? LIMIT 1"); $qg->execute([$rcpG]);
                                        $dealGuess = (int)($qg->fetchColumn() ?: 0);
                                        if ($dealGuess <= 0) {
                                            $base = basename($rcpG);
                                            if ($base !== '') { $qg = $pdo->prepare("SELECT id FROM deals WHERE receipt_file LIKE ? LIMIT 1"); $qg->execute(['%'.$base]); $dealGuess = (int)($qg->fetchColumn() ?: 0); }
                                        }
                                    } elseif (colExists('deals','proof_file')) {
                                        $qg = $pdo->prepare("SELECT id FROM deals WHERE proof_file = ? LIMIT 1"); $qg->execute([$rcpG]);
                                        $dealGuess = (int)($qg->fetchColumn() ?: 0);
                                        if ($dealGuess <= 0) {
                                            $base = basename($rcpG);
                                            if ($base !== '') { $qg = $pdo->prepare("SELECT id FROM deals WHERE proof_file LIKE ? LIMIT 1"); $qg->execute(['%'.$base]); $dealGuess = (int)($qg->fetchColumn() ?: 0); }
                                        }
                                    }
                                }
                                if ($dealGuess <= 0 && $uidG > 0 && $dtG !== '' && colExists('deals','user_id') && colExists('deals','created_at')) {
                                    $qg = $pdo->prepare("SELECT id FROM deals WHERE user_id = ? AND created_at BETWEEN DATE_SUB(?, INTERVAL 1 DAY) AND DATE_ADD(?, INTERVAL 1 DAY) ORDER BY created_at DESC LIMIT 1");
                                    $qg->execute([$uidG, $dtG, $dtG]); $dealGuess = (int)($qg->fetchColumn() ?: 0);
                                    if ($dealGuess <= 0) {
                                        $qg = $pdo->prepare("SELECT id FROM deals WHERE user_id = ? ORDER BY id DESC LIMIT 1"); $qg->execute([$uidG]); $dealGuess = (int)($qg->fetchColumn() ?: 0);
                                    }
                                }
                                if ($dealGuess <= 0 && !empty($row['reference']) && colExists('deals','created_at')) {
                                    $ts = null; if (preg_match('/(\\d{14})/', (string)$row['reference'], $m)) { $ts = DateTime::createFromFormat('YmdHis', $m[1]); }
                                    if ($ts) {
                                        $w = $ts->format('Y-m-d H:i:s');
                                        if ($uidG > 0 && colExists('deals','user_id')) {
                                            $qg = $pdo->prepare("SELECT id FROM deals WHERE user_id = ? AND created_at BETWEEN DATE_SUB(?, INTERVAL 1 DAY) AND DATE_ADD(?, INTERVAL 1 DAY) ORDER BY created_at DESC LIMIT 1");
                                            $qg->execute([$uidG, $w, $w]); $dealGuess = (int)($qg->fetchColumn() ?: 0);
                                        } else {
                                            $qg = $pdo->prepare("SELECT id FROM deals WHERE created_at BETWEEN DATE_SUB(?, INTERVAL 1 DAY) AND DATE_ADD(?, INTERVAL 1 DAY) ORDER BY created_at DESC LIMIT 1");
                                            $qg->execute([$w, $w]); $dealGuess = (int)($qg->fetchColumn() ?: 0);
                                        }
                                    }
                                }
                                if ($dealGuess > 0 && colExists('payments','deal_id')) {
                                    try {
                                        $up = $pdo->prepare("UPDATE payments SET deal_id = ? WHERE id = ?");
                                        $up->execute([$dealGuess, (int)$row['id']]);
                                        try { @file_put_contents(__DIR__ . '/debug_sql.txt', "PAYMENT_LINK:\nUPDATE payments SET deal_id = {$dealGuess} WHERE id = ".(int)$row['id']."\n", FILE_APPEND); } catch (Throwable $ePL0) {}
                                    } catch (Throwable $eUpd) {}
                                }
                                if ($dealGuess > 0) {
                                    $sel = [];
                                    if (colExists('deals','property_estate')) { $sel[] = 'property_estate'; }
                                    if (colExists('deals','project_desc')) { $sel[] = 'project_desc'; }
                                    if (colExists('deals','amount_offered')) { $sel[] = 'amount_offered'; }
                                    if (colExists('deals','amount_paid_now')) { $sel[] = 'amount_paid_now'; }
                                    if (colExists('deals','discount_amount')) { $sel[] = 'discount_amount'; }
                                    if (colExists('deals','discount_approved_by')) { $sel[] = 'discount_approved_by'; }
                                    if (colExists('deals','balance_remaining')) { $sel[] = 'balance_remaining'; }
                                    if (colExists('deals','plan_type')) { $sel[] = 'plan_type'; }
                                    if (colExists('deals','deal_source')) { $sel[] = 'deal_source'; }
                                if (colExists('deals','marketer_name')) { $sel[] = 'marketer_name'; }
                                if (!empty($sel)) {
                                        $qd2 = $pdo->prepare("SELECT ".implode(',', $sel)." FROM deals WHERE id = ? LIMIT 1");
                                        $qd2->execute([$dealGuess]);
                                        $dr = $qd2->fetch(PDO::FETCH_ASSOC) ?: [];
                                        $pEst = (string)($dr['property_estate'] ?? ($dr['property'] ?? ($dr['estate'] ?? '')));
                                        $pDesc = (string)($dr['project_desc'] ?? ($dr['project'] ?? ($dr['property_title'] ?? ($dr['property_name'] ?? ''))));
                                        $pName = isset($dr['project_name']) ? (string)$dr['project_name'] : '';
                                        $proj = ((is_string($proj) && trim($proj) !== '' && $proj !== '-') ? $proj : ($pName ?: ($pDesc ?: ($pEst ?: $proj))));
                                        if (isset($dr['amount_offered'])) { $amountOffered = (float)$dr['amount_offered']; }
                                        if (isset($dr['amount_paid_now']) && $amountPaidSoFar <= 0) { $amountPaidSoFar = (float)$dr['amount_paid_now']; }
                                        if (isset($dr['discount_amount'])) { $discountAmount = (float)$dr['discount_amount']; }
                                        if (isset($dr['discount_approved_by'])) { $discountBy = (string)$dr['discount_approved_by']; }
                                        if (isset($dr['balance_remaining'])) { $balanceRem = (float)$dr['balance_remaining']; }
                                        if (isset($dr['plan_type']) && !$planType) { $planType = (string)$dr['plan_type']; }
                                        if (isset($dr['deal_source']) && !$dealSource) { $dealSource = (string)$dr['deal_source']; }
                                        if (isset($dr['marketer_name']) && (!is_string($marketerName) || trim($marketerName)==='')) { $marketerName = (string)$dr['marketer_name']; }
                                        $quickProperty = $quickProperty ?: ($pEst ?: $pDesc);
                                        $sets = []; $vals = [];
                                        if (isset($dr['project_name']) && trim((string)$dr['project_name']) === '' && $proj !== '') { $sets[]='project_name = ?'; $vals[]=$proj; }
                                        if (isset($dr['project_desc']) && trim((string)$dr['project_desc']) === '' && $proj !== '') { $sets[]='project_desc = ?'; $vals[]=$proj; }
                                        if (isset($dr['deal_source']) && trim((string)$dr['deal_source']) === '' && $dealSource !== '') { $sets[]='deal_source = ?'; $vals[]=$dealSource; }
                                        if (isset($dr['payment_plan']) && trim((string)$dr['payment_plan']) === '' && $planType !== '') { $sets[]='payment_plan = ?'; $vals[]=$planType; }
                                        if (isset($dr['marketer_name']) && trim((string)$dr['marketer_name']) === '' && $marketerName !== '') { $sets[]='marketer_name = ?'; $vals[]=$marketerName; }
                                        if (isset($dr['amount_offered']) && (float)$dr['amount_offered'] == 0.0 && $amountOffered > 0) { $sets[]='amount_offered = ?'; $vals[]=$amountOffered; }
                                        if (isset($dr['amount_paid_now']) && (float)$dr['amount_paid_now'] == 0.0 && $amountPaidSoFar > 0) { $sets[]='amount_paid_now = ?'; $vals[]=$amountPaidSoFar; }
                                        if (isset($dr['discount_amount']) && (float)$dr['discount_amount'] == 0.0 && $discountAmount > 0) { $sets[]='discount_amount = ?'; $vals[]=$discountAmount; }
                                        if (isset($dr['balance_remaining']) && (float)$dr['balance_remaining'] == 0.0 && $balanceRem > 0) { $sets[]='balance_remaining = ?'; $vals[]=$balanceRem; }
                                        if (isset($dr['plan_type']) && trim((string)$dr['plan_type']) === '' && $planType !== '') { $sets[]='plan_type = ?'; $vals[]=$planType; }
                                        if (!empty($sets)) {
                                            $vals[] = $dealGuess;
                                            $upD = $pdo->prepare("UPDATE deals SET ".implode(',', $sets)." WHERE id = ?");
                                            $upD->execute($vals);
                                            try { @file_put_contents(__DIR__ . '/debug_sql.txt', "REPAIR_UPDATE_DEAL:\nUPDATE deals SET ".implode(',', $sets)." WHERE id = {$dealGuess}\nPARAMS:\n".print_r($vals, true)."\n", FILE_APPEND); } catch (Throwable $eRU1) {}
                                        }
                                    }
                                }
                            } catch (Throwable $eX2) {}
                        }
            try {
                            $uidCF0 = (int)($row['user_id'] ?? 0);
                            if ($uidCF0 > 0 && colExists('client_forms','form_data')) {
                                $qcf0 = $pdo->prepare("SELECT form_data FROM client_forms WHERE client_id = ? ORDER BY created_at DESC LIMIT 1");
                                $qcf0->execute([$uidCF0]);
                                $cfj0 = (string)($qcf0->fetchColumn() ?: '');
                                if ($cfj0 !== '') {
                                    $cfm0 = json_decode($cfj0, true) ?: [];
                        $cfProj = '';
                        foreach (['project_desc','Project / Property Description','Project / Property','Property / Estate','Property/Estate','Estate / Property','project_or_property','preferred_property','preferred property','estate_name','property_estate','estate_property','property','estate','project_property','project','property_title','property_name','project_title','Project Name'] as $k) {
                            $v = isset($cfm0[$k]) ? trim((string)$cfm0[$k]) : '';
                            if ($v !== '') { $cfProj = $v; break; }
                        }
                        $cfSource = '';
                        foreach (['deal_source','Deal Source','source','deal_source_type','lead_source','referral_source','referral source','submitted_by_role','Submitted By Role','department','team','channel','source_of_deal','source of deal','how did you hear about us','how you heard about us','where did you hear about us','where heard'] as $k) {
                            $v = isset($cfm0[$k]) ? trim((string)$cfm0[$k]) : '';
                            if ($v !== '') { $cfSource = $v; break; }
                        }
                        $cfPlan = '';
                        foreach (['plan_type','Payment Plan','plan','payment_plan','plan_name','installment_plan','payment_mode','payment mode'] as $k) {
                            $v = isset($cfm0[$k]) ? trim((string)$cfm0[$k]) : '';
                            if ($v !== '') { $cfPlan = $v; break; }
                        }
                        $cfMarketer = '';
                        foreach (['marketer_name','Marketer Name','Marketer or Contact Centre Name','Marketer or Contact Center Name','Contact Centre Name','Contact Center Name','Marketer’s Name','Marketer\'s Name','marketer','sales_agent','sales_rep','contact_rep','uploaded_by_name','submitted_by_name','agent_name','marketer_full_name','marketer full name'] as $k) {
                            $v = isset($cfm0[$k]) ? trim((string)$cfm0[$k]) : '';
                            if ($v !== '') { $cfMarketer = $v; break; }
                        }
                        if ($cfMarketer === '') {
                            foreach ($cfm0 as $kk=>$vv) {
                                if (!is_string($vv) || trim($vv)==='') continue;
                                $lk = strtolower(preg_replace('/[^a-z]/','', (string)$kk));
                                if (strpos($lk,'submittedby')!==false || strpos($lk,'marketername')!==false || strpos($lk,'marketer')!==false || strpos($lk,'contactcentre')!==false || strpos($lk,'contactcenter')!==false) { $cfMarketer = trim((string)$vv); break; }
                            }
                        }
                        if (!isset($meta['client_payment_status'])) {
                            if (isset($cfm0['client_payment_status']) && trim((string)$cfm0['client_payment_status']) !== '') { $meta['client_payment_status'] = trim((string)$cfm0['client_payment_status']); }
                            elseif (isset($cfm0['Client Payment Status / Notes']) && trim((string)$cfm0['Client Payment Status / Notes']) !== '') { $meta['client_payment_status'] = trim((string)$cfm0['Client Payment Status / Notes']); }
                            elseif (isset($cfm0['Client Payment Status']) && trim((string)$cfm0['Client Payment Status']) !== '') { $meta['client_payment_status'] = trim((string)$cfm0['Client Payment Status']); }
                            elseif (isset($cfm0['notes']) && trim((string)$cfm0['notes']) !== '') { $meta['client_payment_status'] = trim((string)$cfm0['notes']); }
                        }
                        if (!isset($meta['client_email'])) {
                            if (isset($cfm0['client_email']) && trim((string)$cfm0['client_email']) !== '') { $meta['client_email'] = trim((string)$cfm0['client_email']); }
                            elseif (isset($cfm0['Client Email (for dashboard)']) && trim((string)$cfm0['Client Email (for dashboard)']) !== '') { $meta['client_email'] = trim((string)$cfm0['Client Email (for dashboard)']); }
                            elseif (isset($cfm0['email']) && trim((string)$cfm0['email']) !== '') { $meta['client_email'] = trim((string)$cfm0['email']); }
                        }
                        if (!isset($meta['client_name'])) {
                            if (isset($cfm0['Client’s Name (text)']) && trim((string)$cfm0['Client’s Name (text)']) !== '') { $meta['client_name'] = trim((string)$cfm0['Client’s Name (text)']); }
                            elseif (isset($cfm0["Client's Name (text)"]) && trim((string)$cfm0["Client's Name (text)"]) !== '') { $meta['client_name'] = trim((string)$cfm0["Client's Name (text)"]); }
                            elseif (isset($cfm0['client_name_text']) && trim((string)$cfm0['client_name_text']) !== '') { $meta['client_name'] = trim((string)$cfm0['client_name_text']); }
                        }
                        if (!isset($meta['amount_offered'])) {
                            if (isset($cfm0['Amount Offered (if installment)'])) { $meta['amount_offered'] = (float)$cfm0['Amount Offered (if installment)']; }
                        }
                        if (!isset($meta['discount_approved_by'])) {
                            if (isset($cfm0['Discount Approved By']) && trim((string)$cfm0['Discount Approved By']) !== '') { $meta['discount_approved_by'] = trim((string)$cfm0['Discount Approved By']); }
                        }
                        if (!isset($meta['commission_pct'])) {
                            if (isset($cfm0['Commission %'])) { $meta['commission_pct'] = (float)$cfm0['Commission %']; }
                        }
                        if (!isset($meta['marketer_comm'])) {
                            if (isset($cfm0['Marketer Commission Amount'])) { $meta['marketer_comm'] = (float)$cfm0['Marketer Commission Amount']; }
                            elseif (isset($cfm0['Marketer Commission'])) { $meta['marketer_comm'] = (float)$cfm0['Marketer Commission']; }
                        }
                        if (!isset($meta['agent_comm'])) {
                            if (isset($cfm0['Agent Commission Amount'])) { $meta['agent_comm'] = (float)$cfm0['Agent Commission Amount']; }
                            elseif (isset($cfm0['Agent Commission'])) { $meta['agent_comm'] = (float)$cfm0['Agent Commission']; }
                        }
                                    if ($proj === '-' || $proj === '') { $proj = $cfProj !== '' ? $cfProj : $proj; }
                                    if (!$dealSource && $cfSource !== '') { $dealSource = $cfSource; }
                                    if (!$planType && $cfPlan !== '') { $planType = $cfPlan; }
                                    if (!$marketerName && $cfMarketer !== '') { $marketerName = $cfMarketer; }
                                    if (empty($mkBank) || (empty($mkBank['acc_no']) && empty($mkBank['bank']) && empty($mkBank['acc_name']))) {
                                        if (isset($cfm0['marketer_bank']) && is_array($cfm0['marketer_bank'])) {
                                            $mkBank = [
                                                'acc_no' => trim((string)($cfm0['marketer_bank']['acc_no'] ?? $cfm0['marketer_bank']['account_number'] ?? $cfm0['marketer_bank']['accNo'] ?? '')),
                                                'bank' => trim((string)($cfm0['marketer_bank']['bank'] ?? $cfm0['marketer_bank']['bank_name'] ?? $cfm0['marketer_bank']['bankName'] ?? '')),
                                                'acc_name' => trim((string)($cfm0['marketer_bank']['acc_name'] ?? $cfm0['marketer_bank']['account_name'] ?? $cfm0['marketer_bank']['accountName'] ?? ''))
                                            ];
                                        }
                                        if (empty($mkBank) || (empty($mkBank['acc_no']) && empty($mkBank['bank']) && empty($mkBank['acc_name']))) {
                                            $mkBank = [
                                                'acc_no' => trim((string)($cfm0['mk_acc_no'] ?? ($cfm0['marketer_account_number'] ?? ($cfm0['Marketer Account Number'] ?? ($cfm0['marketer_acc_no'] ?? ''))))),
                                                'bank' => trim((string)($cfm0['mk_bank'] ?? ($cfm0['marketer_bank_name'] ?? ($cfm0['Marketer Bank Name'] ?? ($cfm0['marketer_bank'] ?? ''))))),
                                                'acc_name' => trim((string)($cfm0['mk_acc_name'] ?? ($cfm0['marketer_account_name'] ?? ($cfm0['Marketer Account Name'] ?? ($cfm0['marketer_acc_name'] ?? '')))))
                                            ];
                                        }
                                    }
                                    if (empty($agBank) || (empty($agBank['acc_no']) && empty($agBank['bank']) && empty($agBank['acc_name']))) {
                                        if (isset($cfm0['agent_bank']) && is_array($cfm0['agent_bank'])) {
                                            $agBank = [
                                                'acc_no' => trim((string)($cfm0['agent_bank']['acc_no'] ?? $cfm0['agent_bank']['account_number'] ?? $cfm0['agent_bank']['accNo'] ?? '')),
                                                'bank' => trim((string)($cfm0['agent_bank']['bank'] ?? $cfm0['agent_bank']['bank_name'] ?? $cfm0['agent_bank']['bankName'] ?? '')),
                                                'acc_name' => trim((string)($cfm0['agent_bank']['acc_name'] ?? $cfm0['agent_bank']['account_name'] ?? $cfm0['agent_bank']['accountName'] ?? ''))
                                            ];
                                        }
                                        if (empty($agBank) || (empty($agBank['acc_no']) && empty($agBank['bank']) && empty($agBank['acc_name']))) {
                                            $agBank = [
                                                'acc_no' => trim((string)($cfm0['ag_acc_no'] ?? ($cfm0['agent_account_number'] ?? ($cfm0['Agent Account Number'] ?? ($cfm0['agent_acc_no'] ?? ''))))),
                                                'bank' => trim((string)($cfm0['ag_bank'] ?? ($cfm0['agent_bank_name'] ?? ($cfm0['Agent Bank Name'] ?? ($cfm0['agent_bank'] ?? ''))))),
                                                'acc_name' => trim((string)($cfm0['ag_acc_name'] ?? ($cfm0['agent_account_name'] ?? ($cfm0['Agent Account Name'] ?? ($cfm0['agent_acc_name'] ?? '')))))
                                            ];
                                        }
                                    }
                                    if ($amountOffered <= 0) {
                                        if (isset($cfm0['amount_offered'])) { $amountOffered = (float)$cfm0['amount_offered']; }
                                        elseif (isset($cfm0['offered_amount'])) { $amountOffered = (float)$cfm0['offered_amount']; }
                                        elseif (isset($cfm0['offered amount'])) { $amountOffered = (float)$cfm0['offered amount']; }
                                    }
                                    if ($discountAmount <= 0 && isset($cfm0['discount_amount'])) { $discountAmount = (float)$cfm0['discount_amount']; }
                                    if ($discountBy === '' && isset($cfm0['discount_approved_by'])) { $discountBy = (string)$cfm0['discount_approved_by']; }
                                    if ($balanceRem <= 0 && isset($cfm0['balance_remaining'])) { $balanceRem = (float)$cfm0['balance_remaining']; }
                                    if ($amountPaidSoFar <= 0 && isset($cfm0['amount_paid_so_far'])) { $amountPaidSoFar = (float)$cfm0['amount_paid_so_far']; }
                                    if ($commissionPct <= 0) {
                                        if (isset($cfm0['commission_pct'])) { $commissionPct = (float)$cfm0['commission_pct']; }
                                        elseif (isset($cfm0['commission_percent'])) { $commissionPct = (float)$cfm0['commission_percent']; }
                                        elseif (isset($cfm0['commission %'])) { $commissionPct = (float)$cfm0['commission %']; }
                                    }
                                    if ($marketerComm <= 0) {
                                        if (isset($cfm0['marketer_comm'])) { $marketerComm = (float)$cfm0['marketer_comm']; }
                                        elseif (isset($cfm0['marketer_commission'])) { $marketerComm = (float)$cfm0['marketer_commission']; }
                                        elseif (isset($cfm0['marketer commission'])) { $marketerComm = (float)$cfm0['marketer commission']; }
                                    }
                                    if ($agentComm <= 0) {
                                        if (isset($cfm0['agent_comm'])) { $agentComm = (float)$cfm0['agent_comm']; }
                                        elseif (isset($cfm0['agent_commission'])) { $agentComm = (float)$cfm0['agent_commission']; }
                                        elseif (isset($cfm0['agent commission'])) { $agentComm = (float)$cfm0['agent commission']; }
                                    }
                                    if ($statusNotes === '') {
                                        if (isset($cfm0['client_payment_status'])) { $statusNotes = (string)$cfm0['client_payment_status']; }
                                        elseif (isset($cfm0['payment_status'])) { $statusNotes = (string)$cfm0['payment_status']; }
                                        elseif (isset($cfm0['payment status'])) { $statusNotes = (string)$cfm0['payment status']; }
                                        elseif (isset($cfm0['notes'])) { $statusNotes = (string)$cfm0['notes']; }
                                    }
                                }
                            }
                        } catch (Throwable $eCF0) {}
                        try {
                            $needFromEmail = false;
                            if (!is_string($proj) || trim($proj) === '' || $proj === '-') { $needFromEmail = true; }
                            if (!is_string($dealSource) || trim($dealSource) === '' || $dealSource === '-') { $needFromEmail = true; }
                            if (!is_string($planType) || trim($planType) === '' || $planType === '-') { $needFromEmail = true; }
                            if (!is_string($marketerName) || trim($marketerName) === '' || $marketerName === '-') { $needFromEmail = true; }
                            if ($needFromEmail && colExists('client_forms','form_data')) {
                                $em = '';
                                if (isset($clientEmailView) && is_string($clientEmailView) && trim($clientEmailView) !== '') { $em = trim($clientEmailView); }
                                elseif (isset($row['client_email']) && is_string($row['client_email'])) { $em = trim($row['client_email']); }
                                elseif (isset($meta['client_email']) && is_string($meta['client_email'])) { $em = trim($meta['client_email']); }
                                        if ($em !== '') {
                                            $cfjE = '';
                                            // 1) Exact JSON key match for "email"
                                            try {
                                                $qfe = $pdo->prepare("SELECT form_data FROM client_forms WHERE form_data LIKE ? ORDER BY created_at DESC LIMIT 1");
                                                $qfe->execute(['%"email":"'.$em.'"%']);
                                                $cfjE = (string)($qfe->fetchColumn() ?: '');
                                            } catch (Throwable $eE1) {}
                                            // 2) Known alternate label
                                            if ($cfjE === '') {
                                                try {
                                                    $qfe2 = $pdo->prepare("SELECT form_data FROM client_forms WHERE form_data LIKE ? ORDER BY created_at DESC LIMIT 1");
                                                    $qfe2->execute(['%"Client Email (for dashboard)":"'.$em.'"%']);
                                                    $cfjE = (string)($qfe2->fetchColumn() ?: '');
                                                } catch (Throwable $eE2) {}
                                            }
                                            // 3) Fallback: any occurrence of the email substring
                                            if ($cfjE === '') {
                                                try {
                                                    $qfe3 = $pdo->prepare("SELECT form_data FROM client_forms WHERE form_data LIKE ? ORDER BY created_at DESC LIMIT 1");
                                                    $qfe3->execute(['%'.$em.'%']);
                                                    $cfjE = (string)($qfe3->fetchColumn() ?: '');
                                                } catch (Throwable $eE3) {}
                                            }
                                            // 4) If still empty, try matching by client name labels
                                            if ($cfjE === '') {
                                                try {
                                                    $clientNameGuess = '';
                                                    if (!empty($row['client_name'])) { $clientNameGuess = (string)$row['client_name']; }
                                                    elseif (!empty($meta['client_name'])) { $clientNameGuess = (string)$meta['client_name']; }
                                                    if ($clientNameGuess !== '') {
                                                        $patterns = [
                                                            '%"Client’s Name (text)":"'.$clientNameGuess.'"%',
                                                            '%"Client\'s Name (text)":"'.$clientNameGuess.'"%',
                                                            '%"client_name_text":"'.$clientNameGuess.'"%',
                                                            '%'.$clientNameGuess.'%'
                                                        ];
                                                        foreach ($patterns as $pt) {
                                                            $qfcn = $pdo->prepare("SELECT form_data FROM client_forms WHERE form_data LIKE ? ORDER BY created_at DESC LIMIT 1");
                                                            $qfcn->execute([$pt]);
                                                            $tmp = (string)($qfcn->fetchColumn() ?: '');
                                                            if ($tmp !== '') { $cfjE = $tmp; break; }
                                                        }
                                                    }
                                                } catch (Throwable $eE4) {}
                                            }
                                            if ($cfjE !== '') {
                                        $cfmE = json_decode($cfjE, true) ?: [];
                                        $cfProj = '';
                                        foreach (['project_desc','Project / Property Description','Project / Property','Property / Estate','Property/Estate','Estate / Property','project_or_property','preferred_property','preferred property','estate_name','property_estate','estate_property','property','estate','project_property','project','property_title','property_name','project_title','Project Name'] as $k) {
                                            $v = isset($cfmE[$k]) ? trim((string)$cfmE[$k]) : '';
                                            if ($v !== '') { $cfProj = $v; break; }
                                        }
                                        $cfSource = '';
                                        foreach (['deal_source','Deal Source','source','deal_source_type','lead_source','referral_source','referral source','submitted_by_role','Submitted By Role','department','team','channel','source_of_deal','source of deal','how did you hear about us','how you heard about us','where did you hear about us','where heard'] as $k) {
                                            $v = isset($cfmE[$k]) ? trim((string)$cfmE[$k]) : '';
                                            if ($v !== '') { $cfSource = $v; break; }
                                        }
                                        $cfPlan = '';
                                        foreach (['plan_type','Payment Plan','plan','payment_plan','plan_name','installment_plan','payment_mode','payment mode'] as $k) {
                                            $v = isset($cfmE[$k]) ? trim((string)$cfmE[$k]) : '';
                                            if ($v !== '') { $cfPlan = $v; break; }
                                        }
                                        $cfMarketer = '';
                                        foreach (['marketer_name','Marketer Name','Marketer or Contact Centre Name','Marketer or Contact Center Name','Contact Centre Name','Contact Center Name','Marketer’s Name','Marketer\'s Name','marketer','sales_agent','sales_rep','contact_rep','uploaded_by_name','submitted_by_name','agent_name','marketer_full_name','marketer full name'] as $k) {
                                            $v = isset($cfmE[$k]) ? trim((string)$cfmE[$k]) : '';
                                            if ($v !== '') { $cfMarketer = $v; break; }
                                        }
                                        if ($cfMarketer === '') {
                                            foreach ($cfmE as $kk=>$vv) {
                                                if (!is_string($vv) || trim($vv)==='') continue;
                                                $lk = strtolower(preg_replace('/[^a-z]/','', (string)$kk));
                                                if (strpos($lk,'submittedby')!==false || strpos($lk,'marketername')!==false || strpos($lk,'marketer')!==false || strpos($lk,'contactcentre')!==false || strpos($lk,'contactcenter')!==false) { $cfMarketer = trim((string)$vv); break; }
                                            }
                                        }
                                        if (!isset($meta['client_payment_status'])) {
                                            if (isset($cfmE['client_payment_status']) && trim((string)$cfmE['client_payment_status']) !== '') { $meta['client_payment_status'] = trim((string)$cfmE['client_payment_status']); }
                                            elseif (isset($cfmE['Client Payment Status / Notes']) && trim((string)$cfmE['Client Payment Status / Notes']) !== '') { $meta['client_payment_status'] = trim((string)$cfmE['Client Payment Status / Notes']); }
                                            elseif (isset($cfmE['Client Payment Status']) && trim((string)$cfmE['Client Payment Status']) !== '') { $meta['client_payment_status'] = trim((string)$cfmE['Client Payment Status']); }
                                            elseif (isset($cfmE['notes']) && trim((string)$cfmE['notes']) !== '') { $meta['client_payment_status'] = trim((string)$cfmE['notes']); }
                                        }
                                        if (!isset($meta['client_email'])) {
                                            if (isset($cfmE['client_email']) && trim((string)$cfmE['client_email']) !== '') { $meta['client_email'] = trim((string)$cfmE['client_email']); }
                                            elseif (isset($cfmE['Client Email (for dashboard)']) && trim((string)$cfmE['Client Email (for dashboard)']) !== '') { $meta['client_email'] = trim((string)$cfmE['Client Email (for dashboard)']); }
                                            elseif (isset($cfmE['email']) && trim((string)$cfmE['email']) !== '') { $meta['client_email'] = trim((string)$cfmE['email']); }
                                        }
                                        if (!isset($meta['client_name'])) {
                                            if (isset($cfmE['Client’s Name (text)']) && trim((string)$cfmE['Client’s Name (text)']) !== '') { $meta['client_name'] = trim((string)$cfmE['Client’s Name (text)']); }
                                            elseif (isset($cfmE["Client's Name (text)"]) && trim((string)$cfmE["Client's Name (text)"]) !== '') { $meta['client_name'] = trim((string)$cfmE["Client's Name (text)"]); }
                                            elseif (isset($cfmE['client_name_text']) && trim((string)$cfmE['client_name_text']) !== '') { $meta['client_name'] = trim((string)$cfmE['client_name_text']); }
                                        }
                                        if (!isset($meta['amount_offered'])) {
                                            if (isset($cfmE['Amount Offered (if installment)'])) { $meta['amount_offered'] = (float)$cfmE['Amount Offered (if installment)']; }
                                            elseif (isset($cfmE['offered_amount'])) { $meta['amount_offered'] = (float)$cfmE['offered_amount']; }
                                            elseif (isset($cfmE['offered amount'])) { $meta['amount_offered'] = (float)$cfmE['offered amount']; }
                                        }
                                        if (!isset($meta['amount_paid_so_far'])) {
                                            if (isset($cfmE['Amount Paid So Far'])) { $meta['amount_paid_so_far'] = (float)$cfmE['Amount Paid So Far']; }
                                            elseif (isset($cfmE['Paid So Far'])) { $meta['amount_paid_so_far'] = (float)$cfmE['Paid So Far']; }
                                        }
                                        if (!isset($meta['discount_approved_by'])) {
                                            if (isset($cfmE['Discount Approved By']) && trim((string)$cfmE['Discount Approved By']) !== '') { $meta['discount_approved_by'] = trim((string)$cfmE['Discount Approved By']); }
                                        }
                                        if (!isset($meta['commission_pct'])) {
                                            if (isset($cfmE['Commission %'])) { $meta['commission_pct'] = (float)$cfmE['Commission %']; }
                                        }
                                        if (!isset($meta['marketer_comm'])) {
                                            if (isset($cfmE['Marketer Commission Amount'])) { $meta['marketer_comm'] = (float)$cfmE['Marketer Commission Amount']; }
                                            elseif (isset($cfmE['Marketer Commission'])) { $meta['marketer_comm'] = (float)$cfmE['Marketer Commission']; }
                                        }
                                        if (!isset($meta['agent_comm'])) {
                                            if (isset($cfmE['Agent Commission Amount'])) { $meta['agent_comm'] = (float)$cfmE['Agent Commission Amount']; }
                                            elseif (isset($cfmE['Agent Commission'])) { $meta['agent_comm'] = (float)$cfmE['Agent Commission']; }
                                        }
                                        if ($proj === '-' || $proj === '') { $proj = $cfProj !== '' ? $cfProj : $proj; }
                                        if (!$dealSource && $cfSource !== '') { $dealSource = $cfSource; }
                                        if (!$planType && $cfPlan !== '') { $planType = $cfPlan; }
                                        if (!$marketerName && $cfMarketer !== '') { $marketerName = $cfMarketer; }
                                        if (empty($mkBank) || (empty($mkBank['acc_no']) && empty($mkBank['bank']) && empty($mkBank['acc_name']))) {
                                            if (isset($cfmE['marketer_bank']) && is_array($cfmE['marketer_bank'])) {
                                                $mkBank = [
                                                    'acc_no' => trim((string)($cfmE['marketer_bank']['acc_no'] ?? $cfmE['marketer_bank']['account_number'] ?? $cfmE['marketer_bank']['accNo'] ?? '')),
                                                    'bank' => trim((string)($cfmE['marketer_bank']['bank'] ?? $cfmE['marketer_bank']['bank_name'] ?? $cfmE['marketer_bank']['bankName'] ?? '')),
                                                    'acc_name' => trim((string)($cfmE['marketer_bank']['acc_name'] ?? $cfmE['marketer_bank']['account_name'] ?? $cfmE['marketer_bank']['accountName'] ?? ''))
                                                ];
                                            }
                                            if (empty($mkBank) || (empty($mkBank['acc_no']) && empty($mkBank['bank']) && empty($mkBank['acc_name']))) {
                                                $mkBank = [
                                                    'acc_no' => trim((string)($cfmE['mk_acc_no'] ?? ($cfmE['marketer_account_number'] ?? ($cfmE['Marketer Account Number'] ?? ($cfmE['marketer_acc_no'] ?? ''))))),
                                                    'bank' => trim((string)($cfmE['mk_bank'] ?? ($cfmE['marketer_bank_name'] ?? ($cfmE['Marketer Bank Name'] ?? ($cfmE['marketer_bank'] ?? ''))))),
                                                    'acc_name' => trim((string)($cfmE['mk_acc_name'] ?? ($cfmE['marketer_account_name'] ?? ($cfmE['Marketer Account Name'] ?? ($cfmE['marketer_acc_name'] ?? '')))))
                                                ];
                                            }
                                        }
                                        if (empty($agBank) || (empty($agBank['acc_no']) && empty($agBank['bank']) && empty($agBank['acc_name']))) {
                                            if (isset($cfmE['agent_bank']) && is_array($cfmE['agent_bank'])) {
                                                $agBank = [
                                                    'acc_no' => trim((string)($cfmE['agent_bank']['acc_no'] ?? $cfmE['agent_bank']['account_number'] ?? $cfmE['agent_bank']['accNo'] ?? '')),
                                                    'bank' => trim((string)($cfmE['agent_bank']['bank'] ?? $cfmE['agent_bank']['bank_name'] ?? $cfmE['agent_bank']['bankName'] ?? '')),
                                                    'acc_name' => trim((string)($cfmE['agent_bank']['acc_name'] ?? $cfmE['agent_bank']['account_name'] ?? $cfmE['agent_bank']['accountName'] ?? ''))
                                                ];
                                            }
                                            if (empty($agBank) || (empty($agBank['acc_no']) && empty($agBank['bank']) && empty($agBank['acc_name']))) {
                                                $agBank = [
                                                    'acc_no' => trim((string)($cfmE['ag_acc_no'] ?? ($cfmE['agent_account_number'] ?? ($cfmE['Agent Account Number'] ?? ($cfmE['agent_acc_no'] ?? ''))))),
                                                    'bank' => trim((string)($cfmE['ag_bank'] ?? ($cfmE['agent_bank_name'] ?? ($cfmE['Agent Bank Name'] ?? ($cfmE['agent_bank'] ?? ''))))),
                                                    'acc_name' => trim((string)($cfmE['ag_acc_name'] ?? ($cfmE['agent_account_name'] ?? ($cfmE['Agent Account Name'] ?? ($cfmE['agent_acc_name'] ?? '')))))
                                                ];
                                            }
                                        }
                                        if ($amountOffered <= 0) {
                                            if (isset($cfmE['amount_offered'])) { $amountOffered = (float)$cfmE['amount_offered']; }
                                            elseif (isset($cfmE['offered_amount'])) { $amountOffered = (float)$cfmE['offered_amount']; }
                                            elseif (isset($cfmE['offered amount'])) { $amountOffered = (float)$cfmE['offered amount']; }
                                        }
                                        if ($discountAmount <= 0 && isset($cfmE['discount_amount'])) { $discountAmount = (float)$cfmE['discount_amount']; }
                                        if ($discountBy === '' && isset($cfmE['discount_approved_by'])) { $discountBy = (string)$cfmE['discount_approved_by']; }
                                        if ($balanceRem <= 0 && isset($cfmE['balance_remaining'])) { $balanceRem = (float)$cfmE['balance_remaining']; }
                                        if ($amountPaidSoFar <= 0 && isset($cfmE['amount_paid_so_far'])) { $amountPaidSoFar = (float)$cfmE['amount_paid_so_far']; }
                                        if ($commissionPct <= 0) {
                                            if (isset($cfmE['commission_pct'])) { $commissionPct = (float)$cfmE['commission_pct']; }
                                            elseif (isset($cfmE['commission_percent'])) { $commissionPct = (float)$cfmE['commission_percent']; }
                                            elseif (isset($cfmE['commission %'])) { $commissionPct = (float)$cfmE['commission %']; }
                                        }
                                        if ($marketerComm <= 0) {
                                            if (isset($cfmE['marketer_comm'])) { $marketerComm = (float)$cfmE['marketer_comm']; }
                                            elseif (isset($cfmE['marketer_commission'])) { $marketerComm = (float)$cfmE['marketer_commission']; }
                                            elseif (isset($cfmE['marketer commission'])) { $marketerComm = (float)$cfmE['marketer commission']; }
                                        }
                                        if ($agentComm <= 0) {
                                            if (isset($cfmE['agent_comm'])) { $agentComm = (float)$cfmE['agent_comm']; }
                                            elseif (isset($cfmE['agent_commission'])) { $agentComm = (float)$cfmE['agent_commission']; }
                                            elseif (isset($cfmE['agent commission'])) { $agentComm = (float)$cfmE['agent commission']; }
                                        }
                                        if ($statusNotes === '') {
                                            if (isset($cfmE['client_payment_status'])) { $statusNotes = (string)$cfmE['client_payment_status']; }
                                            elseif (isset($cfmE['payment_status'])) { $statusNotes = (string)$cfmE['payment_status']; }
                                            elseif (isset($cfmE['payment status'])) { $statusNotes = (string)$cfmE['payment status']; }
                                            elseif (isset($cfmE['notes'])) { $statusNotes = (string)$cfmE['notes']; }
                                        }
                                    }
                                }
                            }
                        } catch (Throwable $eCFE) {}
                        try {
                            $needMore = false;
                            if (!is_string($proj) || trim($proj) === '' || $proj === '-') { $needMore = true; }
                            if (!is_string($dealSource) || trim($dealSource) === '' || $dealSource === '-') { $needMore = true; }
                            if (!is_string($planType) || trim($planType) === '' || $planType === '-') { $needMore = true; }
                            if (!is_string($marketerName) || trim($marketerName) === '' || $marketerName === '-') { $needMore = true; }
                            if ($needMore && colExists('client_forms','form_data')) {
                                $em2 = '';
                                if (isset($clientEmailView) && is_string($clientEmailView) && trim($clientEmailView) !== '') { $em2 = trim($clientEmailView); }
                                elseif (isset($row['client_email']) && is_string($row['client_email'])) { $em2 = trim($row['client_email']); }
                                elseif (isset($meta['client_email']) && is_string($meta['client_email'])) { $em2 = trim($meta['client_email']); }
                                if ($em2 !== '') {
                                    $qfm = $pdo->prepare("SELECT form_data FROM client_forms WHERE form_data LIKE ? ORDER BY created_at DESC LIMIT 10");
                                    $qfm->execute(['%"email":"'.$em2.'"%']);
                                    $forms = $qfm->fetchAll(PDO::FETCH_COLUMN) ?: [];
                                    foreach ($forms as $cfj) {
                                        $cf = json_decode((string)$cfj, true) ?: [];
                                        if ((!is_string($proj) || trim($proj) === '' || $proj === '-')) {
                                            foreach (['project_desc','property','estate','project_property','project','property_title','property_name','estate_name','project_or_property','preferred_property','preferred property'] as $k) {
                                                if (isset($cf[$k]) && trim((string)$cf[$k]) !== '') { $proj = trim((string)$cf[$k]); break; }
                                            }
                                        }
                                        if ((!is_string($dealSource) || trim($dealSource) === '' || $dealSource === '-')) {
                                            foreach (['deal_source','Deal Source','source','deal_source_type','lead_source','referral_source','referral source'] as $k) {
                                                if (isset($cf[$k]) && trim((string)$cf[$k]) !== '') { $dealSource = trim((string)$cf[$k]); break; }
                                            }
                                        }
                                        if ((!is_string($planType) || trim($planType) === '' || $planType === '-')) {
                                            foreach (['plan_type','Payment Plan','plan','payment_plan','plan_name','installment_plan','payment_mode','payment mode'] as $k) {
                                                if (isset($cf[$k]) && trim((string)$cf[$k]) !== '') { $planType = trim((string)$cf[$k]); break; }
                                            }
                                        }
                                        if ((!is_string($marketerName) || trim($marketerName) === '' || $marketerName === '-')) {
                                            foreach (['marketer_name','Marketer Name','Marketer or Contact Centre Name','Marketer or Contact Center Name','Contact Centre Name','Contact Center Name','marketer','sales_agent','sales_rep','contact_rep','uploaded_by_name','submitted_by_name','agent_name'] as $k) {
                                                if (isset($cf[$k]) && trim((string)$cf[$k]) !== '') { $marketerName = trim((string)$cf[$k]); break; }
                                            }
                                        }
                                        if ((empty($mkBank) || (empty($mkBank['acc_no']) && empty($mkBank['bank']) && empty($mkBank['acc_name'])))) {
                                            if (isset($cf['marketer_bank']) && is_array($cf['marketer_bank'])) {
                                                $mkBank = [
                                                    'acc_no' => trim((string)($cf['marketer_bank']['acc_no'] ?? $cf['marketer_bank']['account_number'] ?? $cf['marketer_bank']['accNo'] ?? '')),
                                                    'bank' => trim((string)($cf['marketer_bank']['bank'] ?? $cf['marketer_bank']['bank_name'] ?? $cf['marketer_bank']['bankName'] ?? '')),
                                                    'acc_name' => trim((string)($cf['marketer_bank']['acc_name'] ?? $cf['marketer_bank']['account_name'] ?? $cf['marketer_bank']['accountName'] ?? ''))
                                                ];
                                            } else {
                                                $mkBank = [
                                                    'acc_no' => trim((string)($cf['mk_acc_no'] ?? ($cf['marketer_account_number'] ?? ($cf['Marketer Account Number'] ?? ($cf['marketer_acc_no'] ?? ''))))),
                                                    'bank' => trim((string)($cf['mk_bank'] ?? ($cf['marketer_bank_name'] ?? ($cf['Marketer Bank Name'] ?? ($cf['marketer_bank'] ?? ''))))),
                                                    'acc_name' => trim((string)($cf['mk_acc_name'] ?? ($cf['marketer_account_name'] ?? ($cf['Marketer Account Name'] ?? ($cf['marketer_acc_name'] ?? '')))))
                                                ];
                                            }
                                        }
                                        if ((empty($agBank) || (empty($agBank['acc_no']) && empty($agBank['bank']) && empty($agBank['acc_name'])))) {
                                            if (isset($cf['agent_bank']) && is_array($cf['agent_bank'])) {
                                                $agBank = [
                                                    'acc_no' => trim((string)($cf['agent_bank']['acc_no'] ?? $cf['agent_bank']['account_number'] ?? $cf['agent_bank']['accNo'] ?? '')),
                                                    'bank' => trim((string)($cf['agent_bank']['bank'] ?? $cf['agent_bank']['bank_name'] ?? $cf['agent_bank']['bankName'] ?? '')),
                                                    'acc_name' => trim((string)($cf['agent_bank']['acc_name'] ?? $cf['agent_bank']['account_name'] ?? $cf['agent_bank']['accountName'] ?? ''))
                                                ];
                                            } else {
                                                $agBank = [
                                                    'acc_no' => trim((string)($cf['ag_acc_no'] ?? ($cf['agent_account_number'] ?? ($cf['Agent Account Number'] ?? ($cf['agent_acc_no'] ?? ''))))),
                                                    'bank' => trim((string)($cf['ag_bank'] ?? ($cf['agent_bank_name'] ?? ($cf['Agent Bank Name'] ?? ($cf['agent_bank'] ?? ''))))),
                                                    'acc_name' => trim((string)($cf['ag_acc_name'] ?? ($cf['agent_account_name'] ?? ($cf['Agent Account Name'] ?? ($cf['agent_acc_name'] ?? '')))))
                                                ];
                                            }
                                        }
                                        if ($amountOffered <= 0) {
                                            if (isset($cf['amount_offered'])) { $amountOffered = (float)$cf['amount_offered']; }
                                            elseif (isset($cf['offered_amount'])) { $amountOffered = (float)$cf['offered_amount']; }
                                            elseif (isset($cf['offered amount'])) { $amountOffered = (float)$cf['offered amount']; }
                                        }
                                        if ($discountAmount <= 0 && isset($cf['discount_amount'])) { $discountAmount = (float)$cf['discount_amount']; }
                                        if ($discountBy === '' && isset($cf['discount_approved_by'])) { $discountBy = (string)$cf['discount_approved_by']; }
                                        if ($balanceRem <= 0 && isset($cf['balance_remaining'])) { $balanceRem = (float)$cf['balance_remaining']; }
                                        if ($amountPaidSoFar <= 0 && isset($cf['amount_paid_so_far'])) { $amountPaidSoFar = (float)$cf['amount_paid_so_far']; }
                                        if ($commissionPct <= 0) {
                                            if (isset($cf['commission_pct'])) { $commissionPct = (float)$cf['commission_pct']; }
                                            elseif (isset($cf['commission_percent'])) { $commissionPct = (float)$cf['commission_percent']; }
                                            elseif (isset($cf['commission %'])) { $commissionPct = (float)$cf['commission %']; }
                                        }
                                        if ($marketerComm <= 0) {
                                            if (isset($cf['marketer_comm'])) { $marketerComm = (float)$cf['marketer_comm']; }
                                            elseif (isset($cf['marketer_commission'])) { $marketerComm = (float)$cf['marketer_commission']; }
                                            elseif (isset($cf['marketer commission'])) { $marketerComm = (float)$cf['marketer commission']; }
                                        }
                                        if ($agentComm <= 0) {
                                            if (isset($cf['agent_comm'])) { $agentComm = (float)$cf['agent_comm']; }
                                            elseif (isset($cf['agent_commission'])) { $agentComm = (float)$cf['agent_commission']; }
                                            elseif (isset($cf['agent commission'])) { $agentComm = (float)$cf['agent commission']; }
                                        }
                                        if ($statusNotes === '') {
                                            if (isset($cf['client_payment_status'])) { $statusNotes = (string)$cf['client_payment_status']; }
                                            elseif (isset($cf['payment_status'])) { $statusNotes = (string)$cf['payment_status']; }
                                            elseif (isset($cf['payment status'])) { $statusNotes = (string)$cf['payment status']; }
                                            elseif (isset($cf['notes'])) { $statusNotes = (string)$cf['notes']; }
                                        }
                                        $done = true;
                                        if ((is_string($proj) && trim($proj) !== '' && $proj !== '-')
                                            && (is_string($dealSource) && trim($dealSource) !== '' && $dealSource !== '-')
                                            && (is_string($planType) && trim($planType) !== '' && $planType !== '-')
                                            && (is_string($marketerName) && trim($marketerName) !== '' && $marketerName !== '-')) { break; }
                                    }
                                }
                            }
                        } catch (Throwable $eCFMany) {}
                        try {
                            if ((!is_string($marketerName) || trim($marketerName) === '' || $marketerName === '-')) {
                                $sid = 0;
                                if (colExists('payments','submitted_by_user') && isset($row['submitted_by_user'])) { $sid = (int)$row['submitted_by_user']; }
                                if ($sid <= 0 && isset($meta['submitted_by_user'])) { $sid = (int)$meta['submitted_by_user']; }
                                if ($sid > 0) {
                                    $name = '';
                                    try {
                                        $qu = $pdo->prepare("SELECT name,full_name,fullname,first_name,last_name FROM users WHERE id = ? LIMIT 1");
                                        $qu->execute([$sid]);
                                        $ur = $qu->fetch(PDO::FETCH_ASSOC) ?: [];
                                        if (!empty($ur)) {
                                            foreach (['name','full_name','fullname'] as $n) {
                                                if (isset($ur[$n]) && trim((string)$ur[$n]) !== '') { $name = trim((string)$ur[$n]); break; }
                                            }
                                            if ($name === '') {
                                                $fn = isset($ur['first_name']) ? trim((string)$ur['first_name']) : '';
                                                $ln = isset($ur['last_name']) ? trim((string)$ur['last_name']) : '';
                                                $nm = trim($fn.' '.$ln);
                                                if ($nm !== '') { $name = $nm; }
                                            }
                                        }
                                    } catch (Throwable $eU) {}
                                    if ($name !== '') { $marketerName = $name; }
                                }
                            }
                        } catch (Throwable $eStaff) {}
                        if ($amountPaidSoFar <= 0 && isset($row['amount'])) { $amountPaidSoFar = (float)$row['amount']; }
                        $subUidFull = 0; $subRoleFull = ''; $subNameFull = '';
                        if (!$submittedBy) {
                            try {
                                $subUid = 0; $subRole = '';
                                if ($dealIdRef > 0 && colExists('deals','meta_json')) {
                                    $qd = $pdo->prepare("SELECT meta_json FROM deals WHERE id = ? LIMIT 1");
                                    $qd->execute([$dealIdRef]);
                                    $dmj = $qd->fetchColumn();
                                    if ($dmj) {
                                        $m = json_decode($dmj, true) ?: [];
                                        $subUid = (int)($m['submitted_by_user'] ?? 0);
                                        $subRole = (string)($m['submitted_by_role'] ?? '');
                                        if ($subNameFull === '' && !empty($m['submitted_by_name'])) { $subNameFull = (string)$m['submitted_by_name']; }
                                    }
                                }
                                if ($subUid <= 0) {
                                    $rcp = (string)($row['receipt_file'] ?? '');
                                    if ($rcp !== '' && colExists('deals','meta_json')) {
                                        if (colExists('deals','receipt_file')) {
                                            $qs = $pdo->prepare("SELECT meta_json FROM deals WHERE receipt_file = ? LIMIT 1"); $qs->execute([$rcp]);
                                            $dmj = $qs->fetchColumn();
                                            if ($dmj) { $m = json_decode($dmj, true) ?: []; $subUid = (int)($m['submitted_by_user'] ?? 0); $subRole = (string)($m['submitted_by_role'] ?? ''); if ($subNameFull === '' && !empty($m['submitted_by_name'])) { $subNameFull = (string)$m['submitted_by_name']; } }
                                        } elseif (colExists('deals','proof_file')) {
                                            $qs = $pdo->prepare("SELECT meta_json FROM deals WHERE proof_file = ? LIMIT 1"); $qs->execute([$rcp]);
                                            $dmj = $qs->fetchColumn();
                                            if ($dmj) { $m = json_decode($dmj, true) ?: []; $subUid = (int)($m['submitted_by_user'] ?? 0); $subRole = (string)($m['submitted_by_role'] ?? ''); if ($subNameFull === '' && !empty($m['submitted_by_name'])) { $subNameFull = (string)$m['submitted_by_name']; } }
                                        }
                                    }
                                }
                                if ($subUid <= 0) {
                                    $uid = (int)($row['user_id'] ?? 0);
                                    if ($uid > 0 && colExists('deals','user_id') && colExists('deals','meta_json')) {
                                        $qd = $pdo->prepare("SELECT meta_json FROM deals WHERE user_id = ? ORDER BY id DESC LIMIT 1");
                                        $qd->execute([$uid]);
                                        $dmj = $qd->fetchColumn();
                                        if ($dmj) { $m = json_decode($dmj, true) ?: []; $subUid = (int)($m['submitted_by_user'] ?? 0); $subRole = (string)($m['submitted_by_role'] ?? ''); if ($subNameFull === '' && !empty($m['submitted_by_name'])) { $subNameFull = (string)$m['submitted_by_name']; } }
                                    }
                                }
                                if ($subUid > 0) {
                                    $display = '#'.$subUid;
                                    if (colExists('users','name')) {
                                        $qn = $pdo->prepare("SELECT name FROM users WHERE id = ? LIMIT 1");
                                        $qn->execute([$subUid]); $n = (string)($qn->fetchColumn() ?: '');
                                        if ($n !== '') { $display .= ' '.$n; if ($subNameFull === '') { $subNameFull = $n; } }
                                    }
                                    if ($subRole !== '') { $display .= ' / '.strtoupper($subRole); }
                                    $subUidFull = $subUid; $subRoleFull = $subRole;
                                    $submittedBy = $display;
                                }
                        if (!$submittedBy && $marketerName !== '' && colExists('users','name')) {
                            try {
                                $qnm = $pdo->prepare("SELECT id FROM users WHERE name = ? LIMIT 1");
                                $qnm->execute([$marketerName]);
                                $sid = (int)($qnm->fetchColumn() ?: 0);
                                if ($sid <= 0) {
                                    $qnm = $pdo->prepare("SELECT id FROM users WHERE name LIKE ? ORDER BY id DESC LIMIT 1");
                                    $qnm->execute(['%'.$marketerName.'%']); $sid = (int)($qnm->fetchColumn() ?: 0);
                                }
                                if ($sid > 0) {
                                    $subUidFull = $sid;
                                    $subRoleFull = ($dealSource !== '' ? strtolower($dealSource) : 'marketing');
                                    $disp = '#'.$sid;
                                    if (colExists('users','name')) {
                                        $qn = $pdo->prepare("SELECT name FROM users WHERE id = ? LIMIT 1");
                                        $qn->execute([$sid]); $nn = (string)($qn->fetchColumn() ?: '');
                                        if ($nn !== '') { $disp .= ' '.$nn; if ($subNameFull === '') { $subNameFull = $nn; } }
                                    }
                                    if ($subRoleFull !== '') { $disp .= ' / '.strtoupper($subRoleFull); }
                                    $submittedBy = $disp;
                                }
                            } catch (Throwable $eNameMap) {}
                        }
                        if (!$submittedBy && $marketerName !== '') {
                            $subRoleFull = $subRoleFull !== '' ? $subRoleFull : ($dealSource !== '' ? strtolower($dealSource) : 'marketing');
                            $submittedBy = $marketerName . ' / ' . strtoupper($subRoleFull);
                            if ($subNameFull === '') { $subNameFull = $marketerName; }
                        }
                        if (!$submittedBy) {
                            try {
                                $uidP = 0;
                                // Prefer explicit staff/submitter identifiers on payments
                                $payStaffCols = ['submitted_by_user','submitted_by','created_by','created_by_user','staff_id','marketer_id','agent_id','contact_rep_id'];
                                foreach ($payStaffCols as $pc) {
                                    if ($uidP > 0) break;
                                    if (isset($row[$pc]) && (int)$row[$pc] > 0) { $uidP = (int)$row[$pc]; break; }
                                }
                                // Fallback to meta-provided submitter identifiers
                                if ($uidP <= 0) {
                                    $metaStaffKeys = ['submitted_by_user','submitted_by','created_by','created_by_user','staff_id','marketer_id','agent_id','contact_rep_id'];
                                    foreach ($metaStaffKeys as $mk) {
                                        if ($uidP > 0) break;
                                        if (isset($meta[$mk]) && (int)$meta[$mk] > 0) { $uidP = (int)$meta[$mk]; break; }
                                    }
                                }
                                if ($uidP > 0) {
                                    $nmP = '';
                                    if (colExists('users','name')) {
                                        $qn = $pdo->prepare("SELECT name FROM users WHERE id = ? LIMIT 1");
                                        $qn->execute([$uidP]); $nmP = (string)($qn->fetchColumn() ?: '');
                                    }
                                    $roleP = $subRoleFull !== '' ? $subRoleFull : ((string)($meta['submitted_by_role'] ?? '') !== '' ? (string)$meta['submitted_by_role'] : ($dealSource !== '' ? strtolower($dealSource) : 'marketing'));
                                    $dispP = '#'.$uidP . ($nmP !== '' ? ' '.$nmP : '') . ($roleP !== '' ? ' / '.strtoupper($roleP) : '');
                                    $submittedBy = $dispP;
                                    if ($subUidFull <= 0) { $subUidFull = $uidP; }
                                    if ($subRoleFull === '') { $subRoleFull = $roleP; }
                                    if ($subNameFull === '' && $nmP !== '') { $subNameFull = $nmP; }
                                }
                            } catch (Throwable $eSubP) {}
                        }
                            } catch (Throwable $eSB) {}
                        if (!$submittedBy) {
                            $nameAlt = '';
                            if ($subNameFull !== '') { $nameAlt = $subNameFull; }
                            elseif (!empty($meta['submitted_by_name'])) { $nameAlt = (string)$meta['submitted_by_name']; }
                            elseif (!empty($meta['uploaded_by_name'])) { $nameAlt = (string)$meta['uploaded_by_name']; }
                            elseif (!empty($meta['created_by_name'])) { $nameAlt = (string)$meta['created_by_name']; }
                            elseif (!empty($meta['creator_name'])) { $nameAlt = (string)$meta['creator_name']; }
                            elseif (!empty($meta['contact_centre_name'])) { $nameAlt = (string)$meta['contact_centre_name']; }
                            elseif (!empty($meta['contact_center_name'])) { $nameAlt = (string)$meta['contact_center_name']; }
                            elseif (!empty($meta['Submitted By'])) { $nameAlt = (string)$meta['Submitted By']; }
                            elseif (!empty($meta['submitted_by'])) { $nameAlt = (string)$meta['submitted_by']; }
                            elseif (!empty($meta['SUBMITTED BY'])) { $nameAlt = (string)$meta['SUBMITTED BY']; }
                            elseif (!empty($meta['sales_agent'])) { $nameAlt = (string)$meta['sales_agent']; }
                            elseif (!empty($meta['sales_rep'])) { $nameAlt = (string)$meta['sales_rep']; }
                            elseif (!empty($meta['agent_name'])) { $nameAlt = (string)$meta['agent_name']; }
                            elseif (isset($row['submitted_by_name']) && is_string($row['submitted_by_name']) && trim($row['submitted_by_name'])!=='') { $nameAlt = (string)$row['submitted_by_name']; }
                            elseif (isset($row['uploaded_by_name']) && is_string($row['uploaded_by_name']) && trim($row['uploaded_by_name'])!=='') { $nameAlt = (string)$row['uploaded_by_name']; }
                            elseif (isset($row['created_by_name']) && is_string($row['created_by_name']) && trim($row['created_by_name'])!=='') { $nameAlt = (string)$row['created_by_name']; }
                            elseif (isset($row['created_by_full_name']) && is_string($row['created_by_full_name']) && trim($row['created_by_full_name'])!=='') { $nameAlt = (string)$row['created_by_full_name']; }
                            elseif ($marketerName !== '') { $nameAlt = $marketerName; }
                            $roleAlt = $subRoleFull !== '' ? $subRoleFull : ((string)($meta['submitted_by_role'] ?? '') !== '' ? (string)$meta['submitted_by_role'] : ($dealSource !== '' ? strtolower($dealSource) : 'marketing'));
                            $roleDisp = strtoupper($roleAlt ?: 'marketing');
                            if ($nameAlt !== '') { $subNameFull = $nameAlt; $submittedBy = $nameAlt . ' / ' . $roleDisp; }
                        }
                        }
                        $clientEmailView = isset($meta['client_email']) ? (string)$meta['client_email'] : '';
                        $paymentRefView = '';
                        $paymentMethodView = '';
                        try {
                            $uid = (int)($row['user_id'] ?? 0);
                            if ($clientEmailView === '' && $uid > 0 && colExists('users','email')) {
                                $qe = $pdo->prepare("SELECT email FROM users WHERE id = ? LIMIT 1");
                                $qe->execute([$uid]);
                                $clientEmailView = (string)($qe->fetchColumn() ?: '');
                            }
                            $refCol = colExists('payments','reference') ? "reference" : (colExists('payments','ref') ? "ref" : "NULL");
                            $methodCol = colExists('payments','payment_method') ? "payment_method" : (colExists('payments','method') ? "method" : "NULL");
                            $qp = $pdo->prepare("SELECT {$refCol} AS ref, {$methodCol} AS method FROM payments WHERE id = ? LIMIT 1");
                            $qp->execute([(int)$row['id']]);
                            $prm = $qp->fetch(PDO::FETCH_ASSOC) ?: [];
                            $paymentRefView = (string)($prm['ref'] ?? '');
                            $paymentMethodView = (string)($prm['method'] ?? '');
                        } catch (Throwable $eInfo) {}
                        try {
                            $needCore = false;
                            if (!is_string($proj) || trim($proj) === '' || $proj === '-') { $needCore = true; }
                            if (!is_string($dealSource) || trim($dealSource) === '' || $dealSource === '-') { $needCore = true; }
                            if (!is_string($planType) || trim($planType) === '' || $planType === '-') { $needCore = true; }
                            if (!is_string($marketerName) || trim($marketerName) === '' || $marketerName === '-') { $needCore = true; }
                            if ($needCore) {
                                $rcpG = (string)($row['receipt_file'] ?? '');
                                if ($rcpG !== '') {
                                    $selCols = [];
                                    $selCols[] = 'id';
                                    if (colExists('deals','project_name')) { $selCols[] = 'project_name'; }
                                    if (colExists('deals','project_desc')) { $selCols[] = 'project_desc'; }
                                    if (colExists('deals','deal_source')) { $selCols[] = 'deal_source'; }
                                    if (colExists('deals','plan_type')) { $selCols[] = 'plan_type'; }
                                    if (colExists('deals','payment_plan')) { $selCols[] = 'payment_plan'; }
                                    if (colExists('deals','marketer_name')) { $selCols[] = 'marketer_name'; }
                                    if (colExists('deals','amount_offered')) { $selCols[] = 'amount_offered'; }
                                    if (colExists('deals','amount_paid_so_far')) { $selCols[] = 'amount_paid_so_far'; }
                                    if (colExists('deals','discount_amount')) { $selCols[] = 'discount_amount'; }
                                    if (colExists('deals','discount_approved_by')) { $selCols[] = 'discount_approved_by'; }
                                    if (colExists('deals','commission_percent')) { $selCols[] = 'commission_percent'; }
                                    if (colExists('deals','balance_remaining')) { $selCols[] = 'balance_remaining'; }
                                    if (colExists('deals','notes')) { $selCols[] = 'notes'; }
                                    $sel = implode(',', $selCols);
                                    $drX = [];
                                    if (colExists('deals','receipt_file')) {
                                        $qd = $pdo->prepare("SELECT $sel FROM deals WHERE receipt_file = ? ORDER BY id DESC LIMIT 1");
                                        $qd->execute([$rcpG]); $drX = $qd->fetch(PDO::FETCH_ASSOC) ?: [];
                                        if (empty($drX)) {
                                            $base = basename($rcpG);
                                            if ($base !== '') { $qd = $pdo->prepare("SELECT $sel FROM deals WHERE receipt_file LIKE ? ORDER BY id DESC LIMIT 1"); $qd->execute(['%'.$base]); $drX = $qd->fetch(PDO::FETCH_ASSOC) ?: []; }
                                        }
                                    } elseif (colExists('deals','proof_file')) {
                                        $qd = $pdo->prepare("SELECT $sel FROM deals WHERE proof_file = ? ORDER BY id DESC LIMIT 1");
                                        $qd->execute([$rcpG]); $drX = $qd->fetch(PDO::FETCH_ASSOC) ?: [];
                                        if (empty($drX)) {
                                            $base = basename($rcpG);
                                            if ($base !== '') { $qd = $pdo->prepare("SELECT $sel FROM deals WHERE proof_file LIKE ? ORDER BY id DESC LIMIT 1"); $qd->execute(['%'.$base]); $drX = $qd->fetch(PDO::FETCH_ASSOC) ?: []; }
                                        }
                                    }
                                    if (!empty($drX)) {
                                        if ((!is_string($proj) || trim($proj) === '' || $proj === '-')) {
                                            $pName = isset($drX['project_name']) ? (string)$drX['project_name'] : '';
                                            $pDesc = isset($drX['project_desc']) ? (string)$drX['project_desc'] : '';
                                            $proj = $pName !== '' ? $pName : ($pDesc !== '' ? $pDesc : $proj);
                                        }
                                        if ((!is_string($dealSource) || trim($dealSource) === '' || $dealSource === '-') && isset($drX['deal_source'])) { $dealSource = (string)$drX['deal_source']; }
                                        if ((!is_string($planType) || trim($planType) === '' || $planType === '-')) {
                                            $planType = isset($drX['plan_type']) ? (string)$drX['plan_type'] : (isset($drX['payment_plan']) ? (string)$drX['payment_plan'] : $planType);
                                        }
                                        if ((!is_string($marketerName) || trim($marketerName) === '' || $marketerName === '-') && isset($drX['marketer_name'])) { $marketerName = (string)$drX['marketer_name']; }
                                        if ($amountOffered <= 0 && isset($drX['amount_offered'])) { $amountOffered = (float)$drX['amount_offered']; }
                                        if ($amountPaidSoFar <= 0 && isset($drX['amount_paid_so_far'])) { $amountPaidSoFar = (float)$drX['amount_paid_so_far']; }
                                        if ($discountAmount <= 0 && isset($drX['discount_amount'])) { $discountAmount = (float)$drX['discount_amount']; }
                                        if ($commissionPct <= 0 && isset($drX['commission_percent'])) { $commissionPct = (float)$drX['commission_percent']; }
                                        if ($balanceRem <= 0 && isset($drX['balance_remaining'])) { $balanceRem = (float)$drX['balance_remaining']; }
                                        if ($statusNotes === '' && isset($drX['notes'])) { $statusNotes = (string)$drX['notes']; }
                                    }
                                }
                                // Time-window fallback by created_at and user_id if still missing
                                $stillMissing = (!is_string($proj) || trim($proj) === '' || $proj === '-') 
                                    || (!is_string($dealSource) || trim($dealSource) === '' || $dealSource === '-')
                                    || (!is_string($planType) || trim($planType) === '' || $planType === '-')
                                    || (!is_string($marketerName) || trim($marketerName) === '' || $marketerName === '-');
                                if ($stillMissing) {
                                    $createdAt = (string)($row['created_at'] ?? '');
                                    $uidH = (int)($row['user_id'] ?? 0);
                                    if ($createdAt !== '') {
                                        $selCols2 = [];
                                        $selCols2[] = 'id';
                                        if (colExists('deals','project_name')) { $selCols2[] = 'project_name'; }
                                        if (colExists('deals','project_desc')) { $selCols2[] = 'project_desc'; }
                                        if (colExists('deals','deal_source')) { $selCols2[] = 'deal_source'; }
                                        if (colExists('deals','plan_type')) { $selCols2[] = 'plan_type'; }
                                        if (colExists('deals','payment_plan')) { $selCols2[] = 'payment_plan'; }
                                        if (colExists('deals','marketer_name')) { $selCols2[] = 'marketer_name'; }
                                        if (colExists('deals','amount_offered')) { $selCols2[] = 'amount_offered'; }
                                        if (colExists('deals','amount_paid_so_far')) { $selCols2[] = 'amount_paid_so_far'; }
                                        if (colExists('deals','discount_amount')) { $selCols2[] = 'discount_amount'; }
                                        if (colExists('deals','discount_approved_by')) { $selCols2[] = 'discount_approved_by'; }
                                        if (colExists('deals','commission_percent')) { $selCols2[] = 'commission_percent'; }
                                        if (colExists('deals','balance_remaining')) { $selCols2[] = 'balance_remaining'; }
                                        if (colExists('deals','notes')) { $selCols2[] = 'notes'; }
                                        $sel2 = implode(',', $selCols2);
                                        $clauses = ["created_at BETWEEN DATE_SUB(?, INTERVAL 2 HOUR) AND DATE_ADD(?, INTERVAL 2 HOUR)"];
                                        $params = [$createdAt, $createdAt];
                                        if ($uidH > 0 && (colExists('deals','user_id') || colExists('deals','submitted_by'))) {
                                            $cl = [];
                                            if (colExists('deals','user_id')) { $cl[] = "user_id = ?"; $params[] = $uidH; }
                                            if (colExists('deals','submitted_by')) { $cl[] = "submitted_by = ?"; $params[] = $uidH; }
                                            if (!empty($cl)) { $clauses[] = '('.implode(' OR ', $cl).')'; }
                                        }
                                        $sqlF = "SELECT $sel2 FROM deals WHERE ".implode(' AND ', $clauses)." ORDER BY id DESC LIMIT 1";
                                        try {
                                            $qf = $pdo->prepare($sqlF);
                                            $qf->execute($params);
                                            $drW = $qf->fetch(PDO::FETCH_ASSOC) ?: [];
                                            if (!empty($drW)) {
                                                if ((!is_string($proj) || trim($proj) === '' || $proj === '-')) {
                                                    $pName = isset($drW['project_name']) ? (string)$drW['project_name'] : '';
                                                    $pDesc = isset($drW['project_desc']) ? (string)$drW['project_desc'] : '';
                                                    $proj = $pName !== '' ? $pName : ($pDesc !== '' ? $pDesc : $proj);
                                                }
                                                if ((!is_string($dealSource) || trim($dealSource) === '' || $dealSource === '-') && isset($drW['deal_source'])) { $dealSource = (string)$drW['deal_source']; }
                                                if ((!is_string($planType) || trim($planType) === '' || $planType === '-')) {
                                                    $planType = isset($drW['plan_type']) ? (string)$drW['plan_type'] : (isset($drW['payment_plan']) ? (string)$drW['payment_plan'] : $planType);
                                                }
                                                if ((!is_string($marketerName) || trim($marketerName) === '' || $marketerName === '-') && isset($drW['marketer_name'])) { $marketerName = (string)$drW['marketer_name']; }
                                                if ($amountOffered <= 0 && isset($drW['amount_offered'])) { $amountOffered = (float)$drW['amount_offered']; }
                                                if ($amountPaidSoFar <= 0 && isset($drW['amount_paid_so_far'])) { $amountPaidSoFar = (float)$drW['amount_paid_so_far']; }
                                                if ($discountAmount <= 0 && isset($drW['discount_amount'])) { $discountAmount = (float)$drW['discount_amount']; }
                                                if ($commissionPct <= 0 && isset($drW['commission_percent'])) { $commissionPct = (float)$drW['commission_percent']; }
                                                if ($balanceRem <= 0 && isset($drW['balance_remaining'])) { $balanceRem = (float)$drW['balance_remaining']; }
                                                if ($statusNotes === '' && isset($drW['notes'])) { $statusNotes = (string)$drW['notes']; }
                                            }
                                        } catch (Throwable $eWin) {}
                                    }
                                }
                            }
                        } catch (Throwable $ePreNorm) {}
                        try {
                            if (colExists('payments','meta_json')) {
                                $currentMeta = [];
                                try {
                                    $qcm = $pdo->prepare("SELECT meta_json FROM payments WHERE id = ? LIMIT 1");
                                    $qcm->execute([(int)$row['id']]); $cmj = (string)($qcm->fetchColumn() ?: '');
                                    if ($cmj !== '') { $currentMeta = json_decode($cmj, true) ?: []; }
                                } catch (Throwable $eCM) {}
                                // Hard-resolution for missing core fields before building normalized payload
                                try {
                                    $projMissing = (!is_string($proj) || trim($proj) === '' || $proj === '-');
                                    $srcMissing = (!is_string($dealSource) || trim($dealSource) === '' || $dealSource === '-');
                                    $planMissing = (!is_string($planType) || trim($planType) === '' || $planType === '-');
                                    $markMissing = (!is_string($marketerName) || trim($marketerName) === '' || $marketerName === '-');
                                    $rcpG = (string)($row['receipt_file'] ?? '');
                                    if (($projMissing || $srcMissing || $planMissing || $markMissing) && $rcpG !== '') {
                                        $dealCols = [];
                                        $dealCols[] = 'id';
                                        if (colExists('deals','project_name')) { $dealCols[] = 'project_name'; }
                                        if (colExists('deals','project_desc')) { $dealCols[] = 'project_desc'; }
                                        if (colExists('deals','deal_source')) { $dealCols[] = 'deal_source'; }
                                        if (colExists('deals','plan_type')) { $dealCols[] = 'plan_type'; }
                                        if (colExists('deals','payment_plan')) { $dealCols[] = 'payment_plan'; }
                                        if (colExists('deals','marketer_name')) { $dealCols[] = 'marketer_name'; }
                                        if (colExists('deals','amount_offered')) { $dealCols[] = 'amount_offered'; }
                                        if (colExists('deals','amount_paid_so_far')) { $dealCols[] = 'amount_paid_so_far'; }
                                        if (colExists('deals','discount_amount')) { $dealCols[] = 'discount_amount'; }
                                        if (colExists('deals','discount_approved_by')) { $dealCols[] = 'discount_approved_by'; }
                                        if (colExists('deals','commission_percent')) { $dealCols[] = 'commission_percent'; }
                                        if (colExists('deals','balance_remaining')) { $dealCols[] = 'balance_remaining'; }
                                        if (colExists('deals','notes')) { $dealCols[] = 'notes'; }
                                        if (colExists('deals','meta_json')) { $dealCols[] = 'meta_json'; }
                                        $sel = implode(',', $dealCols);
                                        $qd = null; $dr = [];
                                        if (colExists('deals','receipt_file')) {
                                            $qd = $pdo->prepare("SELECT $sel FROM deals WHERE receipt_file = ? ORDER BY id DESC LIMIT 1");
                                            $qd->execute([$rcpG]);
                                            $dr = $qd->fetch(PDO::FETCH_ASSOC) ?: [];
                                            if (empty($dr)) {
                                                $base = basename($rcpG);
                                                if ($base !== '') {
                                                    $qd = $pdo->prepare("SELECT $sel FROM deals WHERE receipt_file LIKE ? ORDER BY id DESC LIMIT 1");
                                                    $qd->execute(['%'.$base]);
                                                    $dr = $qd->fetch(PDO::FETCH_ASSOC) ?: [];
                                                }
                                            }
                                        } elseif (colExists('deals','proof_file')) {
                                            $qd = $pdo->prepare("SELECT $sel FROM deals WHERE proof_file = ? ORDER BY id DESC LIMIT 1");
                                            $qd->execute([$rcpG]);
                                            $dr = $qd->fetch(PDO::FETCH_ASSOC) ?: [];
                                            if (empty($dr)) {
                                                $base = basename($rcpG);
                                                if ($base !== '') {
                                                    $qd = $pdo->prepare("SELECT $sel FROM deals WHERE proof_file LIKE ? ORDER BY id DESC LIMIT 1");
                                                    $qd->execute(['%'.$base]);
                                                    $dr = $qd->fetch(PDO::FETCH_ASSOC) ?: [];
                                                }
                                            }
                                        }
                                        if (!empty($dr)) {
                                            if ($projMissing) {
                                                $pName = (string)($dr['project_name'] ?? '');
                                                $pDesc = (string)($dr['project_desc'] ?? '');
                                                $proj = $pName !== '' ? $pName : ($pDesc !== '' ? $pDesc : $proj);
                                            }
                                            if ($srcMissing && isset($dr['deal_source'])) { $dealSource = (string)$dr['deal_source']; }
                                            if ($planMissing) {
                                                $planType = isset($dr['plan_type']) ? (string)$dr['plan_type'] : (isset($dr['payment_plan']) ? (string)$dr['payment_plan'] : $planType);
                                            }
                                            if ($markMissing && isset($dr['marketer_name'])) { $marketerName = (string)$dr['marketer_name']; }
                                            if ($amountOffered <= 0 && isset($dr['amount_offered'])) { $amountOffered = (float)$dr['amount_offered']; }
                                            if ($amountPaidSoFar <= 0 && isset($dr['amount_paid_so_far'])) { $amountPaidSoFar = (float)$dr['amount_paid_so_far']; }
                                            if ($discountAmount <= 0 && isset($dr['discount_amount'])) { $discountAmount = (float)$dr['discount_amount']; }
                                            if ($commissionPct <= 0 && isset($dr['commission_percent'])) { $commissionPct = (float)$dr['commission_percent']; }
                                            if ($balanceRem <= 0 && isset($dr['balance_remaining'])) { $balanceRem = (float)$dr['balance_remaining']; }
                                            if ($statusNotes === '' && isset($dr['notes'])) { $statusNotes = (string)$dr['notes']; }
                                            if (colExists('payments','deal_id') && isset($dr['id'])) {
                                                try {
                                                    $pdo->prepare("UPDATE payments SET deal_id = ? WHERE id = ?")->execute([(int)$dr['id'], (int)$row['id']]);
                                                    @file_put_contents(__DIR__ . '/debug_sql.txt', "PAYMENT_LINK:\nUPDATE payments SET deal_id = ".(int)$dr['id']." WHERE id = ".(int)$row['id']."\n", FILE_APPEND);
                                                } catch (Throwable $eLink) {}
                                            }
                                            if (empty($currentMeta) && isset($dr['meta_json']) && is_string($dr['meta_json']) && $dr['meta_json'] !== '') {
                                                $currentMeta = json_decode($dr['meta_json'], true) ?: [];
                                            }
                                        }
                                    }
                                } catch (Throwable $eHard) {}
                                $paymentStatusMeta = (string)($row['status'] ?? ($row['payment_status'] ?? ($row['paymentStatus'] ?? '')));
                                $paymentDateMeta = (string)($row['created_at'] ?? ($row['date'] ?? ($row['payment_date'] ?? ($row['approved_at'] ?? ($row['verified_at'] ?? ($row['updated_at'] ?? ''))))));
                                $instStartMeta = (string)($meta['installment_start_date'] ?? ($meta['installmentStartDate'] ?? ($meta['start_date'] ?? ($meta['startDate'] ?? ($meta['Installment Start Date'] ?? ($meta['Start Date'] ?? ''))))));
                                $sqmMeta = null;
                                foreach (['sqm','SQM','sqm_size','SQM Size','plot_size','Plot Size','size_sqm','Size (SQM)'] as $k0) {
                                    if (isset($meta[$k0]) && is_numeric($meta[$k0])) { $sqmMeta = (float)$meta[$k0]; break; }
                                }
                                $normalized = [
                                    'payment_id' => (int)($row['id'] ?? 0),
                                    'payment_status' => $paymentStatusMeta,
                                    'payment_date' => $paymentDateMeta,
                                    'client_name' => $clientNameMeta ?: ($row['client_name'] ?? ''),
                                    'client_email' => $clientEmailView,
                                    'project_desc' => $proj !== '-' ? $proj : ($quickProperty ?: ''),
                                    'deal_source' => $dealSource,
                                    'plan_type' => $planType,
                                    'installment_start_date' => $instStartMeta,
                                    'sqm' => $sqmMeta,
                                    'amount_offered' => $amountOffered,
                                    'amount_paid_so_far' => $amountPaidSoFar,
                                    'amount_paid_now' => (float)($row['amount'] ?? 0),
                                    'discount_amount' => $discountAmount,
                                    'discount_approved_by' => $discountBy,
                                    'commission_pct' => $commissionPct,
                                    'marketer_comm' => $marketerComm,
                                    'agent_comm' => $agentComm,
                                    'balance_remaining' => $balanceRem,
                                    'client_payment_status' => $statusNotes ?: $quickNotes,
                                    'marketer_bank' => $mkBank,
                                    'agent_bank' => $agBank,
                                    'transactions' => $transactionsMeta,
                                    'submitted_by_user' => $subUidFull > 0 ? $subUidFull : (int)($meta['submitted_by_user'] ?? 0),
                                    'submitted_by_role' => $subRoleFull !== '' ? $subRoleFull : (string)($meta['submitted_by_role'] ?? ''),
                                    'submitted_by_name' => ($subNameFull !== '' ? $subNameFull : $marketerName),
                                    'marketer_name' => $marketerName,
                                    'payment_reference' => $paymentRefView,
                                    'payment_method' => $paymentMethodView
                                ];
                                $merged = is_array($currentMeta) ? $currentMeta : [];
                                $allBlankArr = function($arr) {
                                    if (!is_array($arr)) return false;
                                    if (empty($arr)) return true;
                                    foreach ($arr as $vv) {
                                        if (is_array($vv)) {
                                            if (!empty($vv)) return false;
                                            continue;
                                        }
                                        $s = trim((string)$vv);
                                        if ($s !== '' && $s !== '-') return false;
                                    }
                                    return true;
                                };
                                foreach ($normalized as $k=>$v) {
                                    $hasKey = array_key_exists($k, $merged);
                                    $cur = $hasKey ? $merged[$k] : null;
                                    $shouldSet = !$hasKey;
                                    if (!$shouldSet) {
                                        if (is_string($cur)) { $t = trim($cur); $shouldSet = ($t === '' || $t === '-'); }
                                        elseif (is_array($cur)) { $shouldSet = $allBlankArr($cur); }
                                        elseif ($cur === null) { $shouldSet = true; }
                                    }
                                    if ($shouldSet) { $merged[$k] = $v; }
                                }
                                $newJson = json_encode($merged);
                                $oldJson = isset($cmj) ? $cmj : '';
                                if ($newJson && $newJson !== $oldJson) {
                                    $up = $pdo->prepare("UPDATE payments SET meta_json = ? WHERE id = ?");
                                    $up->execute([$newJson, (int)$row['id']]);
                                }
                                $modalMetaJson = $newJson ?: '{}';
                            }
                        } catch (Throwable $eWrite) {}
                        // Ensure modal meta exists even if payments.meta_json column is absent
                        if (!isset($modalMetaJson) || !is_string($modalMetaJson) || trim($modalMetaJson) === '') {
                            $fallbackMeta = [
                                'payment_id' => (int)($row['id'] ?? 0),
                                'payment_status' => (string)($row['status'] ?? ($row['payment_status'] ?? ($row['paymentStatus'] ?? ''))),
                                'payment_date' => (string)($row['created_at'] ?? ($row['date'] ?? ($row['payment_date'] ?? ($row['approved_at'] ?? ($row['verified_at'] ?? ($row['updated_at'] ?? '')))))),
                                'client_name' => $clientNameMeta ?: ($row['client_name'] ?? ''),
                                'client_email' => $clientEmailView,
                                'project_desc' => $proj !== '-' ? $proj : ($quickProperty ?: ''),
                                'deal_source' => $dealSource,
                                'plan_type' => $planType,
                                'installment_start_date' => (string)($meta['installment_start_date'] ?? ($meta['installmentStartDate'] ?? ($meta['start_date'] ?? ($meta['startDate'] ?? ($meta['Installment Start Date'] ?? ($meta['Start Date'] ?? '')))))),
                                'sqm' => (function() use ($meta) {
                                    foreach (['sqm','SQM','sqm_size','SQM Size','plot_size','Plot Size','size_sqm','Size (SQM)'] as $k0) {
                                        if (isset($meta[$k0]) && is_numeric($meta[$k0])) { return (float)$meta[$k0]; }
                                    }
                                    return null;
                                })(),
                                'amount_offered' => $amountOffered,
                                'amount_paid_so_far' => $amountPaidSoFar,
                                'amount_paid_now' => (float)($row['amount'] ?? 0),
                                'discount_amount' => $discountAmount,
                                'discount_approved_by' => $discountBy,
                                'commission_pct' => $commissionPct,
                                'marketer_comm' => $marketerComm,
                                'agent_comm' => $agentComm,
                                'balance_remaining' => $balanceRem,
                                'client_payment_status' => $statusNotes ?: $quickNotes,
                                'marketer_bank' => $mkBank,
                                'agent_bank' => $agBank,
                                'transactions' => $transactionsMeta,
                                'submitted_by_user' => $subUidFull > 0 ? $subUidFull : (int)($meta['submitted_by_user'] ?? 0),
                                'submitted_by_role' => $subRoleFull !== '' ? $subRoleFull : (string)($meta['submitted_by_role'] ?? ''),
                                'submitted_by_name' => ($subNameFull !== '' ? $subNameFull : $marketerName),
                                'marketer_name' => $marketerName,
                                'payment_reference' => $paymentRefView,
                                'payment_method' => $paymentMethodView
                            ];
                            $modalMetaJson = json_encode($fallbackMeta);
                        }
                        // Apply final fallback from modal meta for server-rendered summary row
                        if (isset($modalMetaJson) && is_string($modalMetaJson) && trim($modalMetaJson) !== '') {
                            $mm = json_decode($modalMetaJson, true);
                            if (is_array($mm)) {
                                if (($proj === '' || $proj === '-') && !empty($mm['project_desc'])) { $proj = (string)$mm['project_desc']; }
                                if ($dealSource === '' && !empty($mm['deal_source'])) { $dealSource = (string)$mm['deal_source']; }
                                if ($planType === '' && !empty($mm['plan_type'])) { $planType = (string)$mm['plan_type']; }
                                if ($marketerName === '' && !empty($mm['marketer_name'])) { $marketerName = (string)$mm['marketer_name']; }
                                if ($marketerName === '' && !empty($mm['submitted_by_name'])) { $marketerName = (string)$mm['submitted_by_name']; }
                                if (($dealSource === '' || $dealSource === '-') && !empty($mm['submitted_by_role'])) { $dealSource = ucfirst(strtolower((string)$mm['submitted_by_role'])); }
                                if ($amountOffered <= 0 && isset($mm['amount_offered'])) { $amountOffered = (float)$mm['amount_offered']; }
                                if ($amountPaidSoFar <= 0 && isset($mm['amount_paid_so_far'])) { $amountPaidSoFar = (float)$mm['amount_paid_so_far']; }
                                if ($discountAmount <= 0 && isset($mm['discount_amount'])) { $discountAmount = (float)$mm['discount_amount']; }
                                if ($commissionPct <= 0 && isset($mm['commission_pct'])) { $commissionPct = (float)$mm['commission_pct']; }
                                if ($balanceRem <= 0 && isset($mm['balance_remaining'])) { $balanceRem = (float)$mm['balance_remaining']; }
                                if ($statusNotes === '' && !empty($mm['client_payment_status'])) { $statusNotes = (string)$mm['client_payment_status']; }
                                if (empty($mkBank)) { $mkBank = is_array($mm['marketer_bank'] ?? null) ? $mm['marketer_bank'] : []; }
                                if (empty($agBank)) { $agBank = is_array($mm['agent_bank'] ?? null) ? $mm['agent_bank'] : []; }
                                if (empty($transactionsMeta)) { $transactionsMeta = is_array($mm['transactions'] ?? null) ? $mm['transactions'] : []; }
                            }
                        }
                        if (!is_string($dealSource) || trim($dealSource) === '' || $dealSource === '-') { $dealSource = 'Marketing'; }
                        if (!is_string($marketerName) || trim($marketerName) === '' || $marketerName === '-') {
                            if (isset($meta['submitted_by_name']) && trim((string)$meta['submitted_by_name']) !== '') { $marketerName = (string)$meta['submitted_by_name']; }
                            elseif (isset($meta['Submitted By']) && trim((string)$meta['Submitted By']) !== '') { $marketerName = (string)$meta['Submitted By']; }
                            elseif (isset($meta['submitted_by']) && trim((string)$meta['submitted_by']) !== '') { $marketerName = (string)$meta['submitted_by']; }
                            elseif (isset($meta['SUBMITTED BY']) && trim((string)$meta['SUBMITTED BY']) !== '') { $marketerName = (string)$meta['SUBMITTED BY']; }
                            elseif (isset($meta['created_by_name']) && trim((string)$meta['created_by_name']) !== '') { $marketerName = (string)$meta['created_by_name']; }
                            elseif (isset($row['submitted_by_name']) && is_string($row['submitted_by_name']) && trim($row['submitted_by_name']) !== '') { $marketerName = (string)$row['submitted_by_name']; }
                            elseif (isset($row['uploaded_by_name']) && is_string($row['uploaded_by_name']) && trim($row['uploaded_by_name']) !== '') { $marketerName = (string)$row['uploaded_by_name']; }
                        }
                        if (!is_string($marketerName) || trim($marketerName) === '' || $marketerName === '-') {
                            if (is_array($meta) && !empty($meta)) {
                                foreach ($meta as $kk=>$vv) {
                                    if (!is_string($vv) || trim($vv)==='') continue;
                                    $lk = strtolower(preg_replace('/[^a-z]/','', (string)$kk));
                                    if (strpos($lk,'submittedby')!==false || strpos($lk,'marketername')!==false || strpos($lk,'marketer')!==false || strpos($lk,'contactcentre')!==false || strpos($lk,'contactcenter')!==false) { $marketerName = trim((string)$vv); break; }
                                }
                            }
                        }
                        if (!is_string($marketerName) || trim($marketerName) === '' || $marketerName === '-') {
                            try {
                                if (colExists('deals_submit','marketer_name')) {
                                    $did = isset($row['deal_id']) ? (int)$row['deal_id'] : 0;
                                    if ($did > 0) {
                                        $qdss = $pdo->prepare("SELECT marketer_name, submitted_by FROM deals_submit WHERE id = ? LIMIT 1");
                                        $qdss->execute([$did]);
                                        $dsv = $qdss->fetch(PDO::FETCH_ASSOC) ?: [];
                                        if (!empty($dsv)) {
                                            if ($marketerName === '' && !empty($dsv['marketer_name'])) { $marketerName = (string)$dsv['marketer_name']; }
                                            if ($subNameFull === '' && !empty($dsv['submitted_by'])) { $subNameFull = (string)$dsv['submitted_by']; }
                                        }
                                    }
                                    if ((!is_string($marketerName) || trim($marketerName) === '') && isset($row['user_id']) && (int)$row['user_id'] > 0 && colExists('deals_submit','user_id')) {
                                        $qdss = $pdo->prepare("SELECT marketer_name, submitted_by FROM deals_submit WHERE user_id = ? ORDER BY id DESC LIMIT 1");
                                        $qdss->execute([(int)$row['user_id']]);
                                        $dsv = $qdss->fetch(PDO::FETCH_ASSOC) ?: [];
                                        if (!empty($dsv)) {
                                            if ($marketerName === '' && !empty($dsv['marketer_name'])) { $marketerName = (string)$dsv['marketer_name']; }
                                            if ($subNameFull === '' && !empty($dsv['submitted_by'])) { $subNameFull = (string)$dsv['submitted_by']; }
                                        }
                                    }
                                    if ((!is_string($marketerName) || trim($marketerName) === '') && isset($row['created_at']) && is_string($row['created_at']) && trim($row['created_at']) !== '' && colExists('deals_submit','created_at')) {
                                        $cat = (string)$row['created_at'];
                                        if ($cat !== '') {
                                            if (isset($row['user_id']) && (int)$row['user_id'] > 0 && colExists('deals_submit','user_id')) {
                                                $qdss = $pdo->prepare("SELECT marketer_name, submitted_by FROM deals_submit WHERE user_id = ? AND created_at BETWEEN DATE_SUB(?, INTERVAL 2 HOUR) AND DATE_ADD(?, INTERVAL 2 HOUR) ORDER BY id DESC LIMIT 1");
                                                $qdss->execute([(int)$row['user_id'], $cat, $cat]);
                                            } else {
                                                $qdss = $pdo->prepare("SELECT marketer_name, submitted_by FROM deals_submit WHERE created_at BETWEEN DATE_SUB(?, INTERVAL 2 HOUR) AND DATE_ADD(?, INTERVAL 2 HOUR) ORDER BY id DESC LIMIT 1");
                                                $qdss->execute([$cat, $cat]);
                                            }
                                            $dsv = $qdss->fetch(PDO::FETCH_ASSOC) ?: [];
                                            if (!empty($dsv)) {
                                                if ($marketerName === '' && !empty($dsv['marketer_name'])) { $marketerName = (string)$dsv['marketer_name']; }
                                                if ($subNameFull === '' && !empty($dsv['submitted_by'])) { $subNameFull = (string)$dsv['submitted_by']; }
                                            }
                                        }
                                    }
                                }
                            } catch (Throwable $eDSN) {}
                        }
                        // Finalize Submitted By just before render to avoid blanks
                        $sbNameFinal = '';
                        if (!empty($subNameFull)) { $sbNameFinal = (string)$subNameFull; }
                        elseif (!empty($meta['submitted_by_name'])) { $sbNameFinal = (string)$meta['submitted_by_name']; }
                        elseif (!empty($meta['Submitted By'])) { $sbNameFinal = (string)$meta['Submitted By']; }
                        elseif (!empty($meta['submitted_by'])) { $sbNameFinal = (string)$meta['submitted_by']; }
                        elseif (!empty($meta['SUBMITTED BY'])) { $sbNameFinal = (string)$meta['SUBMITTED BY']; }
                        elseif (!empty($meta['uploaded_by_name'])) { $sbNameFinal = (string)$meta['uploaded_by_name']; }
                        elseif (!empty($meta['created_by_name'])) { $sbNameFinal = (string)$meta['created_by_name']; }
                        elseif (isset($row['submitted_by_name']) && is_string($row['submitted_by_name']) && trim($row['submitted_by_name'])!=='') { $sbNameFinal = (string)$row['submitted_by_name']; }
                        elseif (isset($row['uploaded_by_name']) && is_string($row['uploaded_by_name']) && trim($row['uploaded_by_name'])!=='') { $sbNameFinal = (string)$row['uploaded_by_name']; }
                        elseif ($marketerName !== '') { $sbNameFinal = $marketerName; }
                        if ($sbNameFinal === '' && is_array($meta) && !empty($meta)) {
                            foreach ($meta as $kk=>$vv) {
                                if (!is_string($vv) || trim($vv)==='') continue;
                                $lk = strtolower(preg_replace('/[^a-z]/','', (string)$kk));
                                if (
                                    strpos($lk,'submittedby')!==false || strpos($lk,'marketername')!==false || strpos($lk,'marketer')!==false
                                    || strpos($lk,'contactcentre')!==false || strpos($lk,'contactcenter')!==false
                                    || strpos($lk,'salesagent')!==false || strpos($lk,'salesrep')!==false
                                    || ($lk==='agent' || strpos($lk,'agentname')!==false) || strpos($lk,'staff')!==false
                                    || strpos($lk,'uploadedby')!==false || strpos($lk,'createdby')!==false
                                ) { $sbNameFinal = trim((string)$vv); break; }
                            }
                        }
                        if ($sbNameFinal === '') {
                            $uidTry = (int)($row['user_id'] ?? 0);
                            if ($uidTry > 0) {
                                try {
                                    $dealName = '';
                                    if (colExists('deals','client_id') && colExists('deals','marketer_name')) {
                                        $qdn = $pdo->prepare("SELECT marketer_name FROM deals WHERE client_id = ? AND marketer_name IS NOT NULL AND TRIM(marketer_name) <> '' ORDER BY id DESC LIMIT 1");
                                        $qdn->execute([$uidTry]);
                                        $dealName = (string)($qdn->fetchColumn() ?: '');
                                    }
                                    if ($dealName === '' && colExists('deals','user_id') && colExists('deals','marketer_name')) {
                                        $qdn = $pdo->prepare("SELECT marketer_name FROM deals WHERE user_id = ? AND marketer_name IS NOT NULL AND TRIM(marketer_name) <> '' ORDER BY id DESC LIMIT 1");
                                        $qdn->execute([$uidTry]);
                                        $dealName = (string)($qdn->fetchColumn() ?: '');
                                    }
                                    if ($dealName !== '') { $sbNameFinal = $dealName; }
                                } catch (Throwable $eDN) {}
                            }
                        }
                        $sbRoleFinal = '';
                        if (!empty($subRoleFull)) { $sbRoleFinal = (string)$subRoleFull; }
                        elseif (!empty($meta['submitted_by_role'])) { $sbRoleFinal = (string)$meta['submitted_by_role']; }
                        elseif (!empty($dealSource)) { $sbRoleFinal = strtolower((string)$dealSource); }
                        if ($sbNameFinal !== '') { $submittedBy = $sbNameFinal; }

                    ?>
                    <?php
                        $rowAmt = (float)($row['amount'] ?? 0);
                        $rowStatusRaw = strtolower((string)($row['status'] ?? ''));
                        $rowIsPending = in_array($rowStatusRaw, $queueStatuses, true);
                        $rowStatusUi = $rowIsPending ? 'pending' : ($rowStatusRaw !== '' ? $rowStatusRaw : 'unknown');
                        $rowPrioClass = '';
                        $rowSelectable = $canVerify && $rowIsPending;
                        $rowUploadTs = 0;
                        try { $rowUploadTs = (int)strtotime((string)($row['created_at'] ?? '')); } catch (Throwable $eT) { $rowUploadTs = 0; }
                        if ($rowUploadTs > (time() + 86400)) { $rowUploadTs = 0; }
                    ?>
                    <tr class="verif-row <?= htmlspecialchars($rowPrioClass) ?>" data-status="<?= htmlspecialchars($rowStatusUi) ?>" data-amount="<?= htmlspecialchars((string)$rowAmt) ?>" data-upload-ts="<?= (int)$rowUploadTs ?>" data-id="<?= (int)$row['id'] ?>">
                        <td class="px-2" data-label="Select"><input type="checkbox" class="form-check-input row-check" data-id="<?= (int)$row['id'] ?>" <?= $rowSelectable ? '' : 'disabled' ?>></td>
                        <td data-label="Payment ID"><?= (int)$row['id'] ?></td>
                        <td data-label="Client Name">
                            <?php
                            $displayClient = $clientNameMeta ?: ($row['client_name'] ?? 'Unknown');
                            $linkUserId = (int)($row['user_id'] ?? 0);
                            if ($linkUserId <= 0) {
                                $metaClientId = isset($meta['client_id']) ? (int)$meta['client_id'] : 0;
                                if ($metaClientId > 0) { $linkUserId = $metaClientId; }
                            }
                            if ($linkUserId <= 0 && !empty($meta['client_email']) && colExists('users','email')) {
                                try {
                                    $qe = $pdo->prepare("SELECT id FROM users WHERE email = ? LIMIT 1");
                                    $qe->execute([(string)$meta['client_email']]);
                                    $linkUserId = (int)($qe->fetchColumn() ?: 0);
                                } catch (Throwable $eE) {}
                            }
                            if ($linkUserId <= 0 && $displayClient !== 'Unknown' && colExists('users','name')) {
                                try {
                                    $qn = $pdo->prepare("SELECT id FROM users WHERE name = ? ORDER BY id DESC LIMIT 1");
                                    $qn->execute([$displayClient]);
                                    $linkUserId = (int)($qn->fetchColumn() ?: 0);
                                } catch (Throwable $eN) {}
                            }
                            if (($displayClient === '' || $displayClient === 'Unknown') && $linkUserId > 0 && colExists('users','name')) {
                                try { $qnm = $pdo->prepare("SELECT name FROM users WHERE id = ? LIMIT 1"); $qnm->execute([$linkUserId]); $nm = (string)($qnm->fetchColumn() ?: ''); if ($nm !== '') { $displayClient = $nm; } } catch (Throwable $eU) {}
                            }
                            if (($displayClient === '' || $displayClient === 'Unknown') && !empty($meta['client_name'])) { $displayClient = (string)$meta['client_name']; }
                            ?>
                            <?= htmlspecialchars($displayClient) ?>
                            <?php if ($linkUserId > 0): ?>
                                <a href="client-profile.php?client_id=<?= (int)$linkUserId ?>" target="_blank" class="ms-2 small text-decoration-none" title="Open client profile"><i class="fa-solid fa-user"></i></a>
                            <?php endif; ?>
                        </td>
                        <td data-label="Submitted By"><?= htmlspecialchars($submittedBy ?: '-') ?></td>
                        <td data-label="Payment Type"><?= htmlspecialchars($displayPaymentType ?: ($row['payment_type'] ?? '-')) ?></td>
                        <td data-label="Plan">
                            <?php
                                $planRaw = $planType;
                                if ($planRaw === '' && isset($row['plan_type'])) { $planRaw = (string)$row['plan_type']; }
                                if ($planRaw === '' && isset($row['payment_plan'])) { $planRaw = (string)$row['payment_plan']; }
                                if ($planRaw === '' && isset($meta['payment_plan'])) { $planRaw = (string)$meta['payment_plan']; }
                                $planNorm = strtolower(trim((string)$planRaw));
                                $planNorm = str_replace([' ', '-'], '_', $planNorm);
                                $planNorm = preg_replace('/_+/', '_', $planNorm);
                                $planLabel = '-';
                                if ($planNorm !== '') {
                                    if (in_array($planNorm, ['full', 'full_payment', 'outright', 'one_time', 'one_off', 'single'], true)) {
                                        $planLabel = 'Full Payment';
                                    } elseif (preg_match('/(\d+)_?months?/', $planNorm, $m)) {
                                        $planLabel = (int)$m[1] . ' Months';
                                    } else {
                                        $planLabel = ucwords(str_replace('_', ' ', $planNorm));
                                    }
                                }
                                $startRaw = '';
                                if (!empty($meta['installment_start_date'])) { $startRaw = (string)$meta['installment_start_date']; }
                                $startDisp = '';
                                if ($startRaw !== '' && preg_match('/^\d{4}-\d{2}-\d{2}/', $startRaw)) {
                                    try { $startDisp = date('M d, Y', strtotime(substr($startRaw, 0, 10))); } catch (Throwable $e) { $startDisp = ''; }
                                }
                            ?>
                            <div class="fw-semibold small"><?= htmlspecialchars($planLabel) ?></div>
                            <?php if ($startDisp !== '' && $planLabel !== 'Full Payment'): ?>
                                <div class="text-muted small">Start: <?= htmlspecialchars($startDisp) ?></div>
                            <?php endif; ?>
                        </td>
                        <td data-label="Amount">
                            ₦<?= number_format((float)($row['amount'] ?? 0)) ?>
                        </td>
                        <td data-label="Receipt">
                            <?php
                            $rcp = (string)($row['receipt_file'] ?? '');
                            if ($rcp !== '') {
                                $tmp = trim($rcp);
                                $href = $tmp;
                                if ($tmp !== '' && !preg_match('#^https?://#i', $tmp)) {
                                    $norm = str_replace('\\', '/', $tmp);
                                    $pos = stripos($norm, '/uploads/');
                                    if ($pos === false) { $pos = stripos($norm, 'uploads/'); }
                                    if ($pos !== false) {
                                        $norm = substr($norm, $pos);
                                        if ($norm !== '' && $norm[0] !== '/') { $norm = '/' . $norm; }
                                    }
                                    $baseAbs = function_exists('buildAbsBaseUrl') ? (string)buildAbsBaseUrl() : (isset($absBaseUrl) ? (string)$absBaseUrl : '/');
                                    $href = function_exists('normalizeUrlPath') ? normalizeUrlPath($norm, $baseAbs) : $norm;
                                }
                                ?>
                                <a href="<?= htmlspecialchars($href) ?>" target="_blank">View Receipt</a>
                                <?php
                            } else {
                                ?>
                                -
                                <?php
                            }
                            ?>
                        </td>
                        <td data-label="Upload Date"><?= date('M d, Y', strtotime($row['created_at'] ?? date('Y-m-d'))) ?></td>
                        <?php $st = strtolower((string)($row['status'] ?? '')); $badgeClass = ($st === 'approved' ? 'badge-status-approved' : ($st === 'rejected' ? 'badge-status-rejected' : 'badge-status-pending')); $stLabel = (in_array($st, $queueStatuses, true) ? 'Pending' : ucfirst($st)); ?>
                        <td data-label="Status"><span class="badge fin-status-badge <?= $badgeClass ?>"><?= htmlspecialchars($stLabel) ?></span></td>
                        <td data-label="View Details">
                                <?php
                                    $cfData = '{}'; $cfReceipt = ''; $cfStatus = '';
                                    try {
                                        $uidCF = (int)($row['user_id'] ?? 0);
                                        if ($uidCF > 0) {
                                            $qcf = $pdo->prepare("SELECT form_data, receipt_path, status FROM client_forms WHERE client_id = ? ORDER BY created_at DESC LIMIT 1");
                                            $qcf->execute([$uidCF]);
                                            $cfRow = $qcf->fetch(PDO::FETCH_ASSOC) ?: [];
                                            $cfData = isset($cfRow['form_data']) && is_string($cfRow['form_data']) ? $cfRow['form_data'] : '{}';
                                            $cfReceipt = (string)($cfRow['receipt_path'] ?? '');
                                            $cfStatus = (string)($cfRow['status'] ?? '');
                                        }
                                            if ((trim($cfData) === '' || trim($cfData) === '{}' || trim($cfData) === 'null') && colExists('client_forms','receipt_path')) {
                                                $rcpTry = (string)($row['receipt_file'] ?? '');
                                                if ($rcpTry === '' && isset($row['proof_file'])) { $rcpTry = (string)$row['proof_file']; }
                                                if ($rcpTry !== '') {
                                                    $qcf2 = $pdo->prepare("SELECT form_data, receipt_path, status FROM client_forms WHERE receipt_path = ? ORDER BY created_at DESC LIMIT 1");
                                                    $qcf2->execute([$rcpTry]);
                                                    $cfRow2 = $qcf2->fetch(PDO::FETCH_ASSOC) ?: [];
                                                    if (!empty($cfRow2)) {
                                                        $cfData = isset($cfRow2['form_data']) && is_string($cfRow2['form_data']) ? $cfRow2['form_data'] : $cfData;
                                                        $cfReceipt = (string)($cfRow2['receipt_path'] ?? $cfReceipt);
                                                        $cfStatus = (string)($cfRow2['status'] ?? $cfStatus);
                                                    } else {
                                                        $base = basename($rcpTry);
                                                        if ($base !== '') {
                                                            $qcf3 = $pdo->prepare("SELECT form_data, receipt_path, status FROM client_forms WHERE receipt_path LIKE ? ORDER BY created_at DESC LIMIT 1");
                                                            $qcf3->execute(['%'.$base]);
                                                            $cfRow3 = $qcf3->fetch(PDO::FETCH_ASSOC) ?: [];
                                                            if (!empty($cfRow3)) {
                                                                $cfData = isset($cfRow3['form_data']) && is_string($cfRow3['form_data']) ? $cfRow3['form_data'] : $cfData;
                                                                $cfReceipt = (string)($cfRow3['receipt_path'] ?? $cfReceipt);
                                                                $cfStatus = (string)($cfRow3['status'] ?? $cfStatus);
                                                            }
                                                        }
                                                    }
                                                }
                                            }
                                    } catch (Throwable $eCF) {}
                                    $cfB64 = base64_encode($cfData);
                                ?>
                                <?php
                                    $basePath = rtrim(dirname($_SERVER['SCRIPT_NAME'] ?? '/'), '/\\');
                                    $pmB64 = base64_encode(isset($modalMetaJson) ? $modalMetaJson : '{}');
                                    // Prefer receipt from client_forms; if missing, fall back to payments receipt_file or proof_file
                                    $receiptForBtn = $cfReceipt;
                                    if ($receiptForBtn === '') {
                                        $receiptForBtn = (string)($row['receipt_file'] ?? '');
                                        if ($receiptForBtn === '' && isset($row['proof_file'])) { $receiptForBtn = (string)$row['proof_file']; }
                                    }
                                    $history = [[
                                        'id' => (int)($row['id'] ?? 0),
                                        'amount' => $row['amount'] ?? null,
                                        'payment_type' => (string)($row['payment_type_raw'] ?? ($row['payment_method'] ?? ($row['type'] ?? 'Payment'))),
                                        'status' => (string)($row['status'] ?? ''),
                                        'created_at' => (string)($row['created_at'] ?? '')
                                    ]];
                                    $histB64 = base64_encode(json_encode($history));
                                ?>
                                <button type="button"
                                        class="btn btn-sm btn-outline-primary"
                                        data-bs-toggle="modal"
                                        data-bs-target="#financeClientInfoModal"
                                        data-pm-id="<?= (int)($row['id'] ?? 0) ?>"
                                        data-pay-status="<?= htmlspecialchars((string)($row['status'] ?? '')) ?>"
                                        data-pay-date="<?= htmlspecialchars((string)($row['created_at'] ?? ($row['date'] ?? ''))) ?>"
                                        data-client="<?= htmlspecialchars($row['client_name'] ?? '') ?>"
                                        data-email="<?= htmlspecialchars($clientEmailView ?? '') ?>"
                                        data-amount="<?= htmlspecialchars((string)($row['amount'] ?? '0')) ?>"
                                        data-receipt="<?= htmlspecialchars($receiptForBtn) ?>"
                                        data-form="<?= htmlspecialchars($cfB64) ?>"
                                        data-status="<?= htmlspecialchars($cfStatus) ?>"
                                        data-base="<?= htmlspecialchars($basePath) ?>"
                                        data-payment="<?= htmlspecialchars($pmB64) ?>"
                                        data-submitter="<?= htmlspecialchars($submittedBy ?: '-') ?>"
                                        data-history="<?= htmlspecialchars($histB64) ?>"
                                        data-user-id="<?= (int)($row['user_id'] ?? 0) ?>"
                                        data-client-email="<?= htmlspecialchars($clientEmailView ?? '') ?>">
                                    <i class="fa-solid fa-circle-info me-1"></i>View Details
                                </button>
                        </td>
                        <td data-label="Actions">
                            <?php $stL = strtolower((string)($row['status'] ?? '')); $isRev = (int)($row['is_reversed'] ?? 0); ?>
                            <?php if ($canApprovePayments && in_array($stL, $queueStatuses, true)): ?>
                                <div class="fin-action-buttons">
                                    <button type="button" class="btn btn-sm btn-success approve-btn" data-id="<?= (int)$row['id'] ?>"><i class="fa-solid fa-check me-1"></i>Approve</button>
                                    <button type="button" class="btn btn-sm btn-danger reject-btn" data-id="<?= (int)$row['id'] ?>"><i class="fa-solid fa-xmark me-1"></i>Reject</button>
                                </div>
                            <?php elseif ($canApprovePayments && $stL === 'approved' && $isRev === 0): ?>
                                <div class="fin-action-buttons">
                                    <button type="button" class="btn btn-sm btn-outline-warning reverse-btn" data-id="<?= (int)$row['id'] ?>"><i class="fa-solid fa-rotate-left me-1"></i>Reverse</button>
                                </div>
                            <?php else: ?>
                                -
                            <?php endif; ?>
                        </td>
                    </tr>
                    <tr class="collapse verif-collapse-row" id="<?= $collapseId ?>">
                        <td colspan="12">
                            <div class="border rounded p-3 bg-light">
                                <div class="row g-3">
                                    <div class="col-12">
                                        <div class="small text-uppercase text-muted fw-semibold mb-2">Client</div>
                                        <div class="row g-3">
                                            <div class="col-md-6"><div class="small text-muted">Client</div><div class="fw-semibold"><?= htmlspecialchars($clientNameMeta ?: ($row['client_name'] ?? 'Unknown')) ?></div></div>
                                            <div class="col-md-6"><div class="small text-muted">Client Email</div><div class="fw-semibold"><?= htmlspecialchars($clientEmailView ?: '-') ?></div></div>
                                            <div class="col-md-6"><div class="small text-muted">Submitted By</div><div class="fw-semibold"><?= htmlspecialchars($submittedBy ?: ($marketerName ?: '-')) ?></div></div>
                                        </div>
                                    </div>
                                    <div class="col-12">
                                        <div class="small text-uppercase text-muted fw-semibold mb-2">Deal</div>
                                        <div class="row g-3">
                                            <div class="col-md-6"><div class="small text-muted">Project / Property</div><div class="fw-semibold"><?= htmlspecialchars($proj !== '-' ? $proj : ($quickProperty ?: '-')) ?></div></div>
                                            
                                            <div class="col-md-3"><div class="small text-muted">Plan</div><div class="fw-semibold"><?= htmlspecialchars($planType ?: '-') ?></div></div>
                                            <div class="col-md-6"><div class="small text-muted">Marketer or Contact Centre Name</div><div class="fw-semibold"><?= htmlspecialchars($marketerName ?: '-') ?></div></div>
                                        </div>
                                    </div>
                                    <div class="col-12">
                                        <div class="small text-uppercase text-muted fw-semibold mb-2">Payment</div>
                                        <div class="row g-3">
                                            <div class="col-md-3"><div class="small text-muted">Amount Paid Now</div><div class="fw-semibold"><?= formatCurrency((float)($row['amount'] ?? 0)) ?></div></div>
                                            <div class="col-md-3"><div class="small text-muted">Payment Reference</div><div class="fw-semibold"><?= htmlspecialchars($paymentRefView ?: '-') ?></div></div>
                                            <div class="col-md-3"><div class="small text-muted">Payment Method</div><div class="fw-semibold"><?= htmlspecialchars($paymentMethodView ?: '-') ?></div></div>
                                            <div class="col-md-12"><div class="small text-muted">Payment Status / Notes</div><div class="fw-semibold"><?= htmlspecialchars($statusNotes ?: ($quickNotes ?: '-')) ?></div></div>
                                        </div>
                                    </div>
                                    <div class="col-12">
                                        <div class="small text-uppercase text-muted fw-semibold mb-2">Financials</div>
                                        <div class="row g-3">
                                            <div class="col-md-3"><div class="small text-muted">Amount Offered</div><div class="fw-semibold"><?= formatCurrency($amountOffered) ?></div></div>
                                            <div class="col-md-3"><div class="small text-muted">Paid So Far</div><div class="fw-semibold"><?= formatCurrency($amountPaidSoFar) ?></div></div>
                                            <div class="col-md-3"><div class="small text-muted">Discount</div><div class="fw-semibold"><?= formatCurrency($discountAmount) ?></div></div>
                                            <div class="col-md-3"><div class="small text-muted">Discount Approved By</div><div class="fw-semibold"><?= htmlspecialchars($discountBy ?: '-') ?></div></div>
                                            <div class="col-md-3"><div class="small text-muted">Commission %</div><div class="fw-semibold"><?= htmlspecialchars(number_format($commissionPct, 2)) ?></div></div>
                                            <div class="col-md-3"><div class="small text-muted">Marketer Commission</div><div class="fw-semibold"><?= formatCurrency($marketerComm) ?></div></div>
                                            <div class="col-md-3"><div class="small text-muted">Agent Commission</div><div class="fw-semibold"><?= formatCurrency($agentComm) ?></div></div>
                                            <div class="col-md-3"><div class="small text-muted">Balance Remaining</div><div class="fw-semibold"><?= formatCurrency($balanceRem) ?></div></div>
                                        </div>
                                    </div>
                                    <div class="col-12">
                                        <div class="small text-uppercase text-muted fw-semibold mb-2">Bank Details</div>
                                        <div class="row g-3">
                                            <div class="col-md-6">
                                                <div class="border rounded p-2 h-100">
                                                    <div class="small text-muted">Marketer Bank</div>
                                                    <div class="fw-semibold mb-2"><?= htmlspecialchars(($mkBank['bank'] ?? '').' / '.($mkBank['acc_name'] ?? '').' / '.($mkBank['acc_no'] ?? '')) ?></div>
                                                    <div class="row g-2">
                                                        <div class="col-md-4"><div class="small text-muted">Account Number</div><div class="fw-semibold"><?= htmlspecialchars($mkBank['acc_no'] ?? '') ?></div></div>
                                                        <div class="col-md-4"><div class="small text-muted">Bank Name</div><div class="fw-semibold"><?= htmlspecialchars($mkBank['bank'] ?? '') ?></div></div>
                                                        <div class="col-md-4"><div class="small text-muted">Account Name</div><div class="fw-semibold"><?= htmlspecialchars($mkBank['acc_name'] ?? '') ?></div></div>
                                                    </div>
                                                </div>
                                            </div>
                                            <div class="col-md-6">
                                                <div class="border rounded p-2 h-100">
                                                    <div class="small text-muted">Agent Bank</div>
                                                    <div class="fw-semibold mb-2"><?= htmlspecialchars(($agBank['bank'] ?? '').' / '.($agBank['acc_name'] ?? '').' / '.($agBank['acc_no'] ?? '')) ?></div>
                                                    <div class="row g-2">
                                                        <div class="col-md-4"><div class="small text-muted">Account Number</div><div class="fw-semibold"><?= htmlspecialchars($agBank['acc_no'] ?? '') ?></div></div>
                                                        <div class="col-md-4"><div class="small text-muted">Bank Name</div><div class="fw-semibold"><?= htmlspecialchars($agBank['bank'] ?? '') ?></div></div>
                                                        <div class="col-md-4"><div class="small text-muted">Account Name</div><div class="fw-semibold"><?= htmlspecialchars($agBank['acc_name'] ?? '') ?></div></div>
                                                    </div>
                                                </div>
                                            </div>
                                        </div>
                                    </div>
                                    <div class="col-12">
                                        <div class="small text-uppercase text-muted fw-semibold mb-2">Transaction History</div>
                                        <?php if (empty($transactionsMeta)): ?>
                                            <div class="text-muted">-</div>
                                        <?php else: ?>
                                            <div class="table-responsive">
                                                <table class="table table-sm">
                                                    <thead><tr><th>Date</th><th class="text-end">Amount</th></tr></thead>
                                                    <tbody>
                                                        <?php foreach ($transactionsMeta as $t): ?>
                                                        <tr><td><?= htmlspecialchars($t['date']) ?></td><td class="text-end"><?= formatCurrency($t['amount'] ?? 0) ?></td></tr>
                                                        <?php endforeach; ?>
                                                    </tbody>
                                                </table>
                                            </div>
                                        <?php endif; ?>
                                    </div>
                                </div>
                            </div>
                        </td>
                    </tr>
                    <?php endforeach; ?>
                    <?php $hasRows = count($transactionsPage) > 0; ?>
                    <tr id="verifyEmptyState" class="<?= $hasRows ? 'd-none' : '' ?>">
                        <td colspan="12" class="text-muted text-center py-4">No pending approvals at the moment</td>
                    </tr>
                </tbody>
            </table>
        </div>
        </div>
        <?php if ($totalPages > 1): ?>
            <?php
                $start = $totalRows > 0 ? ($offset + 1) : 0;
                $end = min($totalRows, $offset + count($transactionsPage));
                $qsBase = $_GET;
                unset($qsBase['page']);
                $makeUrl = function(int $p) use ($qsBase) {
                    $q = $qsBase;
                    $q['page'] = $p;
                    return 'finance-payments.php?' . http_build_query($q);
                };
                $window = 2;
                $from = max(1, $page - $window);
                $to = min($totalPages, $page + $window);
                if ($to - $from < ($window * 2)) {
                    $from = max(1, $to - ($window * 2));
                    $to = min($totalPages, $from + ($window * 2));
                }
            ?>
            <div class="d-flex justify-content-between align-items-center flex-wrap gap-2 p-3 border-top bg-white">
                <div class="small text-muted">Showing <?= (int)$start ?>–<?= (int)$end ?> of <?= (int)$totalRows ?></div>
                <nav aria-label="Verification pagination">
                    <ul class="pagination pagination-sm mb-0">
                        <li class="page-item <?= $page <= 1 ? 'disabled' : '' ?>">
                            <a class="page-link" href="<?= htmlspecialchars($makeUrl(max(1, $page - 1))) ?>">Prev</a>
                        </li>
                        <?php for ($p = $from; $p <= $to; $p++): ?>
                            <li class="page-item <?= $p === $page ? 'active' : '' ?>">
                                <a class="page-link" href="<?= htmlspecialchars($makeUrl($p)) ?>"><?= (int)$p ?></a>
                            </li>
                        <?php endfor; ?>
                        <li class="page-item <?= $page >= $totalPages ? 'disabled' : '' ?>">
                            <a class="page-link" href="<?= htmlspecialchars($makeUrl(min($totalPages, $page + 1))) ?>">Next</a>
                        </li>
                    </ul>
                </nav>
            </div>
        <?php endif; ?>
        
    <div class="modal fade" id="financeClientInfoModal" tabindex="-1" aria-labelledby="financeClientInfoLabel" aria-hidden="true" data-bs-backdrop="false" data-bs-keyboard="true">
        <div class="modal-dialog modal-xl modal-dialog-scrollable">
            <div class="modal-content modal-premium">
                <div class="modal-header">
                    <div class="d-flex align-items-center gap-3">
                        <img id="finAvatarImg" src="" alt="" style="width:56px;height:56px;border-radius:50%;object-fit:cover;display:none;">
                        <div>
                            <h5 class="modal-title" id="financeClientInfoLabel">Client Information</h5>
                            <div class="small text-muted" id="finEmailText"></div>
                        </div>
                        <span class="badge bg-light text-dark border ms-3" id="finStatusBadge"></span>
                        <span class="badge bg-light text-dark border ms-2" id="finPlanBadge" style="display:none;"></span>
                        <button type="button" class="btn btn-sm btn-outline-light ms-auto" id="finTransBtn">Transactions</button>
                    </div>
                    <button type="button" class="btn-close btn-close-white" data-bs-dismiss="modal" aria-label="Close"></button>
                </div>
                <div class="modal-body">
                    <div class="row g-3">
                        <div class="col-12">
                            <div class="card shadow-sm">
                                <div class="card-header bg-white d-flex align-items-center justify-content-between">
                                    <strong>This Payment (Clicked)</strong>
                                    <span class="small text-muted" id="finPaymentMeta"></span>
                                </div>
                                <div class="card-body" id="finPaymentSummary"><div class="text-muted">Loading…</div></div>
                            </div>
                        </div>
                    </div>
                    <div class="row g-3">
                        <div class="col-md-6">
                            <div class="card shadow-sm">
                                <div class="card-header bg-white"><strong>Profile & Contact</strong></div>
                                <div class="card-body" id="finDetailsProfile"><div class="text-muted">Loading…</div></div>
                            </div>
                        </div>
                        <div class="col-md-6">
                            <div class="card shadow-sm">
                                <div class="card-header bg-white"><strong>Attachments</strong></div>
                                <div class="card-body" id="finDetailsAttachments"><div class="text-muted">Loading…</div></div>
                            </div>
                        </div>
                    </div>
                    <div class="mt-3">
                        <div class="card shadow-sm">
                            <div class="card-header bg-white d-flex align-items-center justify-content-between">
                                <strong>Payment History</strong>
                                <span class="small text-muted" id="finTransCount"></span>
                            </div>
                            <div class="card-body" id="finTransHistory"><div class="text-muted">Loading…</div></div>
                        </div>
                    </div>
                    <div class="mt-3">
                        <div class="card shadow-sm">
                            <div class="card-header bg-white"><strong>Application Data</strong></div>
                            <div class="card-body" id="finDetailsData"><div class="text-muted">Loading…</div></div>
                        </div>
                    </div>
                </div>
                <div class="modal-footer">
                    <button type="button" class="btn btn-outline-secondary" data-bs-dismiss="modal">Close</button>
                </div>
            </div>
        </div>
        <style>
            .modal { z-index: 1065 !important; }
            .modal-backdrop { z-index: 1040 !important; }
            .modal-content.modal-premium { border-radius: 24px; background: #ffffff; border: 6px solid transparent; background-image: linear-gradient(#ffffff, #ffffff), linear-gradient(135deg, #001F3F, #2ECC40); background-origin: border-box; background-clip: padding-box, border-box; box-shadow: 0 40px 80px rgba(0,31,63,.28); overflow: hidden; }
            .modal-content.modal-premium .modal-header { background: linear-gradient(135deg, rgba(0,31,63,.95), rgba(46,204,64,.85)); color: #fff; border-bottom: 0; position: sticky; top: 0; z-index: 1060; }
            .modal-content.modal-premium .modal-title { font-weight: 700; letter-spacing: .3px; }
            .modal-content.modal-premium .modal-header .modal-title { color: #ffffff !important; }
            .modal-content.modal-premium .btn { border-radius: 10px; }
            .modal-content.modal-premium .btn-close { filter: invert(1); opacity: .85; }
            #financeClientInfoModal { pointer-events: none; }
            #financeClientInfoModal .modal-dialog { pointer-events: auto; max-width: min(1000px, 94vw); margin: 0; position: fixed; left: 50%; top: 50%; transform: translate(-50%, -50%); }
            #financeClientInfoModal .modal-dialog.draggable { transform: none; }
            #financeClientInfoModal .modal-content { display: flex; flex-direction: column; max-height: 70vh; overflow: visible !important; }
            #financeClientInfoModal .modal-body { overflow-y: auto; -webkit-overflow-scrolling: touch; }
            .modal-backdrop, .modal-backdrop.fade.show { display: none !important; }
            #financeClientInfoModal .modal-footer { position: static; background: #fff; border-top: 1px solid #e9ecef; flex-shrink: 0; }
            #financeClientInfoModal .card-body img { max-width: 100%; height: auto; }
            .kv-table th, .kv-table td { vertical-align: top; word-break: break-word; white-space: normal; }
            .kv-table td { overflow-wrap: anywhere; }
            @media (max-width: 576px) { #financeClientInfoModal .modal-dialog { margin-top: 0; } #financeClientInfoModal .modal-content { max-height: 80vh; } }
        </style>
        <script>
        document.getElementById('financeClientInfoModal').addEventListener('shown.bs.modal', function (ev) {
            var mb = document.querySelector('#financeClientInfoModal .modal-body'); if (mb) { mb.scrollTop = 0; }
            try {
                var dlg0 = document.querySelector('#financeClientInfoModal .modal-dialog');
                if (dlg0) { dlg0.classList.remove('draggable'); dlg0.style.left=''; dlg0.style.top=''; }
                document.body.style.overflow = 'auto';
                document.body.classList.remove('modal-open');
                document.body.style.paddingRight = '';
            } catch(e){}
            var btn = ev.relatedTarget;
            var client = btn.getAttribute('data-client') || '';
            var email = btn.getAttribute('data-email') || '';
            var pmid = btn.getAttribute('data-pm-id') || '';
            var uid = btn.getAttribute('data-user-id') || '';
            var cemail = btn.getAttribute('data-client-email') || '';
            var amount = btn.getAttribute('data-amount') || '';
            var receipt = btn.getAttribute('data-receipt') || '';
            var formB64 = btn.getAttribute('data-form') || '';
            var status = btn.getAttribute('data-status') || '';
            var payStatus0 = btn.getAttribute('data-pay-status') || '';
            var payDate0 = btn.getAttribute('data-pay-date') || '';
            var base = btn.getAttribute('data-base') || '';
            var pmB64 = btn.getAttribute('data-payment') || '';
            var submitter = btn.getAttribute('data-submitter') || '';
            var histB64 = btn.getAttribute('data-history') || '';
            var data = {};
            var pm = {};
            var pmSubmission = {};
            var hist = [];
            try {
                var smallForm = formB64 && formB64.length < 150000;
                var smallPm = pmB64 && pmB64.length < 150000;
                var smallHist = histB64 && histB64.length < 120000;
                if (smallForm) { try { data = JSON.parse(atob(formB64)); } catch(e){} }
                if (smallPm) { try { pm = JSON.parse(atob(pmB64)); } catch(e){} }
                if (smallHist) { try { hist = JSON.parse(atob(histB64)); } catch(e){} }
            } catch(eParse) { data = {}; pm = {}; hist = []; }
            var initialRendered = false;
            function renderAll(){
                function valFromKeys(obj, keys){ for (var i=0;i<keys.length;i++){ var k = keys[i]; var v = (obj && obj[k]!=null) ? String(obj[k]) : ''; if (v.trim()!=='') return v; } return ''; }
                var avatar = valFromKeys(data, ['passport_photo_path','passport_photo','passportPhotoPath','passportPhoto','passport','passport_url']);
                if (avatar && !/^https?:\/\//i.test(avatar)) { avatar = base + '/' + avatar.replace(/^\/+/, ''); }
                var avatarImg = document.getElementById('finAvatarImg');
                if (avatar && avatarImg) { avatarImg.src = avatar; avatarImg.style.display = 'block'; } else { if (avatarImg) { avatarImg.style.display = 'none'; } }
                var emEl = document.getElementById('finEmailText'); if (emEl) { emEl.textContent = email || ''; }
                var stEl = document.getElementById('finStatusBadge'); if (stEl) { stEl.textContent = status || ''; }
                function pick(){ for (var i=0;i<arguments.length;i++){ var v = arguments[i]; if (v!==undefined && v!==null && String(v).trim()!=='') return v; } return ''; }
                function naira(x){ var n = Number(x||0); try { return '₦'+n.toLocaleString('en-NG'); } catch(e){ return '₦'+n; } }
                var srcPm = (pmSubmission && Object.keys(pmSubmission).length) ? pmSubmission : pm;
                var project = pick(pm.project_desc, pm.project_name, pm.property_estate, data.project_desc, data.project_or_property, data.preferred_property, data['preferred property'], data.estate_name, data.property_estate, data['Property / Estate'], data['Estate / Property'], data.property, data.project, data.property_title, data.property_name, data.project_title, data['Project Name']);
                var dealSource = pick(pm.deal_source, data.deal_source, data['Deal Source'], data.source, data.deal_source_type, data.lead_source);
                var planType = pick(pm.plan_type, pm.payment_plan, data.plan_type, data['Payment Plan'], data.payment_plan, data.plan, data.plan_name, data.installment_plan);
                var planNorm = String(planType || '').toLowerCase().trim().replace(/[\s-]+/g, '_').replace(/_+/g,'_');
                var planLabel = '';
                if (planNorm) {
                    if (['full','full_payment','outright','one_time','one_off','single'].indexOf(planNorm) !== -1) { planLabel = 'Full Payment'; }
                    else {
                        var m = planNorm.match(/(\d+)_?months?/);
                        if (m && m[1]) { planLabel = String(parseInt(m[1],10)) + ' Months'; }
                        else { planLabel = planNorm.replace(/_/g,' ').replace(/\b\w/g, function(ch){ return ch.toUpperCase(); }); }
                    }
                }
                var pb = document.getElementById('finPlanBadge');
                if (pb) {
                    if (planLabel) { pb.textContent = planLabel; pb.style.display = ''; }
                    else { pb.textContent = ''; pb.style.display = 'none'; }
                }
                var phoneVal = pick(data.phone, data.phone_number, data.telephone, data.mobile, data['Phone Number'], data['phone'], pm.client_phone, pm.phone, pm.client_mobile);
                var marketer = pick(pm.marketer_name, pm.submitted_by_name, data.marketer_name, data.sales_agent, data.sales_rep, data.contact_rep, data.uploaded_by_name, data.submitted_by_name, data.agent_name);
                var notes = pick(pm.client_payment_status, pm.notes, data.client_payment_status, data['Client Payment Status / Notes'], data.notes);
                var amountOffered = Number(pm.amount_offered || 0);
                var paidSoFar = Number(pm.amount_paid_so_far || 0);
                var discountAmt = Number(pm.discount_amount || 0);
                var commissionPct = (pm.commission_pct!=null)? pm.commission_pct : '';
                var marketerComm = Number(pm.marketer_comm || 0);
                var agentComm = Number(pm.agent_comm || 0);
                var balanceRem = Number(pm.balance_remaining || 0);
                var clickedSrc = (function(){
                    try {
                        if (pm && Object.keys(pm).length) {
                            var has = pick(pm.payment_id, pm.payment_status, pm.payment_date, pm.sqm, pm.installment_start_date, pm.start_date, pm.SQM);
                            if (has) return pm;
                        }
                    } catch(e){}
                    return srcPm;
                })();
                var clickedId = pick(clickedSrc.payment_id, pmid);
                var clickedAmt = pick(clickedSrc.payment_amount, clickedSrc.amount_paid_now, amount);
                var clickedStatus = pick(clickedSrc.payment_status, clickedSrc.paymentStatus, clickedSrc.status, payStatus0, status);
                var clickedRef = pick(clickedSrc.payment_reference, clickedSrc.reference, clickedSrc.ref, clickedSrc.reference_number);
                var clickedMethod = pick(clickedSrc.payment_method, clickedSrc.method, clickedSrc.payment_mode);
                var clickedDate = pick(clickedSrc.payment_date, clickedSrc.paymentDate, clickedSrc.created_at, clickedSrc.date, payDate0);
                var clickedAlloc = pick(clickedSrc.allocation_id, clickedSrc.inv_allocation_id);
                var clickedProp = pick(clickedSrc.property_id, clickedSrc.property);
                var clickedSqm = pick(
                    clickedSrc.sqm, clickedSrc.SQM, clickedSrc.sqm_size, clickedSrc.plot_size, clickedSrc.size_sqm,
                    clickedSrc['SQM'], clickedSrc['Size (SQM)'], clickedSrc['Size(SQM)'],
                    data.sqm, data.SQM, data.sqm_size, data.plot_size, data.size_sqm, data['SQM'], data['Size (SQM)'], data['Size(SQM)']
                );
                var clickedStart = pick(
                    clickedSrc.installment_start_date, clickedSrc.installmentStartDate, clickedSrc.start_date, clickedSrc.startDate,
                    clickedSrc['Installment Start Date'], clickedSrc['Start Date'],
                    data.installment_start_date, data.installmentStartDate, data.start_date, data.startDate,
                    data['Installment Start Date'], data['Start Date']
                );
                var startDisp = '';
                if (clickedStart && /^\d{4}-\d{2}-\d{2}/.test(String(clickedStart))) {
                    try { startDisp = new Date(String(clickedStart).slice(0,10)).toLocaleDateString('en-US', {year:'numeric', month:'short', day:'2-digit'}); } catch(e){ startDisp = String(clickedStart).slice(0,10); }
                }
                var dateDisp = '';
                if (clickedDate) {
                    var sdt = String(clickedDate);
                    if (/^\d{4}-\d{2}-\d{2}/.test(sdt)) {
                        try { dateDisp = new Date(sdt.replace(' ', 'T')).toLocaleDateString('en-US', {year:'numeric', month:'short', day:'2-digit'}); } catch(e){ dateDisp = sdt.slice(0,10); }
                    } else { dateDisp = sdt; }
                }
                var receiptLink = '';
                if (receipt) {
                    var rcp3 = receipt;
                    if (!/^https?:\/\//i.test(rcp3)) { rcp3 = base + '/' + rcp3.replace(/^\/+/, ''); }
                    receiptLink = '<a target="_blank" href="'+rcp3+'">Open Receipt</a>';
                }
                var metaLine = [];
                if (clickedAlloc) metaLine.push('Alloc #' + clickedAlloc);
                if (clickedProp) metaLine.push('Prop #' + clickedProp);
                var pmMetaEl = document.getElementById('finPaymentMeta');
                if (pmMetaEl) { pmMetaEl.textContent = metaLine.join(' • '); }
                var payHtml = '<div class="row g-2">'
                    + '<div class="col-md-3"><div class="small text-muted">Payment ID</div><div class="fw-semibold">#'+ (clickedId || '-') +'</div></div>'
                    + '<div class="col-md-3"><div class="small text-muted">Amount</div><div class="fw-semibold">'+ naira(clickedAmt || 0) +'</div></div>'
                    + '<div class="col-md-3"><div class="small text-muted">Status</div><div class="fw-semibold">'+ (clickedStatus || '-') +'</div></div>'
                    + '<div class="col-md-3"><div class="small text-muted">Date</div><div class="fw-semibold">'+ (dateDisp || '-') +'</div></div>'
                    + '<div class="col-md-4"><div class="small text-muted">Reference</div><div class="fw-semibold">'+ (clickedRef || '-') +'</div></div>'
                    + '<div class="col-md-4"><div class="small text-muted">Method</div><div class="fw-semibold">'+ (clickedMethod || '-') +'</div></div>'
                    + '<div class="col-md-4"><div class="small text-muted">Receipt</div><div class="fw-semibold">'+ (receiptLink || '-') +'</div></div>'
                    + '<div class="col-md-4"><div class="small text-muted">Plan</div><div class="fw-semibold">'+ (planLabel || '-') +'</div></div>'
                    + '<div class="col-md-4"><div class="small text-muted">Start Date</div><div class="fw-semibold">'+ (startDisp || '-') +'</div></div>'
                    + '<div class="col-md-4"><div class="small text-muted">SQM</div><div class="fw-semibold">'+ (clickedSqm || '-') +'</div></div>'
                    + '</div>';
                var payEl = document.getElementById('finPaymentSummary');
                if (payEl) { payEl.innerHTML = payHtml; }
                document.getElementById('finDetailsProfile').innerHTML =
                    '<div class="row g-2">'
                    + '<div class="col-12"><div class="fw-bold">'+client+'</div><div class="text-muted small">'+email+'</div></div>'
                    + '<div class="col-6"><span class="text-muted small">Phone</span><div>'+ (phoneVal || '-') +'</div></div>'
                    + '<div class="col-6"><span class="text-muted small">Address</span><div>'+ (data.address || '-') +'</div></div>'
                    + '<div class="col-6"><span class="text-muted small">Purpose</span><div>'+ (data.purpose || '-') +'</div></div>'
                    + '<div class="col-6"><span class="text-muted small">Applicant Status</span><div>'+ (data.applicant_status || '-') +'</div></div>'
                    + '<div class="col-6"><span class="text-muted small">DOB</span><div>'+ (data.dob || '-') +'</div></div>'
                    + '<div class="col-6"><span class="text-muted small">Nationality</span><div>'+ (data.nationality || '-') +'</div></div>'
                    + '<div class="col-6"><span class="text-muted small">Form Status</span><div>'+ (status || '-') +'</div></div>'
                    + (function(){ var sbName = pick(submitter, pm.submitted_by_name, pm['Submitted By'], pm.submitted_by, pm.created_by_name, pm.uploaded_by_name, data.submitted_by_name, data['Submitted By'], data['submitted_by'], data['SUBMITTED BY'], data.contact_rep, data.contact_centre_name, data.contact_center_name, data.marketer_name, data.sales_agent, data.sales_rep, data.agent_name); var sbDisp = sbName || '-'; return '<div class="col-6"><span class="text-muted small">Submitted By</span><div>'+ sbDisp +'</div></div>'; })()
                    + '<div class="col-6"><span class="text-muted small">Project / Property</span><div>'+ (project || '-') +'</div></div>'
                    + '<div class="col-6"><span class="text-muted small">Payment Plan</span><div>'+ (planType || '-') +'</div></div>'
                    + '<div class="col-6"><span class="text-muted small">Marketer or Contact Centre Name</span><div>'+ (marketer || '-') +'</div></div>'
                    + '</div>';
                var attHtml = '<div class="d-flex flex-wrap gap-2 align-items-start">';
                if (receipt) { var rcp = receipt; if (!/^https?:\/\//i.test(rcp)) { rcp = base + '/' + rcp.replace(/^\/+/, ''); } attHtml += '<a class="btn btn-sm btn-outline-secondary" target="_blank" href="'+rcp+'">Receipt</a>'; }
                var passPath = valFromKeys(data, ['passport_photo_path','passport_photo','passportPhotoPath','passportPhoto','passport','passport_url']);
                if (passPath) { var pp = passPath; if (!/^https?:\/\//i.test(pp)) { pp = base + '/' + pp.replace(/^\/+/, ''); } attHtml += '<a class="btn btn-sm btn-outline-primary" target="_blank" href="'+pp+'">Passport Photo</a>'; attHtml += '<div><img src="'+pp+'" style="width:120px;height:120px;border-radius:10px;object-fit:cover;border:1px solid #e5e7eb;"></div>'; }
                var idDocPath = valFromKeys(data, ['id_document_path','id_document','id_card','idCard','national_id','nin_card']);
                if (idDocPath) { var idp = idDocPath; if (!/^https?:\/\//i.test(idp)) { idp = base + '/' + idp.replace(/^\/+/, ''); } attHtml += '<a class="btn btn-sm btn-outline-dark" target="_blank" href="'+idp+'">ID Document</a>'; }
                attHtml += '</div>';
                document.getElementById('finDetailsAttachments').innerHTML = attHtml;
                var keys = ['employer','occupation','office_address','nhf_number','other_info','nok_name','nok_relationship','nok_address','nok_phone','company_name','company_address','company_reg_no','business_nature','company_contact','preferred_property','offered_amount','payment_mode','rent_per_annum','rent_payer','referral_source','referral_other'];
                var table = '<div class=\"table-responsive\"><table class=\"table table-sm\"><tbody>';
                keys.forEach(function(k){ var label = k.replace(/_/g,' ').replace(/\\b\\w/g,function(m){return m.toUpperCase();}); var val = (data[k] || ''); table += '<tr><th class=\"w-25\">'+ label +'</th><td>'+ (val || '-') +'</td></tr>'; });
                table += '</tbody></table></div>';
                var blocks = [];
                function bval(o, a, b, c){ if(!o) return ''; return o[a]||o[b]||o[c]||''; }
                var marketerRole = pick(pm.submitted_by_role, data.submitted_by_role, dealSource ? String(dealSource).toLowerCase() : '');
                var marketerNameField = pick(pm.marketer_name, pm.submitted_by_name, pm['Marketer Name'], data.marketer_name, data['Marketer Name'], data.sales_agent, data.sales_rep, data.contact_rep, data.uploaded_by_name, data.submitted_by_name, data.agent_name);
                var amountNow = Number(pm.amount_paid_now || amount || 0);
                var mkAccNo = bval(pm.marketer_bank, 'acc_no', 'account_number', 'accNo');
                var mkBankName = bval(pm.marketer_bank, 'bank', 'bank_name', 'bankName');
                var mkAccName = bval(pm.marketer_bank, 'acc_name', 'account_name', 'accountName');
                var agAccNo = bval(pm.agent_bank, 'acc_no', 'account_number', 'accNo');
                var agBankName = bval(pm.agent_bank, 'bank', 'bank_name', 'bankName');
                var agAccName = bval(pm.agent_bank, 'acc_name', 'account_name', 'accountName');
                var rcpLink = ''; if (receipt) { var rcp2 = receipt; if (!/^https?:\/\//i.test(rcp2)) { rcp2 = base + '/' + rcp2.replace(/^\/+/, ''); } rcpLink = '<a target=\"_blank\" href=\"'+rcp2+'\">View Receipt</a>'; }
                function txSummary() { try { if (Array.isArray(pm.transactions) && pm.transactions.length) { return pm.transactions.map(function(t){ var d = t.date || t.d || t.created_at || ''; var a = t.amount || t.a || ''; return (d ? d : '') + (a!=='' ? ' — '+naira(a) : ''); }).join('; '); } } catch(e){} try { if (Array.isArray(hist) && hist.length) { return hist.map(function(t){ var d = t.created_at || t.d || ''; var a = t.amount || t.a || ''; return (d ? d : '') + (a!=='' ? ' — '+a : ''); }).join('; '); } } catch(e){} return ''; }
                var onb = '<div class=\"row g-3\">'
                    + '<div class=\"col-md-6\"><div class=\"small text-muted\">Client’s Name (text)</div><div class=\"fw-semibold\">'+ (client || '-') +'</div></div>'
                    + '<div class=\"col-md-6\"><div class=\"small text-muted\">Client Email (for dashboard)</div><div class=\"fw-semibold\">'+ (email || '-') +'</div></div>'
                    + '<div class=\"col-md-6\"><div class=\"small text-muted\">Marketer</div><div class=\"fw-semibold\">'+ (marketerRole ? marketerRole.toUpperCase() : '-') +'</div></div>'
                    + '<div class=\"col-md-6\"><div class=\"small text-muted\">Marketer or Contact Centre Name</div><div class=\"fw-semibold\">'+ (marketerNameField || '-') +'</div></div>'
                    + '<div class=\"col-md-12\"><div class=\"small text-muted\">Project / Property Description</div><div class=\"fw-semibold\">'+ (project || '-') +'</div></div>'
                    + '<div class=\"col-md-6\"><div class=\"small text-muted\">Payment Plan</div><div class=\"fw-semibold\">'+ (planType || '-') +'</div></div>'
                    + '<div class=\"col-md-6\"><div class=\"small text-muted\">Amount Offered (if installment)</div><div class=\"fw-semibold\">'+ naira(amountOffered) +'</div></div>'
                    + '<div class=\"col-md-6\"><div class=\"small text-muted\">Amount Paid So Far</div><div class=\"fw-semibold\">'+ naira(paidSoFar) +'</div></div>'
                    + '<div class=\"col-md-6\"><div class=\"small text-muted\">Amount Paid Now</div><div class=\"fw-semibold\">'+ naira(amountNow) +'</div></div>'
                    + '<div class=\"col-md-12\"><div class=\"small text-muted\">Client Payment Status / Notes</div><div class=\"fw-semibold\">'+ (notes || '-') +'</div></div>'
                    + '<div class=\"col-md-12\"><div class=\"small text-muted\">Transaction History</div><div class=\"fw-semibold\">'+ (txSummary() || '-') +'</div></div>'
                    + '<div class=\"col-md-4\"><div class=\"small text-muted\">Discount Amount</div><div class=\"fw-semibold\">'+ naira(discountAmt) +'</div></div>'
                    + '<div class=\"col-md-4\"><div class=\"small text-muted\">Discount Approved By</div><div class=\"fw-semibold\">'+ (pm.discount_approved_by || '-') +'</div></div>'
                    + '<div class=\"col-md-4\"><div class=\"small text-muted\">Balance Remaining</div><div class=\"fw-semibold\">'+ naira(balanceRem) +'</div></div>'
                    + '<div class=\"col-md-3\"><div class=\"small text-muted\">Commission %</div><div class=\"fw-semibold\">'+ (commissionPct!=='' ? commissionPct : '-') +'</div></div>'
                    + '<div class=\"col-md-3\"><div class=\"small text-muted\">Marketer Commission Amount</div><div class=\"fw-semibold\">'+ naira(marketerComm) +'</div></div>'
                    + '<div class=\"col-md-3\"><div class=\"small text-muted\">Agent Commission Amount</div><div class=\"fw-semibold\">'+ naira(agentComm) +'</div></div>'
                    + '<div class=\"col-md-3\"><div class=\"small text-muted\">Upload Payment Receipt (Image/PDF)</div><div class=\"fw-semibold\">'+ (rcpLink || '-') +'</div></div>'
                    + '<div class=\"col-md-4\"><div class=\"small text-muted\">Marketer Account Number</div><div class=\"fw-semibold\">'+ (mkAccNo || '-') +'</div></div>'
                    + '<div class=\"col-md-4\"><div class=\"small text-muted\">Marketer Bank Name</div><div class=\"fw-semibold\">'+ (mkBankName || '-') +'</div></div>'
                    + '<div class=\"col-md-4\"><div class=\"small text-muted\">Marketer Account Name</div><div class=\"fw-semibold\">'+ (mkAccName || '-') +'</div></div>'
                    + '<div class=\"col-md-4\"><div class=\"small text-muted\">Agent Account Number</div><div class=\"fw-semibold\">'+ (agAccNo || '-') +'</div></div>'
                    + '<div class=\"col-md-4\"><div class=\"small text-muted\">Agent Bank Name</div><div class=\"fw-semibold\">'+ (agBankName || '-') +'</div></div>'
                    + '<div class=\"col-md-4\"><div class=\"small text-muted\">Agent Account Name</div><div class=\"fw-semibold\">'+ (agAccName || '-') +'</div></div>'
                    + '</div>';
                var blocks = [];
                function buildKVTable(obj) {
                    function escHtml(s){
                        return String(s)
                            .replace(/&/g,'&amp;')
                            .replace(/</g,'&lt;')
                            .replace(/>/g,'&gt;')
                            .replace(/"/g,'&quot;')
                            .replace(/'/g,'&#039;');
                    }
                    function bankLine(o){
                        if (!o || typeof o !== 'object') return '';
                        var accNo = o.acc_no || o.account_number || o.accNo || o.acc || '';
                        var bank = o.bank || o.bank_name || o.bankName || '';
                        var accName = o.acc_name || o.account_name || o.accountName || '';
                        if (!accNo && !bank && !accName) return '';
                        var parts = [];
                        if (accName) parts.push(accName);
                        if (bank) parts.push(bank);
                        if (accNo) parts.push(accNo);
                        return parts.join(' — ');
                    }
                    function txLine(t){
                        if (!t || typeof t !== 'object') return '';
                        var d = t.date || t.created_at || t.d || '';
                        var a = (t.amount!=null) ? t.amount : ((t.a!=null) ? t.a : '');
                        var st = t.status || t.s || '';
                        var parts = [];
                        if (d) parts.push(d);
                        if (a!=='' && a!==null && a!==undefined) parts.push(naira(a));
                        if (st) parts.push(st);
                        return parts.join(' — ');
                    }
                    function formatVal(v){
                        if (v === null || v === undefined) return '';
                        if (typeof v === 'object') {
                            if (Array.isArray(v)) {
                                if (!v.length) return '';
                                var lines = [];
                                var max = Math.min(v.length, 5);
                                for (var i=0;i<max;i++){
                                    var it = v[i];
                                    if (it && typeof it === 'object') {
                                        var ln = txLine(it);
                                        if (!ln) { try { ln = JSON.stringify(it); } catch(e){ ln = String(it); } }
                                        lines.push(ln);
                                    } else {
                                        lines.push(String(it));
                                    }
                                }
                                var extra = v.length - lines.length;
                                return '<div class="small">'
                                    + lines.map(function(x){ return '<div>'+escHtml(x)+'</div>'; }).join('')
                                    + (extra > 0 ? '<div class="text-muted">+'+extra+' more</div>' : '')
                                    + '</div>';
                            }
                            var bk = bankLine(v);
                            if (bk) return '<span>'+escHtml(bk)+'</span>';
                            var str = '';
                            try { str = JSON.stringify(v, null, 2); } catch(e){ str = String(v); }
                            if (str.length > 800) str = str.slice(0,800) + '…';
                            return '<pre class="mb-0 small">'+escHtml(str)+'</pre>';
                        }
                        var s = String(v);
                        if (s.length > 800) s = s.slice(0,800) + '…';
                        return escHtml(s);
                    }
                    var keys = Object.keys(obj || {});
                    var html = '<div class="table-responsive"><table class="table table-sm kv-table"><tbody>';
                    var cap = 80;
                    for (var i=0;i<keys.length && i<cap;i++){
                        var k = keys[i];
                        var v = obj[k];
                        var valHtml = formatVal(v);
                        var label = k.replace(/_/g,' ').replace(/\\b\\w/g,function(m){return m.toUpperCase();});
                        html += '<tr><th class="w-25">'+escHtml(label)+'</th><td>'+(valHtml || '-')+'</td></tr>';
                    }
                    if (keys.length > cap) {
                        html += '<tr><td colspan="2" class="text-muted small">'+escHtml(String(keys.length-cap))+' more fields not shown</td></tr>';
                    }
                    html += '</tbody></table></div>';
                    return html;
                }
                var usePm = (pmSubmission && Object.keys(pmSubmission).length) ? pmSubmission : pm;
                var pmAll = buildKVTable(usePm);
                var dataAll = buildKVTable(data);
                var cards = '<div class=\"card shadow-sm mb-3\"><div class=\"card-header bg-white\"><strong>Uploaded Payment Data (this payment)</strong></div><div class=\"card-body\">'+ pmAll +'</div></div>'
                          + '<div class=\"card shadow-sm mb-3\"><div class=\"card-header bg-white\"><strong>Client Form Data (full)</strong></div><div class=\"card-body\">'+ dataAll +'</div></div>';
                document.getElementById('finDetailsData').innerHTML = cards + table;
                function renderHist(list){ if (!Array.isArray(list) || list.length === 0) { document.getElementById('finTransHistory').innerHTML = '<div class=\"text-muted\">No transactions found for this client.</div>'; document.getElementById('finTransCount').textContent = ''; return; } var h = '<div class=\"table-responsive\"><table class=\"table table-sm\"><thead><tr><th>ID</th><th>Date</th><th>Type</th><th class=\"text-end\">Amount</th><th>Status</th></tr></thead><tbody>'; list.forEach(function(it){ var dt = it.created_at || ''; var amt = (it.amount!=null)? it.amount : 0; var type = it.payment_type || '-'; var st = it.status || '-'; h += '<tr><td>#'+ (it.id || '-') +'</td><td>'+ dt +'</td><td>'+ type +'</td><td class=\"text-end\">'+ amt +'</td><td>'+ st +'</td></tr>'; }); h += '</tbody></table></div>'; document.getElementById('finTransHistory').innerHTML = h; document.getElementById('finTransCount').textContent = list.length + ' records'; }
                document.getElementById('finTransCount').textContent = (Array.isArray(hist) ? hist.length : 0) + ' records';
                initialRendered = true;
            }
            setTimeout(renderAll, 0);
            function valFromKeys(obj, keys){ for (var i=0;i<keys.length;i++){ var k = keys[i]; var v = (obj && obj[k]!=null) ? String(obj[k]) : ''; if (v.trim()!=='') return v; } return ''; }
            var avatar = valFromKeys(data, ['passport_photo_path','passport_photo','passportPhotoPath','passportPhoto','passport','passport_url']);
            if (avatar && !/^https?:\/\//i.test(avatar)) { avatar = base + '/' + avatar.replace(/^\/+/, ''); }
            var avatarImg = document.getElementById('finAvatarImg');
            if (avatar && avatarImg) { avatarImg.src = avatar; avatarImg.style.display = 'block'; } else { if (avatarImg) { avatarImg.style.display = 'none'; } }
            var emEl = document.getElementById('finEmailText'); if (emEl) { emEl.textContent = email || ''; }
            var stEl = document.getElementById('finStatusBadge'); if (stEl) { stEl.textContent = status || ''; }
            function pick(){
                for (var i=0;i<arguments.length;i++){
                    var v = arguments[i];
                    if (v!==undefined && v!==null && String(v).trim()!=='') return v;
                }
                return '';
            }
            function naira(x){
                var n = Number(x||0); try { return '₦'+n.toLocaleString('en-NG'); } catch(e){ return '₦'+n; }
            }
            var project = pick(pm.project_desc, pm.project_name, pm.property_estate, data.project_desc, data.project_or_property, data.preferred_property, data['preferred property'], data.estate_name, data.property_estate, data['Property / Estate'], data['Estate / Property'], data.property, data.project, data.property_title, data.property_name, data.project_title, data['Project Name']);
            var dealSource = pick(pm.deal_source, data.deal_source, data['Deal Source'], data.source, data.deal_source_type, data.lead_source);
            var planType = pick(pm.plan_type, pm.payment_plan, data.plan_type, data['Payment Plan'], data.payment_plan, data.plan, data.plan_name, data.installment_plan);
            var planNorm = String(planType || '').toLowerCase().trim().replace(/[\s-]+/g, '_').replace(/_+/g,'_');
            var planLabel = '';
            if (planNorm) {
                if (['full','full_payment','outright','one_time','one_off','single'].indexOf(planNorm) !== -1) { planLabel = 'Full Payment'; }
                else {
                    var m = planNorm.match(/(\d+)_?months?/);
                    if (m && m[1]) { planLabel = String(parseInt(m[1],10)) + ' Months'; }
                    else { planLabel = planNorm.replace(/_/g,' ').replace(/\b\w/g, function(ch){ return ch.toUpperCase(); }); }
                }
            }
            var pb = document.getElementById('finPlanBadge');
            if (pb) {
                if (planLabel) { pb.textContent = planLabel; pb.style.display = ''; }
                else { pb.textContent = ''; pb.style.display = 'none'; }
            }
            var phoneVal = pick(data.phone, data.phone_number, data.telephone, data.mobile, data['Phone Number'], data['phone'], pm.client_phone, pm.phone, pm.client_mobile);
            var marketer = pick(pm.marketer_name, pm.submitted_by_name, data.marketer_name, data.sales_agent, data.sales_rep, data.contact_rep, data.uploaded_by_name, data.submitted_by_name, data.agent_name);
            var notes = pick(pm.client_payment_status, pm.notes, data.client_payment_status, data['Client Payment Status / Notes'], data.notes);
            var amountOffered = Number(pm.amount_offered || 0);
            var paidSoFar = Number(pm.amount_paid_so_far || 0);
            var discountAmt = Number(pm.discount_amount || 0);
            var commissionPct = (pm.commission_pct!=null)? pm.commission_pct : '';
            var marketerComm = Number(pm.marketer_comm || 0);
            var agentComm = Number(pm.agent_comm || 0);
            var balanceRem = Number(pm.balance_remaining || 0);
            document.getElementById('finDetailsProfile').innerHTML =
                '<div class="row g-2">'
                + '<div class="col-12"><div class="fw-bold">'+client+'</div><div class="text-muted small">'+email+'</div></div>'
            + '<div class="col-6"><span class="text-muted small">Phone</span><div>'+ (phoneVal || '-') +'</div></div>'
                + '<div class="col-6"><span class="text-muted small">Address</span><div>'+ (data.address || '-') +'</div></div>'
                + '<div class="col-6"><span class="text-muted small">Purpose</span><div>'+ (data.purpose || '-') +'</div></div>'
                + '<div class="col-6"><span class="text-muted small">Applicant Status</span><div>'+ (data.applicant_status || '-') +'</div></div>'
                + '<div class="col-6"><span class="text-muted small">DOB</span><div>'+ (data.dob || '-') +'</div></div>'
                + '<div class="col-6"><span class="text-muted small">Nationality</span><div>'+ (data.nationality || '-') +'</div></div>'
                + '<div class="col-6"><span class="text-muted small">Form Status</span><div>'+ (status || '-') +'</div></div>'
            + (function(){ var sbName = pick(submitter, pm.submitted_by_name, pm['Submitted By'], pm.submitted_by, pm.created_by_name, pm.uploaded_by_name, data.submitted_by_name, data['Submitted By'], data['submitted_by'], data['SUBMITTED BY'], data.contact_rep, data.contact_centre_name, data.contact_center_name, data.marketer_name, data.sales_agent, data.sales_rep, data.agent_name); var sbDisp = sbName || '-'; return '<div class="col-6"><span class="text-muted small">Submitted By</span><div>'+ sbDisp +'</div></div>'; })()
                + '<div class="col-6"><span class="text-muted small">Project / Property</span><div>'+ (project || '-') +'</div></div>'
                + '<div class="col-6"><span class="text-muted small">Payment Plan</span><div>'+ (planType || '-') +'</div></div>'
                + '<div class="col-6"><span class="text-muted small">Marketer or Contact Centre Name</span><div>'+ (marketer || '-') +'</div></div>'
                + '</div>';
            var attHtml = '<div class="d-flex flex-wrap gap-2 align-items-start">';
            if (receipt) {
                var rcp = receipt; if (!/^https?:\/\//i.test(rcp)) { rcp = base + '/' + rcp.replace(/^\/+/, ''); }
                attHtml += '<a class="btn btn-sm btn-outline-secondary" target="_blank" href="'+rcp+'">Receipt</a>';
            }
            if (data.passport_photo_path) {
                var pp = data.passport_photo_path; if (!/^https?:\/\//i.test(pp)) { pp = base + '/' + pp.replace(/^\/+/, ''); }
                attHtml += '<a class="btn btn-sm btn-outline-primary" target="_blank" href="'+pp+'">Passport Photo</a>';
                attHtml += '<div><img src="'+pp+'" style="width:120px;height:120px;border-radius:10px;object-fit:cover;border:1px solid #e5e7eb;"></div>';
            }
            if (data.id_document_path) {
                var idp = data.id_document_path; if (!/^https?:\/\//i.test(idp)) { idp = base + '/' + idp.replace(/^\/+/, ''); }
                attHtml += '<a class="btn btn-sm btn-outline-dark" target="_blank" href="'+idp+'">ID Document</a>';
            }
            attHtml += '</div>';
            document.getElementById('finDetailsAttachments').innerHTML = attHtml;
            var keys = ['employer','occupation','office_address','nhf_number','other_info','nok_name','nok_relationship','nok_address','nok_phone','company_name','company_address','company_reg_no','business_nature','company_contact','preferred_property','offered_amount','payment_mode','rent_per_annum','rent_payer','referral_source','referral_other'];
            var table = '<div class="table-responsive"><table class="table table-sm"><tbody>';
            keys.forEach(function(k){
                var label = k.replace(/_/g,' ').replace(/\b\\w/g,function(m){return m.toUpperCase();});
                var val = (data[k] || '');
                table += '<tr><th class="w-25">'+ label +'</th><td>'+ (val || '-') +'</td></tr>';
            });
            table += '</tbody></table></div>';
            var blocks = [];
            blocks.push('<div class="alert alert-info mb-3">Amount Paid Now: <strong>'+ (amount ? naira(amount) : '₦0') +'</strong></div>');
            function bval(o, a, b, c){ if(!o) return ''; return o[a]||o[b]||o[c]||''; }
            var marketerRole = pick(pm.submitted_by_role, data.submitted_by_role, dealSource ? String(dealSource).toLowerCase() : '');
            var marketerNameField = pick(pm.marketer_name, pm.submitted_by_name, pm['Marketer Name'], data.marketer_name, data['Marketer Name'], data.sales_agent, data.sales_rep, data.contact_rep, data.uploaded_by_name, data.submitted_by_name, data.agent_name);
            var amountNow = Number(pm.amount_paid_now || amount || 0);
            var mkAccNo = bval(pm.marketer_bank, 'acc_no', 'account_number', 'accNo');
            var mkBankName = bval(pm.marketer_bank, 'bank', 'bank_name', 'bankName');
            var mkAccName = bval(pm.marketer_bank, 'acc_name', 'account_name', 'accountName');
            var agAccNo = bval(pm.agent_bank, 'acc_no', 'account_number', 'accNo');
            var agBankName = bval(pm.agent_bank, 'bank', 'bank_name', 'bankName');
            var agAccName = bval(pm.agent_bank, 'acc_name', 'account_name', 'accountName');
            var rcpLink = '';
            if (receipt) { var rcp = receipt; if (!/^https?:\/\//i.test(rcp)) { rcp = base + '/' + rcp.replace(/^\/+/, ''); } rcpLink = '<a target="_blank" href="'+rcp+'">View Receipt</a>'; }
            // Build a compact transaction summary line from pm.transactions or hist list
            function txSummary() {
                try {
                    if (Array.isArray(pm.transactions) && pm.transactions.length) {
                        return pm.transactions.map(function(t){
                            var d = t.date || t.d || t.created_at || '';
                            var a = t.amount || t.a || '';
                            return (d ? d : '') + (a!=='' ? ' — '+naira(a) : '');
                        }).join('; ');
                    }
                } catch(e){}
                try {
                    if (Array.isArray(hist) && hist.length) {
                        return hist.map(function(t){
                            var d = t.created_at || t.d || '';
                            var a = t.amount || t.a || '';
                            return (d ? d : '') + (a!=='' ? ' — '+a : '');
                        }).join('; ');
                    }
                } catch(e){}
                return '';
            }
            var onb = '<div class="row g-3">'
                + '<div class="col-md-6"><div class="small text-muted">Client’s Name (text)</div><div class="fw-semibold">'+ (client || '-') +'</div></div>'
                + '<div class="col-md-6"><div class="small text-muted">Client Email (for dashboard)</div><div class="fw-semibold">'+ (email || '-') +'</div></div>'
                + '<div class="col-md-6"><div class="small text-muted">Deal Source</div><div class="fw-semibold">'+ (dealSource || '-') +'</div></div>'
                + '<div class="col-md-6"><div class="small text-muted">Marketer</div><div class="fw-semibold">'+ (marketerRole ? marketerRole.toUpperCase() : '-') +'</div></div>'
                + '<div class="col-md-6"><div class="small text-muted">Marketer or Contact Centre Name</div><div class="fw-semibold">'+ (marketerNameField || '-') +'</div></div>'
                + '<div class="col-md-12"><div class="small text-muted">Project / Property Description</div><div class="fw-semibold">'+ (project || '-') +'</div></div>'
                + '<div class="col-md-6"><div class="small text-muted">Payment Plan</div><div class="fw-semibold">'+ (planType || '-') +'</div></div>'
                + '<div class="col-md-6"><div class="small text-muted">Amount Offered (if installment)</div><div class="fw-semibold">'+ naira(amountOffered) +'</div></div>'
                + '<div class="col-md-6"><div class="small text-muted">Amount Paid So Far</div><div class="fw-semibold">'+ naira(paidSoFar) +'</div></div>'
                + '<div class="col-md-6"><div class="small text-muted">Amount Paid Now</div><div class="fw-semibold">'+ naira(amountNow) +'</div></div>'
                + '<div class="col-md-12"><div class="small text-muted">Client Payment Status / Notes</div><div class="fw-semibold">'+ (notes || '-') +'</div></div>'
                + '<div class="col-md-12"><div class="small text-muted">Transaction History</div><div class="fw-semibold">'+ (txSummary() || '-') +'</div></div>'
                + '<div class="col-md-4"><div class="small text-muted">Discount Amount</div><div class="fw-semibold">'+ naira(discountAmt) +'</div></div>'
                + '<div class="col-md-4"><div class="small text-muted">Discount Approved By</div><div class="fw-semibold">'+ (pm.discount_approved_by || '-') +'</div></div>'
                + '<div class="col-md-4"><div class="small text-muted">Balance Remaining</div><div class="fw-semibold">'+ naira(balanceRem) +'</div></div>'
                + '<div class="col-md-3"><div class="small text-muted">Commission %</div><div class="fw-semibold">'+ (commissionPct!=='' ? commissionPct : '-') +'</div></div>'
                + '<div class="col-md-3"><div class="small text-muted">Marketer Commission Amount</div><div class="fw-semibold">'+ naira(marketerComm) +'</div></div>'
                + '<div class="col-md-3"><div class="small text-muted">Agent Commission Amount</div><div class="fw-semibold">'+ naira(agentComm) +'</div></div>'
                + '<div class="col-md-3"><div class="small text-muted">Upload Payment Receipt (Image/PDF)</div><div class="fw-semibold">'+ (rcpLink || '-') +'</div></div>'
                + '<div class="col-md-4"><div class="small text-muted">Marketer Account Number</div><div class="fw-semibold">'+ (mkAccNo || '-') +'</div></div>'
                + '<div class="col-md-4"><div class="small text-muted">Marketer Bank Name</div><div class="fw-semibold">'+ (mkBankName || '-') +'</div></div>'
                + '<div class="col-md-4"><div class="small text-muted">Marketer Account Name</div><div class="fw-semibold">'+ (mkAccName || '-') +'</div></div>'
                + '<div class="col-md-4"><div class="small text-muted">Agent Account Number</div><div class="fw-semibold">'+ (agAccNo || '-') +'</div></div>'
                + '<div class="col-md-4"><div class="small text-muted">Agent Bank Name</div><div class="fw-semibold">'+ (agBankName || '-') +'</div></div>'
                + '<div class="col-md-4"><div class="small text-muted">Agent Account Name</div><div class="fw-semibold">'+ (agAccName || '-') +'</div></div>'
                + '</div>';
            var blocks = [];
            function buildKVTable(obj) {
                function escHtml(s){
                    return String(s)
                        .replace(/&/g,'&amp;')
                        .replace(/</g,'&lt;')
                        .replace(/>/g,'&gt;')
                        .replace(/"/g,'&quot;')
                        .replace(/'/g,'&#039;');
                }
                function bankLine(o){
                    if (!o || typeof o !== 'object') return '';
                    var accNo = o.acc_no || o.account_number || o.accNo || o.acc || '';
                    var bank = o.bank || o.bank_name || o.bankName || '';
                    var accName = o.acc_name || o.account_name || o.accountName || '';
                    if (!accNo && !bank && !accName) return '';
                    var parts = [];
                    if (accName) parts.push(accName);
                    if (bank) parts.push(bank);
                    if (accNo) parts.push(accNo);
                    return parts.join(' — ');
                }
                function txLine(t){
                    if (!t || typeof t !== 'object') return '';
                    var d = t.date || t.created_at || t.d || '';
                    var a = (t.amount!=null) ? t.amount : ((t.a!=null) ? t.a : '');
                    var st = t.status || t.s || '';
                    var parts = [];
                    if (d) parts.push(d);
                    if (a!=='' && a!==null && a!==undefined) parts.push(naira(a));
                    if (st) parts.push(st);
                    return parts.join(' — ');
                }
                function formatVal(v){
                    if (v === null || v === undefined) return '';
                    if (typeof v === 'object') {
                        if (Array.isArray(v)) {
                            if (!v.length) return '';
                            var lines = [];
                            var max = Math.min(v.length, 5);
                            for (var i=0;i<max;i++){
                                var it = v[i];
                                if (it && typeof it === 'object') {
                                    var ln = txLine(it);
                                    if (!ln) { try { ln = JSON.stringify(it); } catch(e){ ln = String(it); } }
                                    lines.push(ln);
                                } else {
                                    lines.push(String(it));
                                }
                            }
                            var extra = v.length - lines.length;
                            return '<div class="small">'
                                + lines.map(function(x){ return '<div>'+escHtml(x)+'</div>'; }).join('')
                                + (extra > 0 ? '<div class="text-muted">+'+extra+' more</div>' : '')
                                + '</div>';
                        }
                        var bk = bankLine(v);
                        if (bk) return '<span>'+escHtml(bk)+'</span>';
                        var str = '';
                        try { str = JSON.stringify(v, null, 2); } catch(e){ str = String(v); }
                        if (str.length > 800) str = str.slice(0,800) + '…';
                        return '<pre class="mb-0 small">'+escHtml(str)+'</pre>';
                    }
                    var s = String(v);
                    if (s.length > 800) s = s.slice(0,800) + '…';
                    return escHtml(s);
                }
                var keys = Object.keys(obj || {});
                var html = '<div class="table-responsive"><table class="table table-sm kv-table"><tbody>';
                var cap = 80;
                for (var i=0;i<keys.length && i<cap;i++){
                    var k = keys[i];
                    var v = obj[k];
                    var valHtml = formatVal(v);
                    var label = k.replace(/_/g,' ').replace(/\\b\\w/g,function(m){return m.toUpperCase();});
                    html += '<tr><th class="w-25">'+escHtml(label)+'</th><td>'+(valHtml || '-')+'</td></tr>';
                }
                if (keys.length > cap) {
                    html += '<tr><td colspan="2" class="text-muted small">'+escHtml(String(keys.length-cap))+' more fields not shown</td></tr>';
                }
                html += '</tbody></table></div>';
                return html;
            }
            var usePm2 = (pmSubmission && Object.keys(pmSubmission).length) ? pmSubmission : pm;
            var pmAll = buildKVTable(usePm2);
            var dataAll = buildKVTable(data);
            var cards = '<div class="card shadow-sm mb-3"><div class="card-header bg-white"><strong>Uploaded Payment Data (this payment)</strong></div><div class="card-body">'+ pmAll +'</div></div>'
                      + '<div class="card shadow-sm mb-3"><div class="card-header bg-white"><strong>Client Form Data (full)</strong></div><div class="card-body">'+ dataAll +'</div></div>';
            document.getElementById('finDetailsData').innerHTML = cards + table;
            function renderHist(list){
                if (!Array.isArray(list) || list.length === 0) {
                    document.getElementById('finTransHistory').innerHTML = '<div class="text-muted">No transactions found for this client.</div>';
                    document.getElementById('finTransCount').textContent = '';
                    return;
                }
                    var pidStr = String(pmid || '');
                    var norm = [];
                    list.forEach(function(it){ norm.push(it); });
                    var idx = -1;
                    for (var i=0;i<norm.length;i++){
                        if (String(norm[i].id || '') === pidStr) { idx = i; break; }
                    }
                    if (idx > 0) {
                        var hit = norm.splice(idx, 1)[0];
                        norm.unshift(hit);
                    }
                    var h = '<div class="table-responsive"><table class="table table-sm"><thead><tr><th>ID</th><th>Date</th><th>Type</th><th class="text-end">Amount</th><th>Status</th></tr></thead><tbody>';
                    norm.forEach(function(it){
                        var dt = it.created_at || '';
                        var amt = (it.amount!=null)? it.amount : 0;
                        var type = it.payment_type || '-';
                        var st = it.status || '-';
                        var isCur = (String(it.id || '') === pidStr);
                        h += '<tr'+(isCur?' class="table-success"':'')+'><td>'+ (String(it.id||'').indexOf('tx_')===0 ? String(it.id) : '#'+(it.id || '-')) + (isCur ? ' <span class="badge bg-success ms-2">Current</span>' : '') +'</td><td>'+ dt +'</td><td>'+ type +'</td><td class="text-end">'+ naira(amt) +'</td><td>'+ st +'</td></tr>';
                });
                h += '</tbody></table></div>';
                document.getElementById('finTransHistory').innerHTML = h;
                    document.getElementById('finTransCount').textContent = norm.length + ' records';
            }
                renderHist(hist);
                document.getElementById('finTransCount').textContent = (Array.isArray(hist) ? hist.length : 0) + ' records';
            var btnTrans = document.getElementById('finTransBtn');
                var transactionsRendered = true;
            if (btnTrans) {
                btnTrans.onclick = function(){
                    var el = document.getElementById('finTransHistory');
                    if (!el) return;
                    if (el.style.display === 'none') { el.style.display = ''; } else { el.style.display = 'none'; }
                };
            }
            var fd = new FormData();
            fd.append('history_action','approved_history');
            fd.append('user_id', uid);
            fd.append('payment_id', pmid);
            fd.append('client_name', client);
            fd.append('client_email', cemail);
            fetch('finance-payments.php', { method: 'POST', body: fd })
                .then(function(r){ return r.json(); })
                .then(function(j){
                    if (j && j.success && Array.isArray(j.items)) {
                        hist = j.items;
                        document.getElementById('finTransCount').textContent = hist.length + ' records';
                        if (transactionsRendered) { renderHist(hist); }
                    }
                })
                .catch(function(){});
            var fd2 = new FormData();
            fd2.append('modal_payload','get');
            fd2.append('payment_id', pmid);
            fetch('finance-payments.php', { method: 'POST', body: fd2 })
                .then(function(r){ return r.json(); })
                .then(function(j){
                    if (j && j.success) {
                        if (j.pm) pm = j.pm;
                        if (j.pm_submission) pmSubmission = j.pm_submission;
                        if (j.data) data = j.data;
                        if (Array.isArray(j.history)) {
                            hist = j.history;
                            document.getElementById('finTransCount').textContent = hist.length + ' records';
                            if (transactionsRendered) { renderHist(hist); }
                        }
                        if (j.receipt) receipt = j.receipt;
                        if (j.status) status = j.status;
                        if (j.submitter) submitter = j.submitter;
                        if (j.client) client = j.client;
                        if (j.email) email = j.email;
                        try { if (window.requestAnimationFrame) { requestAnimationFrame(renderAll); } else { setTimeout(renderAll, 0); } } catch(e) { setTimeout(renderAll, 0); }
                    }
                })
                .catch(function(){});
            try {
                var dlg = document.querySelector('#financeClientInfoModal .modal-dialog');
                var header = document.querySelector('#financeClientInfoModal .modal-header');
                if (dlg && header) {
                    header.style.cursor = 'grab';
                    if (!window.__finDragInstalled) {
                        (function(){
                            var down = false, sx = 0, sy = 0, ol = 0, ot = 0;
                            function clamp(n, min, max){ return Math.max(min, Math.min(max, n)); }
                            header.addEventListener('mousedown', function(e){
                                try {
                                    if (e && e.button !== 0) return;
                                    var t = e && e.target ? e.target : null;
                                    if (t && t.closest && t.closest('[data-bs-dismiss="modal"], .btn-close, button, a, input, select, textarea, label')) return;
                                } catch(eSkip){}
                                try {
                                    var r0 = dlg.getBoundingClientRect();
                                    dlg.classList.add('draggable');
                                    dlg.style.left = r0.left + 'px';
                                    dlg.style.top = r0.top + 'px';
                                } catch(e0){}
                                down = true; sx = e.clientX; sy = e.clientY;
                                var r = dlg.getBoundingClientRect(); ol = r.left; ot = r.top;
                                document.body.style.userSelect = 'none';
                                header.style.cursor = 'grabbing';
                            });
                            document.addEventListener('mousemove', function(e){
                                if (!down) return;
                                var nl = ol + (e.clientX - sx);
                                var nt = ot + (e.clientY - sy);
                                var maxL = window.innerWidth - dlg.offsetWidth;
                                var maxT = window.innerHeight - 40;
                                dlg.style.left = clamp(nl, 0, maxL) + 'px';
                                dlg.style.top = clamp(nt, 0, maxT) + 'px';
                            });
                            document.addEventListener('mouseup', function(){
                                if (down) { down = false; document.body.style.userSelect = ''; header.style.cursor = 'grab'; }
                            });
                            header.addEventListener('touchstart', function(e){
                                try {
                                    var t0 = e && e.target ? e.target : null;
                                    if (t0 && t0.closest && t0.closest('[data-bs-dismiss="modal"], .btn-close, button, a, input, select, textarea, label')) return;
                                } catch(eSkip){}
                                try {
                                    var r0 = dlg.getBoundingClientRect();
                                    dlg.classList.add('draggable');
                                    dlg.style.left = r0.left + 'px';
                                    dlg.style.top = r0.top + 'px';
                                } catch(e0){}
                                var t = e.touches[0]; down = true; sx = t.clientX; sy = t.clientY;
                                var r = dlg.getBoundingClientRect(); ol = r.left; ot = r.top;
                            }, { passive: true });
                            document.addEventListener('touchmove', function(e){
                                if (!down) return;
                                var t = e.touches[0];
                                var nl = ol + (t.clientX - sx);
                                var nt = ot + (t.clientY - sy);
                                var maxL = window.innerWidth - dlg.offsetWidth;
                                var maxT = window.innerHeight - 40;
                                dlg.style.left = clamp(nl, 0, maxL) + 'px';
                                dlg.style.top = clamp(nt, 0, maxT) + 'px';
                            }, { passive: true });
                            document.addEventListener('touchend', function(){ down = false; header.style.cursor = 'grab'; });
                            window.__finDragInstalled = true;
                        })();
                    }
                }
            } catch(e){}
        });
        document.getElementById('financeClientInfoModal').addEventListener('hide.bs.modal', function(){
            try {
                var dlg = document.querySelector('#financeClientInfoModal .modal-dialog');
                if (dlg) { dlg.classList.remove('draggable'); dlg.style.left=''; dlg.style.top=''; }
                document.body.style.userSelect = '';
                document.body.style.overflow = '';
            } catch(e){}
        });
        </script>
    </div>
    </div>
</div>
<script>
document.addEventListener('DOMContentLoaded', function(){
    function send(action, id, btn){
        var fd = new FormData();
        fd.append('pm_action', action);
        fd.append('pm_id', id);
        fetch('finance-payments.php', {
            method: 'POST',
            body: fd
        }).then(function(r){ return r.json(); }).then(function(j){
            if (j && j.success) {
                if (j && j.message) { alert(j.message); }
                location.reload();
            }
            else { if (btn) btn.disabled = false; alert('Action failed'); }
        }).catch(function(){ if (btn) btn.disabled = false; alert('Network error'); });
    }
    document.querySelectorAll('.approve-btn').forEach(function(btn){
        btn.addEventListener('click', function(e){
            if (e && e.preventDefault) e.preventDefault();
            if (e && e.stopPropagation) e.stopPropagation();
            btn.disabled = true;
            var id = btn.getAttribute('data-id');
            var api = window.showConfirm ? window.showConfirm({ title: 'Approve Payment', message: 'Are you sure you want to approve this payment?', confirmText: 'Yes, approve', variant: 'success' }) : Promise.resolve(window.confirm('Are you sure?'));
            api.then(function(ok){
                if (!ok) { btn.disabled = false; return; }
                send('approve', id, btn);
            });
        });
    });
    document.querySelectorAll('.reject-btn').forEach(function(btn){
        btn.addEventListener('click', function(e){
            if (e && e.preventDefault) e.preventDefault();
            if (e && e.stopPropagation) e.stopPropagation();
            btn.disabled = true;
            var id = btn.getAttribute('data-id');
            var api = window.showConfirm ? window.showConfirm({ title: 'Reject Payment', message: 'Are you sure you want to reject this payment?', confirmText: 'Yes, reject', variant: 'danger' }) : Promise.resolve(window.confirm('Are you sure?'));
            api.then(function(ok){
                if (!ok) { btn.disabled = false; return; }
                send('reject', id, btn);
            });
        });
    });
    document.querySelectorAll('.reverse-btn').forEach(function(btn){
        btn.addEventListener('click', function(e){
            if (e && e.preventDefault) e.preventDefault();
            if (e && e.stopPropagation) e.stopPropagation();
            btn.disabled = true;
            var id = btn.getAttribute('data-id');
            var api = window.showConfirm ? window.showConfirm({ title: 'Reverse Payment', message: 'Reverse this payment? This creates a reversal record and locks the original.', confirmText: 'Yes, reverse', variant: 'warning' }) : Promise.resolve(window.confirm('Reverse this payment?'));
            api.then(function(ok){
                if (!ok) { btn.disabled = false; return; }
                send('reverse', id, btn);
            });
        });
    });

    var table = document.getElementById('verificationTable');
    var tabs = document.querySelectorAll('#verifyTabs .nav-link');
    var selectAll = document.getElementById('selectAllRows');
    var bulkBar = document.getElementById('bulkBar');
    var bulkCount = document.getElementById('bulkSelectedCount');
    var bulkApprove = document.getElementById('bulkApproveBtn');
    var bulkReject = document.getElementById('bulkRejectBtn');
    var emptyState = document.getElementById('verifyEmptyState');
    var currentFilter = 'all';

    function rowIsVisible(row){
        return row && row.style.display !== 'none';
    }

    function setCollapseVisibility(row, visible){
        try {
            var nxt = row && row.nextElementSibling ? row.nextElementSibling : null;
            if (nxt && nxt.classList && nxt.classList.contains('verif-collapse-row')) {
                nxt.style.display = visible ? '' : 'none';
                if (!visible) { nxt.classList.remove('show'); }
            }
        } catch(e){}
    }

    function updateEmptyState(){
        if (!emptyState) return;
        var rows = document.querySelectorAll('#verificationTable tbody tr.verif-row');
        var vis = 0;
        rows.forEach(function(r){ if (rowIsVisible(r)) vis++; });
        emptyState.classList.toggle('d-none', vis > 0);
    }

    function updateBulkBar(){
        var checked = document.querySelectorAll('.row-check:checked').length;
        if (bulkCount) bulkCount.textContent = String(checked);
        if (bulkApprove) bulkApprove.disabled = checked === 0;
        if (bulkReject) bulkReject.disabled = checked === 0;
        if (bulkBar) {
            if (checked > 0) bulkBar.classList.remove('d-none');
            else bulkBar.classList.add('d-none');
        }

        if (selectAll) {
            var cbs = document.querySelectorAll('#verificationTable tbody tr.verif-row');
            var enabledVisible = 0;
            var checkedVisible = 0;
            cbs.forEach(function(r){
                if (!rowIsVisible(r)) return;
                var cb = r.querySelector('.row-check');
                if (!cb || cb.disabled) return;
                enabledVisible++;
                if (cb.checked) checkedVisible++;
            });
            selectAll.indeterminate = enabledVisible > 0 && checkedVisible > 0 && checkedVisible < enabledVisible;
            selectAll.checked = enabledVisible > 0 && checkedVisible === enabledVisible;
            selectAll.disabled = enabledVisible === 0;
        }
    }

    function sortByNewest(){
        var tbody = document.querySelector('#verificationTable tbody');
        if (!tbody) return;
        var empty = document.getElementById('verifyEmptyState');
        var rows = Array.from(tbody.querySelectorAll('tr.verif-row'));
        rows.sort(function(a, b){
            var ta = parseFloat(a.getAttribute('data-upload-ts') || '0') || 0;
            var tb = parseFloat(b.getAttribute('data-upload-ts') || '0') || 0;
            if (tb !== ta) return tb - ta;
            var ia = parseFloat(a.getAttribute('data-id') || '0') || 0;
            var ib = parseFloat(b.getAttribute('data-id') || '0') || 0;
            return ib - ia;
        });
        var frag = document.createDocumentFragment();
        rows.forEach(function(r){
            var nxt = r.nextElementSibling;
            frag.appendChild(r);
            if (nxt && nxt.classList && nxt.classList.contains('verif-collapse-row')) frag.appendChild(nxt);
        });
        tbody.appendChild(frag);
        if (empty) tbody.appendChild(empty);
    }

    function applyFilter(){
        var rows = document.querySelectorAll('#verificationTable tbody tr.verif-row');
        rows.forEach(function(r){
            var st = r.getAttribute('data-status') || 'unknown';
            var show = true;
            if (currentFilter === 'pending') show = (st === 'pending');
            else if (currentFilter === 'approved') show = (st === 'approved');
            else if (currentFilter === 'rejected') show = (st === 'rejected');
            r.style.display = show ? '' : 'none';
            if (!show) {
                var cb = r.querySelector('.row-check');
                if (cb) cb.checked = false;
            }
            setCollapseVisibility(r, show);
        });
        sortByNewest();
        updateEmptyState();
        updateBulkBar();
    }

    if (tabs && tabs.length) {
        tabs.forEach(function(t){
            t.addEventListener('click', function(){
                tabs.forEach(function(x){ x.classList.remove('active'); });
                t.classList.add('active');
                currentFilter = t.getAttribute('data-filter') || 'all';
                applyFilter();
            });
        });
    }

    if (selectAll) {
        selectAll.addEventListener('change', function(){
            var rows = document.querySelectorAll('#verificationTable tbody tr.verif-row');
            rows.forEach(function(r){
                if (!rowIsVisible(r)) return;
                var cb = r.querySelector('.row-check');
                if (!cb || cb.disabled) return;
                cb.checked = !!selectAll.checked;
            });
            updateBulkBar();
        });
    }

    document.querySelectorAll('.row-check').forEach(function(cb){
        cb.addEventListener('change', updateBulkBar);
    });

    function postAction(action, id){
        var fd = new FormData();
        fd.append('pm_action', action);
        fd.append('pm_id', id);
        return fetch('finance-payments.php', { method: 'POST', body: fd })
            .then(function(r){ return r.json(); })
            .then(function(j){ return { ok: !!(j && j.success), id: id }; })
            .catch(function(){ return { ok: false, id: id }; });
    }

    function bulkRun(action){
        var ids = [];
        document.querySelectorAll('.row-check:checked').forEach(function(cb){
            var id = cb.getAttribute('data-id');
            if (id) ids.push(id);
        });
        if (!ids.length) return;

        var title = action === 'approve' ? 'Approve Selected' : 'Reject Selected';
        var message = action === 'approve' ? ('Approve ' + ids.length + ' selected payments?') : ('Reject ' + ids.length + ' selected payments?');
        var variant = action === 'approve' ? 'success' : 'danger';
        var confirmText = action === 'approve' ? 'Yes, approve' : 'Yes, reject';
        var api = window.showConfirm ? window.showConfirm({ title: title, message: message, confirmText: confirmText, variant: variant }) : Promise.resolve(window.confirm(message));

        api.then(function(ok){
            if (!ok) return;
            if (bulkApprove) bulkApprove.disabled = true;
            if (bulkReject) bulkReject.disabled = true;
            if (selectAll) selectAll.disabled = true;

            var failures = [];
            var i = 0;
            function next(){
                if (i >= ids.length) {
                    if (failures.length) { alert('Some actions failed (' + failures.length + '). Reloading…'); }
                    location.reload();
                    return;
                }
                var id = ids[i];
                i++;
                postAction(action, id).then(function(res){
                    if (!res.ok) failures.push(id);
                    next();
                });
            }
            next();
        });
    }

    if (bulkApprove) bulkApprove.addEventListener('click', function(){ bulkRun('approve'); });
    if (bulkReject) bulkReject.addEventListener('click', function(){ bulkRun('reject'); });

    applyFilter();
});
</script>
<?php require_once __DIR__ . '/includes/footer.php'; ?>

Youez - 2016 - github.com/yon3zu
LinuXploit