<?php
declare(strict_types=1);

/**
 * modules/payments/pending_payments.php
 *
 * Unified Pending Payments (Client / Driver / Commission)
 * -------------------------------------------------------
 * Shows all rows from `pending_payments` and allows marking them paid
 * (partial or full) in-line. On save:
 *  - CLIENT      -> inserts into transactions (CHAUF_INCOME, income)
 *  - DRIVER      -> inserts into driver_payouts + transactions (DRIVER_PAYOUT, expense)
 *  - COMMISSION  -> inserts into partner_payouts + transactions (PARTNER_PAYOUT, expense)
 * Then updates/removes the `pending_payments` row accordingly.
 *
 * Upgrades:
 *  - If columns `invoice_id` / `invoice_no` exist in `pending_payments`,
 *    we display an "Invoice" column, search by invoice_no, and show it in the modal.
 */

require_once dirname(__DIR__, 2) . '/config/functions.php';
require_role(['MD','Accounts','Admin','Management']);

$user = current_user();
$cid  = (int)($user['company_id'] ?? 0);
if ($cid <= 0) redirect(url_public('login.php'));

$errors = [];
$notice = null;

/* ---------- Helpers ---------- */
function tbl_exists(string $t): bool {
  try { db()->query("SELECT 1 FROM `{$t}` LIMIT 1"); return true; } catch (Throwable $e) { return false; }
}
function col_exists(string $t, string $c): bool {
  try {
    $q = db()->prepare("
      SELECT 1
        FROM INFORMATION_SCHEMA.COLUMNS
       WHERE TABLE_SCHEMA = DATABASE()
         AND TABLE_NAME   = :t
         AND COLUMN_NAME  = :c
       LIMIT 1
    ");
    $q->execute([':t'=>$t, ':c'=>$c]);
    return (bool)$q->fetchColumn();
  } catch (Throwable $e) { return false; }
}

/** First assigned (primary) driver for a booking */
function primary_driver(int $bookingId): ?array {
  try {
    $q = db()->prepare("
      SELECT d.id, d.name
        FROM booking_vehicles bv
        INNER JOIN drivers d ON d.id = bv.driver_id
       WHERE bv.booking_id = :bid
       ORDER BY bv.sequence_order ASC, bv.id ASC
       LIMIT 1
    ");
    $q->execute([':bid'=>$bookingId]);
    $r = $q->fetch();
    return $r ? ['id'=>(int)$r['id'], 'name'=>(string)$r['name']] : null;
  } catch (Throwable $e) {
    return null;
  }
}

/** Partner id + name for a booking (if any) */
function booking_partner(int $companyId, int $bookingId): ?array {
  try {
    $q = db()->prepare("
      SELECT p.id, p.name
        FROM bookings b
        LEFT JOIN partners p ON p.id = b.partner_id
       WHERE b.company_id = :cid AND b.id = :bid
       LIMIT 1
    ");
    $q->execute([':cid'=>$companyId, ':bid'=>$bookingId]);
    $r = $q->fetch();
    if ($r && !empty($r['id'])) return ['id'=>(int)$r['id'], 'name'=>(string)$r['name']];
    return null;
  } catch (Throwable $e) {
    return null;
  }
}

/** Booking ref + client name + pickup (for display only) */
function booking_head(int $companyId, int $bookingId): array {
  try {
    $q = db()->prepare("
      SELECT booking_ref, client_name, pickup_date, pickup_time
        FROM bookings
       WHERE company_id=:cid AND id=:bid
       LIMIT 1
    ");
    $q->execute([':cid'=>$companyId, ':bid'=>$bookingId]);
    $r = $q->fetch();
    return [
      'booking_ref' => (string)($r['booking_ref'] ?? '#'.$bookingId),
      'client_name' => (string)($r['client_name'] ?? '—'),
      'pickup_dt'   => trim((string)($r['pickup_date'] ?? '').' '.(string)($r['pickup_time'] ?? '')),
    ];
  } catch (Throwable $e) {
    return ['booking_ref'=>'#'.$bookingId,'client_name'=>'—','pickup_dt'=>''];
  }
}

/* ---------- Feature flags for invoice linkage ---------- */
$pp_has_invoice_id = col_exists('pending_payments','invoice_id');
$pp_has_invoice_no = col_exists('pending_payments','invoice_no');

/* ---------- View / Filters ---------- */
$tab = (string)($_GET['view'] ?? 'pending'); // 'pending' | 'paid'

$today      = new DateTimeImmutable('today');
$monthStart = $today->modify('first day of this month');
$monthEnd   = $today->modify('last day of this month');

$typeFilter = (string)($_GET['type'] ?? 'all'); // all|client|driver|commission
$q          = trim((string)($_GET['q'] ?? '')); // search by ref/name/(invoice no if present)

$from = (string)($_GET['from'] ?? $monthStart->format('Y-m-01'));
$to   = (string)($_GET['to']   ?? $monthEnd->format('Y-m-d'));
if (!preg_match('/^\d{4}-\d{2}-\d{2}$/', $from)) $from = $monthStart->format('Y-m-d');
if (!preg_match('/^\d{4}-\d{2}-\d{2}$/', $to))   $to   = $monthEnd->format('Y-m-d');

$validTypes = ['all','client','driver','commission'];
if (!in_array($typeFilter, $validTypes, true)) $typeFilter = 'all';

/* ---------- Handle mark as paid (POST) ---------- */
if ($_SERVER['REQUEST_METHOD']==='POST' && ($_POST['action'] ?? '') === 'mark_pending_paid') {
  try {
    csrf_verify((string)($_POST['csrf'] ?? ''));

    $rowId  = (int)($_POST['row_id'] ?? 0);             // pending_payments.id
    $amt    = (float)($_POST['amount'] ?? 0);
    $when   = (string)($_POST['paid_at'] ?? '');
    $method = trim((string)($_POST['method'] ?? 'Bank Transfer'));
    $refIn  = trim((string)($_POST['reference'] ?? ''));
    $notes  = trim((string)($_POST['notes'] ?? ''));

    if ($rowId <= 0) throw new RuntimeException('Invalid pending row.');
    if ($amt <= 0)   throw new RuntimeException('Amount must be positive.');
    if ($when === '') $when = date('Y-m-d H:i:s');

    // Load the pending row (lock for update)
    $pdo = db();
    $pdo->beginTransaction();

    $sel = $pdo->prepare("SELECT * FROM pending_payments WHERE id=:id AND company_id=:cid LIMIT 1 FOR UPDATE");
    $sel->execute([':id'=>$rowId, ':cid'=>$cid]);
    $row = $sel->fetch();
    if (!$row) throw new RuntimeException('Pending row not found.');

    $bookingId  = (int)$row['booking_id'];
    $ptype      = (string)$row['type']; // 'client' | 'driver' | 'commission'
    $totalDue   = (float)$row['total_due'];
    $paidSoFar  = (float)$row['amount_paid'];
    $balance    = max(0.0, round($totalDue - $paidSoFar, 2));
    $bhead      = booking_head($cid, $bookingId);
    $bookingRef = $bhead['booking_ref'];

    if ($balance <= 0.0) throw new RuntimeException('Nothing outstanding.');
    if ($amt > $balance) throw new RuntimeException('Amount exceeds pending balance (£'.number_format($balance,2).').');

    /* 1) Post accounting + specific payout rows */
    if ($ptype === 'client') {
      // transactions: CHAUF_INCOME (income)
      if (!tbl_exists('transactions')) throw new RuntimeException('transactions table missing.');
      $tx = $pdo->prepare("
        INSERT INTO transactions
          (company_id, date, account_code, segment, type, amount, booking_id, reference, notes, created_at)
        VALUES
          (:cid, DATE(:paid_at), 'CHAUF_INCOME', 'Chauffeur', 'income',
           :amt, :bid, :ref, :notes, NOW())
      ");
      $tx->execute([
        ':cid'=>$cid,
        ':paid_at'=>$when,
        ':amt'=>$amt,
        ':bid'=>$bookingId,
        ':ref'=> $refIn !== '' ? $refIn : $bookingRef,
        ':notes'=> $notes !== '' ? $notes : ('Booking '.$bookingRef.' — client payment'),
      ]);
      if ($tx->rowCount() !== 1) throw new RuntimeException('Accounting insert failed.');

    } elseif ($ptype === 'driver') {
      // driver_payouts + transactions (DRIVER_PAYOUT, expense)
      $drv = primary_driver($bookingId);
      if (!$drv) throw new RuntimeException('No driver assigned for this booking.');

      if (!tbl_exists('driver_payouts')) throw new RuntimeException('driver_payouts table missing.');
      $ins = $pdo->prepare("
        INSERT INTO driver_payouts
          (company_id, booking_id, driver_id, amount, paid_at, method, reference, notes, created_at)
        VALUES
          (:cid,:bid,:did,:amt,:paid_at,:meth,:ref,:notes,NOW())
      ");
      $ins->execute([
        ':cid'=>$cid, ':bid'=>$bookingId, ':did'=>$drv['id'], ':amt'=>$amt,
        ':paid_at'=>$when,
        ':meth'=>$method !== '' ? $method : null,
        ':ref' =>$refIn  !== '' ? $refIn  : null,
        ':notes'=>$notes !== '' ? $notes  : null,
      ]);

      if (!tbl_exists('transactions')) throw new RuntimeException('transactions table missing.');
      $tx = $pdo->prepare("
        INSERT INTO transactions
          (company_id, date, account_code, segment, type, amount, booking_id, reference, notes, created_at)
        VALUES
          (:cid, DATE(:paid_at), 'DRIVER_PAYOUT', 'Chauffeur', 'expense',
           :amt, :bid, :ref, :notes, NOW())
      ");
      $tx->execute([
        ':cid'=>$cid,
        ':paid_at'=>$when,
        ':amt'=>$amt,
        ':bid'=>$bookingId,
        ':ref'=> $refIn !== '' ? $refIn : ('Driver payout for '.$bookingRef),
        ':notes'=> $notes !== '' ? $notes : null,
      ]);
      if ($tx->rowCount() !== 1) throw new RuntimeException('Accounting insert failed.');

    } elseif ($ptype === 'commission') {
      // partner_payouts + transactions (PARTNER_PAYOUT, expense)
      $partner = booking_partner($cid, $bookingId);
      if (!$partner) throw new RuntimeException('Partner not set for this booking.');

      if (!tbl_exists('partner_payouts')) throw new RuntimeException('partner_payouts table missing.');
      $ins = $pdo->prepare("
        INSERT INTO partner_payouts
          (company_id, booking_id, partner_id, amount, paid_at, method, reference, notes, created_at)
        VALUES
          (:cid,:bid,:pid,:amt,:paid_at,:meth,:ref,:notes,NOW())
      ");
      $ins->execute([
        ':cid'=>$cid, ':bid'=>$bookingId, ':pid'=>$partner['id'], ':amt'=>$amt,
        ':paid_at'=>$when,
        ':meth'=>$method !== '' ? $method : null,
        ':ref' =>$refIn  !== '' ? $refIn  : null,
        ':notes'=>$notes !== '' ? $notes  : null,
      ]);

      if (!tbl_exists('transactions')) throw new RuntimeException('transactions table missing.');
      $tx = $pdo->prepare("
        INSERT INTO transactions
          (company_id, date, account_code, segment, type, amount, booking_id, reference, notes, created_at)
        VALUES
          (:cid, DATE(:paid_at), 'PARTNER_PAYOUT', 'Chauffeur', 'expense',
           :amt, :bid, :ref, :notes, NOW())
      ");
      $tx->execute([
        ':cid'=>$cid,
        ':paid_at'=>$when,
        ':amt'=>$amt,
        ':bid'=>$bookingId,
        ':ref'=> $refIn !== '' ? $refIn : ('Partner payout for '.$bookingRef),
        ':notes'=> $notes !== '' ? $notes : null,
      ]);
      if ($tx->rowCount() !== 1) throw new RuntimeException('Accounting insert failed.');
    } else {
      throw new RuntimeException('Unknown pending type.');
    }

    /* 2) Update or clear pending row */
    $newPaid   = round($paidSoFar + $amt, 2);
    $newBal    = max(0.0, round($totalDue - $newPaid, 2));

    if ($newBal <= 0.0001) {
      // fully settled -> delete pending row
      $del = $pdo->prepare("DELETE FROM pending_payments WHERE id=:id AND company_id=:cid");
      $del->execute([':id'=>$rowId, ':cid'=>$cid]);
    } else {
      // partial -> update pending row
      $upd = $pdo->prepare("
        UPDATE pending_payments
           SET amount_paid = :paid,
               balance_due = :bal,
               updated_at  = NOW()
         WHERE id=:id AND company_id=:cid
      ");
      $upd->execute([
        ':paid'=>$newPaid,
        ':bal' =>$newBal,
        ':id'  =>$rowId,
        ':cid' =>$cid
      ]);
    }

    audit_log('pending.settle', 'booking', $bookingId, [
      'pending_id' => $rowId,
      'type'       => $ptype,
      'amount'     => $amt,
      'paid_at'    => $when,
      'new_paid'   => $newPaid,
      'new_balance'=> $newBal
    ]);

    $pdo->commit();

    // redirect back retaining filters
    $qs = http_build_query([
      'view'=>$tab, 'type'=>$typeFilter, 'q'=>$q, 'from'=>$from, 'to'=>$to, 'ok'=>1
    ]);
    redirect('pending_payments.php?'.$qs);

  } catch (Throwable $e) {
    if (isset($pdo) && $pdo->inTransaction()) $pdo->rollBack();
    $errors[] = (defined('APP_ENV') && APP_ENV==='dev') ? $e->getMessage() : 'Unable to record payment.';
  }
}

if (isset($_GET['ok'])) $notice = 'Payment recorded successfully.';

/* ---------- Load data ---------- */

/** Pending list */
$pending = ['client'=>[], 'driver'=>[], 'commission'=>[]];
$totals  = ['client'=>['paid'=>0.0,'bal'=>0.0], 'driver'=>['paid'=>0.0,'bal'=>0.0], 'commission'=>['paid'=>0.0,'bal'=>0.0]];
if ($tab === 'pending') {
  try {
    $where = "company_id = :cid AND status = 'pending'";
    $args  = [':cid'=>$cid];

    if ($typeFilter !== 'all') {
      $where .= " AND `type` = :t";
      $args[':t'] = $typeFilter;
    }

    $sql = "SELECT * FROM pending_payments WHERE $where ORDER BY created_at DESC, id DESC LIMIT 500";
    $stmt = db()->prepare($sql);
    $stmt->execute($args);
    $rows = $stmt->fetchAll();

    // Enrich with names (client/driver/partner)
    foreach ($rows as $r) {
      $type = (string)$r['type']; // client|driver|commission
      $bookingId = (int)$r['booking_id'];
      $head = booking_head($cid, $bookingId);

      $displayName = '—';
      if ($type === 'client') {
        $displayName = $head['client_name'];
      } elseif ($type === 'driver') {
        $drv = primary_driver($bookingId);
        $displayName = $drv ? $drv['name'] : '—';
      } elseif ($type === 'commission') {
        $par = booking_partner($cid, $bookingId);
        $displayName = $par ? $par['name'] : '—';
      }

      // Build display row
      $row = [
        'id'           => (int)$r['id'],
        'booking_id'   => $bookingId,
        'booking_ref'  => (string)$r['booking_ref'],
        'name'         => $displayName,
        'total'        => (float)$r['total_due'],
        'paid'         => (float)$r['amount_paid'],
        'balance'      => (float)$r['balance_due'],
        'created_at'   => (string)$r['created_at'],
        'updated_at'   => (string)$r['updated_at'],
        // Optional invoice linkage
        'invoice_id'   => $pp_has_invoice_id ? (int)($r['invoice_id'] ?? 0) : 0,
        'invoice_no'   => $pp_has_invoice_no ? (string)($r['invoice_no'] ?? '') : '',
      ];

      // Optional search filter (booking_ref / name / invoice_no if present)
      if ($q !== '') {
        $needle = mb_strtolower($q);
        $hay = mb_strtolower(
          $row['booking_ref'].' '.
          $row['name'].' '.
          ($row['invoice_no'] ?? '')
        );
        if (mb_strpos($hay, $needle) === false) continue;
      }

      $pending[$type][] = $row;
      $totals[$type]['paid'] += $row['paid'];
      $totals[$type]['bal']  += $row['balance'];
    }
  } catch (Throwable $e) {
    $errors[] = (defined('APP_ENV') && APP_ENV==='dev') ? $e->getMessage() : 'Unable to load pending payments.';
  }
}

/** Paid history (from transactions) */
$paidHistory = ['client'=>[], 'driver'=>[], 'commission'=>[]];
$paidTotals  = ['client'=>0.0, 'driver'=>0.0, 'commission'=>0.0];
if ($tab === 'paid') {
  try {
    // Map for each type -> account_code + tx type
    $defs = [
      'client'     => ['account'=>'CHAUF_INCOME',   'tx_type'=>'income'],
      'driver'     => ['account'=>'DRIVER_PAYOUT',  'tx_type'=>'expense'],
      'commission' => ['account'=>'PARTNER_PAYOUT', 'tx_type'=>'expense'],
    ];

    foreach ($defs as $t => $def) {
      if ($typeFilter !== 'all' && $typeFilter !== $t) continue;

      $sql = "
        SELECT t.id, t.date, t.amount, t.booking_id, t.reference, t.notes,
               b.booking_ref, b.client_name, b.partner_id, b.pickup_date, b.pickup_time
          FROM transactions t
          LEFT JOIN bookings b ON b.id = t.booking_id AND b.company_id = t.company_id
         WHERE t.company_id=:cid
           AND t.account_code=:acc
           AND t.type=:typ
           AND t.date BETWEEN :from AND :to
         ORDER BY t.date DESC, t.id DESC
         LIMIT 500
      ";
      $st = db()->prepare($sql);
      $st->execute([
        ':cid'=>$cid,
        ':acc'=>$def['account'],
        ':typ'=>$def['tx_type'],
        ':from'=>$from,
        ':to'=>$to,
      ]);
      $rows = $st->fetchAll();

      foreach ($rows as $r) {
        $name = '—';
        if ($t === 'client') {
          $name = (string)($r['client_name'] ?? '—');
        } elseif ($t === 'driver') {
          $drv = primary_driver((int)$r['booking_id']);
          $name = $drv ? $drv['name'] : '—';
        } else { // commission
          $par = booking_partner($cid, (int)$r['booking_id']);
          $name = $par ? $par['name'] : '—';
        }
        // Optional search
        if ($q !== '') {
          $needle = mb_strtolower($q);
          $hay = mb_strtolower(($r['booking_ref'] ?? '#'.$r['booking_id']).' '.$name);
          if (mb_strpos($hay, $needle) === false) continue;
        }

        $paidHistory[$t][] = [
          'date'        => (string)$r['date'],
          'booking_id'  => (int)$r['booking_id'],
          'booking_ref' => (string)($r['booking_ref'] ?? '#'.$r['booking_id']),
          'name'        => $name,
          'amount'      => (float)$r['amount'],
          'reference'   => (string)($r['reference'] ?? ''),
        ];
        $paidTotals[$t] += (float)$r['amount'];
      }
    }
  } catch (Throwable $e) {
    $errors[] = (defined('APP_ENV') && APP_ENV==='dev') ? $e->getMessage() : 'Unable to load paid history.';
  }
}

/* ---------- Render ---------- */
include dirname(__DIR__, 2) . '/includes/header.php';
?>
<div class="d-flex justify-content-between align-items-center mb-3">
  <div>
    <h1 class="h4 mb-0">Pending Payments</h1>
    <div class="text-muted">Clients, Drivers & Commission balances at a glance.</div>
  </div>
  <div class="btn-group" role="group" aria-label="Tabs">
    <?php
      $baseQs = fn($v) => http_build_query(['view'=>$v,'type'=>$typeFilter,'q'=>$q,'from'=>$from,'to'=>$to]);
    ?>
    <a class="btn btn-<?= $tab==='pending'?'primary':'outline-primary' ?>" href="?<?= e($baseQs('pending')) ?>">Pending</a>
    <a class="btn btn-<?= $tab==='paid'   ?'primary':'outline-primary' ?>" href="?<?= e($baseQs('paid')) ?>">Paid (history)</a>
  </div>
</div>

<?php if ($notice): ?><div class="alert alert-success"><?= e($notice) ?></div><?php endif; ?>
<?php if ($errors): ?>
  <div class="alert alert-danger"><ul class="mb-0"><?php foreach($errors as $er) echo '<li>'.e($er).'</li>'; ?></ul></div>
<?php endif; ?>

<!-- Filters -->
<div class="card shadow-sm mb-3">
  <div class="card-body">
    <form class="row g-2 align-items-end" method="get">
      <input type="hidden" name="view" value="<?= e($tab) ?>">
      <div class="col-md-2">
        <label class="form-label">Type</label>
        <select name="type" class="form-select">
          <option value="all"        <?= $typeFilter==='all'?'selected':'' ?>>All</option>
          <option value="client"     <?= $typeFilter==='client'?'selected':'' ?>>Clients</option>
          <option value="driver"     <?= $typeFilter==='driver'?'selected':'' ?>>Drivers</option>
          <option value="commission" <?= $typeFilter==='commission'?'selected':'' ?>>Commission</option>
        </select>
      </div>
      <div class="col-md-4">
        <label class="form-label"><?= $tab==='pending' ? 'Search' : 'Search (Ref / Name)' ?></label>
        <input class="form-control" name="q" value="<?= e($q) ?>" placeholder="<?= $pp_has_invoice_no ? 'Booking ref / name / invoice #' : 'Booking ref / name' ?>">
      </div>
      <?php if ($tab==='paid'): ?>
      <div class="col-md-2">
        <label class="form-label">From</label>
        <input type="date" class="form-control" name="from" value="<?= e($from) ?>">
      </div>
      <div class="col-md-2">
        <label class="form-label">To</label>
        <input type="date" class="form-control" name="to" value="<?= e($to) ?>">
      </div>
      <?php endif; ?>
      <div class="col-md-2 d-grid">
        <button class="btn btn-primary">Filter</button>
      </div>
    </form>
  </div>
</div>

<?php if ($tab === 'pending'): ?>

<!-- Summary cards -->
<div class="row g-3 mb-3">
  <?php
    $cards = [
      ['title'=>'Client Pending','k'=>'client','class'=>'border-primary','icon'=>'👤'],
      ['title'=>'Driver Pending','k'=>'driver','class'=>'border-success','icon'=>'🚗'],
      ['title'=>'Commission Pending','k'=>'commission','class'=>'border-warning','icon'=>'🤝'],
    ];
    foreach ($cards as $c):
      $k=$c['k']; $paid=$totals[$k]['paid']; $bal=$totals[$k]['bal'];
  ?>
  <div class="col-md-4">
    <div class="card shadow-sm <?= e($c['class']) ?>">
      <div class="card-body">
        <div class="d-flex justify-content-between align-items-center">
          <div>
            <div class="text-muted small"><?= e($c['icon'].' '.$c['title']) ?></div>
            <div class="h5 mb-0">£<?= number_format($bal,2) ?> <span class="small text-muted">balance</span></div>
          </div>
          <div class="text-end">
            <div class="small text-muted">Paid so far</div>
            <div class="fw-semibold">£<?= number_format($paid,2) ?></div>
          </div>
        </div>
      </div>
    </div>
  </div>
  <?php endforeach; ?>
</div>

<!-- Pending tables -->
<?php
$sections = [
  'client'     => ['title'=>'Client Payments Pending','cols'=>['Ref', ($pp_has_invoice_no?'Invoice':''), 'Client','Paid','Pending','Action']],
  'driver'     => ['title'=>'Driver Payments Pending','cols'=>['Ref', ($pp_has_invoice_no?'Invoice':''), 'Driver','Paid','Pending','Action']],
  'commission' => ['title'=>'Commission Payments Pending','cols'=>['Ref', ($pp_has_invoice_no?'Invoice':''), 'Partner','Paid','Pending','Action']],
];
foreach ($sections as $t => $meta):
  if ($typeFilter!=='all' && $typeFilter!==$t) continue;
  $rows = $pending[$t];
?>
<div class="card shadow-sm mb-4">
  <div class="card-header bg-white">
    <div class="d-flex justify-content-between align-items-center">
      <h2 class="h6 mb-0"><?= e($meta['title']) ?></h2>
      <span class="badge text-bg-<?= $t==='client'?'primary':($t==='driver'?'success':'warning') ?>">
        <?= count($rows) ?> pending
      </span>
    </div>
  </div>
  <div class="table-responsive">
    <table class="table align-middle mb-0">
      <thead class="table-light">
      <tr>
        <th style="width:18%"><?= e($meta['cols'][0]) ?></th>
        <?php if ($pp_has_invoice_no): ?><th style="width:16%"><?= e($meta['cols'][1]) ?></th><?php endif; ?>
        <th><?= e($meta['cols'][$pp_has_invoice_no?2:1]) ?></th>
        <th class="text-end"><?= e($meta['cols'][$pp_has_invoice_no?3:2]) ?></th>
        <th class="text-end"><?= e($meta['cols'][$pp_has_invoice_no?4:3]) ?></th>
        <th class="text-end" style="width:160px"><?= e($meta['cols'][$pp_has_invoice_no?5:4]) ?></th>
      </tr>
      </thead>
      <tbody>
      <?php if ($rows): foreach ($rows as $r): ?>
        <tr>
          <td><strong><?= e($r['booking_ref']) ?></strong></td>
          <?php if ($pp_has_invoice_no): ?>
            <td>
              <?php if (!empty($r['invoice_no'])): ?>
                <?php if ($pp_has_invoice_id && (int)$r['invoice_id']>0): ?>
                  <a href="<?= e(url_modules('invoices/view.php').'?id='.(int)$r['invoice_id']) ?>" class="text-decoration-none">
                    <?= e($r['invoice_no']) ?>
                  </a>
                <?php else: ?>
                  <span class="badge text-bg-light"><?= e($r['invoice_no']) ?></span>
                <?php endif; ?>
              <?php else: ?>
                <span class="text-muted">—</span>
              <?php endif; ?>
            </td>
          <?php endif; ?>
          <td><?= e($r['name']) ?></td>
          <td class="text-end">£<?= number_format($r['paid'],2) ?></td>
          <td class="text-end"><span class="badge text-bg-danger">£<?= number_format($r['balance'],2) ?></span></td>
          <td class="text-end">
            <button type="button"
                    class="btn btn-sm btn-dark js-pay"
                    data-row-id="<?= (int)$r['id'] ?>"
                    data-type="<?= e($t) ?>"
                    data-booking-id="<?= (int)$r['booking_id'] ?>"
                    data-ref="<?= e($r['booking_ref']) ?>"
                    data-name="<?= e($r['name']) ?>"
                    data-balance="<?= number_format($r['balance'],2,'.','') ?>"
                    <?php if ($pp_has_invoice_no): ?>data-invoice="<?= e($r['invoice_no']) ?>"<?php endif; ?>
                    >
              Mark Paid
            </button>
          </td>
        </tr>
      <?php endforeach; else: ?>
        <tr><td colspan="<?= $pp_has_invoice_no ? 6 : 5 ?>" class="text-center text-muted py-4">No pending rows.</td></tr>
      <?php endif; ?>
      </tbody>
    </table>
  </div>
</div>
<?php endforeach; ?>

<?php else: // Paid history ?>

<!-- Paid summary -->
<div class="row g-3 mb-3">
  <div class="col-md-4">
    <div class="card shadow-sm border-primary"><div class="card-body text-center">
      <div class="text-muted small">Clients (Income)</div>
      <div class="h5 mb-0">£<?= number_format($paidTotals['client'],2) ?></div>
    </div></div>
  </div>
  <div class="col-md-4">
    <div class="card shadow-sm border-success"><div class="card-body text-center">
      <div class="text-muted small">Drivers (Expense)</div>
      <div class="h5 mb-0">£<?= number_format($paidTotals['driver'],2) ?></div>
    </div></div>
  </div>
  <div class="col-md-4">
    <div class="card shadow-sm border-warning"><div class="card-body text-center">
      <div class="text-muted small">Commission (Expense)</div>
      <div class="h5 mb-0">£<?= number_format($paidTotals['commission'],2) ?></div>
    </div></div>
  </div>
</div>

<?php
$paidSections = [
  'client'     => ['title'=>'Client Payments (Income)','cols'=>['Date','Ref','Client','Amount']],
  'driver'     => ['title'=>'Driver Payouts (Expense)','cols'=>['Date','Ref','Driver','Amount']],
  'commission' => ['title'=>'Commission Payouts (Expense)','cols'=>['Date','Ref','Partner','Amount']],
];
foreach ($paidSections as $t => $meta):
  if ($typeFilter!=='all' && $typeFilter!==$t) continue;
  $rows = $paidHistory[$t];
?>
<div class="card shadow-sm mb-4">
  <div class="card-header bg-white">
    <h2 class="h6 mb-0"><?= e($meta['title']) ?></h2>
  </div>
  <div class="table-responsive">
    <table class="table align-middle mb-0">
      <thead class="table-light">
      <tr>
        <th style="width:14%"><?= e($meta['cols'][0]) ?></th>
        <th style="width:18%"><?= e($meta['cols'][1]) ?></th>
        <th><?= e($meta['cols'][2]) ?></th>
        <th class="text-end" style="width:16%"><?= e($meta['cols'][3]) ?></th>
      </tr>
      </thead>
      <tbody>
      <?php if ($rows): foreach ($rows as $r): ?>
        <tr>
          <td><?= e($r['date']) ?></td>
          <td><strong><?= e($r['booking_ref']) ?></strong></td>
          <td><?= e($r['name']) ?></td>
          <td class="text-end">£<?= number_format($r['amount'],2) ?></td>
        </tr>
      <?php endforeach; else: ?>
        <tr><td colspan="4" class="text-center text-muted py-4">No payments in this range.</td></tr>
      <?php endif; ?>
      </tbody>
    </table>
  </div>
</div>
<?php endforeach; ?>

<?php endif; ?>

<!-- Mark as Paid Modal -->
<div class="modal fade" id="payModal" tabindex="-1" aria-hidden="true">
  <div class="modal-dialog">
    <form class="modal-content" method="post">
      <input type="hidden" name="csrf" value="<?= e(csrf_token()) ?>">
      <input type="hidden" name="action" value="mark_pending_paid">
      <input type="hidden" name="row_id" id="mp_row_id">
      <input type="hidden" name="type" id="mp_type">
      <input type="hidden" name="booking_id" id="mp_booking_id">
      <div class="modal-header">
        <h5 class="modal-title" id="mp_title">Settle Pending</h5>
        <button type="button" class="btn-close" data-bs-dismiss="modal" aria-label="Close"></button>
      </div>
      <div class="modal-body">
        <div class="small text-muted mb-2" id="mp_sub"></div>
        <div class="row g-3">
          <div class="col-6">
            <label class="form-label">Amount (£)</label>
            <input type="number" class="form-control" step="0.01" min="0.01" id="mp_amount" name="amount" required>
          </div>
          <div class="col-6">
            <label class="form-label">Paid At</label>
            <input type="datetime-local" class="form-control" name="paid_at" value="<?= e(date('Y-m-d\TH:i')) ?>">
          </div>
          <div class="col-6">
            <label class="form-label">Method</label>
            <input class="form-control" name="method" value="Bank Transfer">
          </div>
          <div class="col-6">
            <label class="form-label">Reference</label>
            <input class="form-control" name="reference" placeholder="Txn ID / Note">
          </div>
          <div class="col-12">
            <label class="form-label">Notes</label>
            <textarea class="form-control" name="notes" rows="2" placeholder="Optional"></textarea>
          </div>
        </div>
      </div>
      <div class="modal-footer">
        <button class="btn btn-dark">Save Payment</button>
        <button type="button" class="btn btn-outline-secondary" data-bs-dismiss="modal">Cancel</button>
      </div>
    </form>
  </div>
</div>

<?php include dirname(__DIR__, 2) . '/includes/footer.php'; ?>

<script>
(function(){
  const payModal = new bootstrap.Modal(document.getElementById('payModal'));
  document.addEventListener('click', function(e){
    const btn = e.target.closest('.js-pay');
    if(!btn) return;

    const rowId  = btn.getAttribute('data-row-id');
    const type   = btn.getAttribute('data-type'); // client|driver|commission
    const bid    = btn.getAttribute('data-booking-id');
    const ref    = btn.getAttribute('data-ref') || '';
    const name   = btn.getAttribute('data-name') || '';
    const bal    = btn.getAttribute('data-balance') || '0.00';
    const inv    = btn.getAttribute('data-invoice') || '';

    document.getElementById('mp_row_id').value = rowId;
    document.getElementById('mp_type').value   = type;
    document.getElementById('mp_booking_id').value = bid;
    document.getElementById('mp_amount').value = bal;
    document.getElementById('mp_amount').setAttribute('max', bal);

    const titleMap = {client:'Client Payment', driver:'Driver Payout', commission:'Commission Payout'};
    document.getElementById('mp_title').textContent = (titleMap[type] || 'Settle Pending');

    let sub = ref + ' — ' + name + ' · Balance £' + Number(bal).toFixed(2);
    if (inv) sub += ' · Invoice ' + inv;
    document.getElementById('mp_sub').textContent = sub;

    payModal.show();
  });
})();
</script>
