<?php
require_once __DIR__ . '/../../includes/bootstrap.php';
require_login();

$pageTitle = 'Front Office Cashup';

if (!function_exists('h')) {
    function h($v): string { return htmlspecialchars((string)$v, ENT_QUOTES, 'UTF-8'); }
}
if (!function_exists('money_fmt')) {
    function money_fmt($v): string { return number_format((float)$v, 2); }
}
if (!function_exists('ro_table_exists')) {
    function ro_table_exists(PDO $pdo, string $table): bool {
        static $cache = [];
        if (array_key_exists($table, $cache)) return $cache[$table];
        try {
            $stmt = $pdo->prepare("SELECT COUNT(*) FROM information_schema.tables WHERE table_schema = DATABASE() AND table_name = :t");
            $stmt->execute([':t' => $table]);
            return $cache[$table] = ((int)$stmt->fetchColumn() > 0);
        } catch (Throwable $e) {
            return $cache[$table] = false;
        }
    }
}
if (!function_exists('ro_column_exists')) {
    function ro_column_exists(PDO $pdo, string $table, string $column): bool {
        static $cache = [];
        $key = $table . '.' . $column;
        if (array_key_exists($key, $cache)) return $cache[$key];
        try {
            $stmt = $pdo->prepare("SELECT COUNT(*) FROM information_schema.columns WHERE table_schema = DATABASE() AND table_name = :t AND column_name = :c");
            $stmt->execute([':t' => $table, ':c' => $column]);
            return $cache[$key] = ((int)$stmt->fetchColumn() > 0);
        } catch (Throwable $e) {
            return $cache[$key] = false;
        }
    }
}

if (!function_exists('ro_first_existing_column')) {
    function ro_first_existing_column(PDO $pdo, string $table, array $columns): ?string {
        foreach ($columns as $column) {
            if (ro_column_exists($pdo, $table, $column)) return $column;
        }
        return null;
    }
}
if (!function_exists('ro_sql_ident')) {
    function ro_sql_ident(string $name): string {
        return '`' . str_replace('`', '``', $name) . '`';
    }
}
if (!function_exists('ro_format_dt')) {
    function ro_format_dt($dt, string $fallback = '-'): string {
        $dt = trim((string)$dt);
        if ($dt === '' || strtotime($dt) === false) return $fallback;
        return date('d-M-Y H:i', strtotime($dt));
    }
}
if (!function_exists('ro_status_badge_class')) {
    function ro_status_badge_class(string $status): string {
        $status = strtolower(trim($status));
        switch ($status) {
            case 'open': return 'success';
            case 'sent': return 'warning text-dark';
            case 'preparing': return 'info text-dark';
            case 'served': return 'primary';
            case 'bill_requested': return 'dark';
            case 'closed': return 'secondary';
            case 'void': return 'danger';
            default: return 'light text-dark border';
        }
    }
}

/* ---------------------------------------------------------------------
   Filters
--------------------------------------------------------------------- */
$dateFrom = trim((string)($_GET['from'] ?? date('Y-m-d')));
$dateTo   = trim((string)($_GET['to'] ?? date('Y-m-d')));
if (strtotime($dateFrom) === false) $dateFrom = date('Y-m-d');
if (strtotime($dateTo) === false)   $dateTo   = date('Y-m-d');
if (strtotime($dateTo) < strtotime($dateFrom)) { $tmp = $dateFrom; $dateFrom = $dateTo; $dateTo = $tmp; }

$selectedCashiers = array_values(array_filter(array_map('trim', (array)($_GET['cashiers'] ?? []))));
$allCashiersMode  = empty($selectedCashiers);

$hasPayments       = ro_table_exists($pdo, 'restaurant_payments');
$hasOrderItems     = ro_table_exists($pdo, 'restaurant_order_items');
$hasCashierCol     = ro_column_exists($pdo, 'restaurant_orders', 'cashier_name');
$hasFolioPayments  = ro_table_exists($pdo, 'folio_transactions');
$cashierExpr       = $hasCashierCol ? "COALESCE(NULLIF(TRIM(ro.cashier_name),''),'Unassigned')" : "'Unassigned'";

$error = '';
$availableCashiers = [];
$summary = ['order_count' => 0, 'gross_sales' => 0.0, 'room_charged_total' => 0.0];
$methodTotals = [];   // method => ['count'=>n,'amount'=>x]
$gratuityTotal = 0.0;
$cashierRows = [];    // cashier => ['order_count'=>n,'gross_sales'=>x,'room_charged'=>x,'methods'=>[method=>amount]]
$voidSummary = ['order_count' => 0, 'would_be_total' => 0.0];
$detailOrders = [];
$frontDeskCollections = [];
$frontDeskTotal = 0.0;
$frontDeskCount = 0;
$frontDeskMethodTotals = [];
$combinedCollectionRows = [];

try {
    /* Cashier picker options: everyone who has closed a restaurant order in the last 120 days */
    if ($hasCashierCol) {
        $stmt = $pdo->prepare("
            SELECT DISTINCT $cashierExpr AS cashier_name
            FROM restaurant_orders ro
            WHERE ro.status = 'closed'
              AND ro.order_type = 'front_office'
              AND COALESCE(ro.closed_at, ro.updated_at, ro.opened_at) >= DATE_SUB(:today, INTERVAL 120 DAY)
            ORDER BY cashier_name ASC
        ");
        $stmt->execute([':today' => date('Y-m-d')]);
        $availableCashiers = array_column($stmt->fetchAll(PDO::FETCH_ASSOC), 'cashier_name');
    }

    $params = [
        ':from' => $dateFrom . ' 00:00:00',
        ':to'   => $dateTo . ' 23:59:59',
    ];
    $cashierFilterSql = '';
    if (!$allCashiersMode) {
        $ph = [];
        foreach ($selectedCashiers as $i => $c) {
            $key = ':c' . $i;
            $ph[] = $key;
            $params[$key] = $c;
        }
        $cashierFilterSql = " AND $cashierExpr IN (" . implode(',', $ph) . ")";
    }

    $closedWhere = "ro.status = 'closed' AND ro.order_type = 'front_office' AND COALESCE(ro.closed_at, ro.updated_at, ro.opened_at) BETWEEN :from AND :to" . $cashierFilterSql;

    /* Overall summary: order count, gross sales, room/folio charged total */
    $stmt = $pdo->prepare("
        SELECT
            COUNT(*) AS order_count,
            COALESCE(SUM(ro.total_amount),0) AS gross_sales,
            COALESCE(SUM(CASE WHEN LOWER(COALESCE(ro.payment_status,''))='room_charged' THEN ro.total_amount ELSE 0 END),0) AS room_charged_total
        FROM restaurant_orders ro
        WHERE $closedWhere
    ");
    $stmt->execute($params);
    $row = $stmt->fetch(PDO::FETCH_ASSOC) ?: [];
    $summary['order_count']        = (int)($row['order_count'] ?? 0);
    $summary['gross_sales']        = (float)($row['gross_sales'] ?? 0);
    $summary['room_charged_total'] = (float)($row['room_charged_total'] ?? 0);

    /* Payment method breakdown (posted payments only), scoped to closed orders in range */
    if ($hasPayments) {
        $stmt = $pdo->prepare("
            SELECT rp.payment_method AS method, COUNT(*) AS cnt, COALESCE(SUM(rp.amount),0) AS total
            FROM restaurant_payments rp
            INNER JOIN restaurant_orders ro ON ro.id = rp.restaurant_order_id
            WHERE rp.status = 'posted' AND $closedWhere
            GROUP BY rp.payment_method
            ORDER BY total DESC
        ");
        $stmt->execute($params);
        foreach ($stmt->fetchAll(PDO::FETCH_ASSOC) as $r) {
            $method = trim((string)$r['method']) ?: 'Other';
            $methodTotals[$method] = ['count' => (int)$r['cnt'], 'amount' => (float)$r['total']];
        }
    }
    if ($summary['room_charged_total'] > 0) {
        $roomCount = 0;
        $stmtRc = $pdo->prepare("SELECT COUNT(*) FROM restaurant_orders ro WHERE $closedWhere AND LOWER(COALESCE(ro.payment_status,''))='room_charged'");
        $stmtRc->execute($params);
        $roomCount = (int)$stmtRc->fetchColumn();
        $methodTotals['Room / Folio Charge'] = ['count' => $roomCount, 'amount' => $summary['room_charged_total']];
    }

    /* Gratuity collected (posted as its own line item on orders) */
    if ($hasOrderItems && ro_column_exists($pdo, 'restaurant_order_items', 'item_name')) {
        $stmt = $pdo->prepare("
            SELECT COALESCE(SUM(roi.line_total),0)
            FROM restaurant_order_items roi
            INNER JOIN restaurant_orders ro ON ro.id = roi.restaurant_order_id
            WHERE $closedWhere AND LOWER(TRIM(roi.item_name)) = 'gratuity'
        ");
        $stmt->execute($params);
        $gratuityTotal = (float)$stmt->fetchColumn();
    }

    /* Per-cashier order totals */
    $stmt = $pdo->prepare("
        SELECT
            $cashierExpr AS cashier_name,
            COUNT(*) AS order_count,
            COALESCE(SUM(ro.total_amount),0) AS gross_sales,
            COALESCE(SUM(CASE WHEN LOWER(COALESCE(ro.payment_status,''))='room_charged' THEN ro.total_amount ELSE 0 END),0) AS room_charged
        FROM restaurant_orders ro
        WHERE $closedWhere
        GROUP BY cashier_name
        ORDER BY gross_sales DESC
    ");
    $stmt->execute($params);
    foreach ($stmt->fetchAll(PDO::FETCH_ASSOC) as $r) {
        $cashierRows[$r['cashier_name']] = [
            'order_count'  => (int)$r['order_count'],
            'gross_sales'  => (float)$r['gross_sales'],
            'room_charged' => (float)$r['room_charged'],
            'methods'      => [],
        ];
    }

    /* Per-cashier per-method payment totals, folded into the same rows */
    if ($hasPayments) {
        $stmt = $pdo->prepare("
            SELECT $cashierExpr AS cashier_name, rp.payment_method AS method, COALESCE(SUM(rp.amount),0) AS total
            FROM restaurant_payments rp
            INNER JOIN restaurant_orders ro ON ro.id = rp.restaurant_order_id
            WHERE rp.status = 'posted' AND $closedWhere
            GROUP BY cashier_name, rp.payment_method
        ");
        $stmt->execute($params);
        foreach ($stmt->fetchAll(PDO::FETCH_ASSOC) as $r) {
            $cName  = $r['cashier_name'];
            $method = trim((string)$r['method']) ?: 'Other';
            if (!isset($cashierRows[$cName])) {
                $cashierRows[$cName] = ['order_count' => 0, 'gross_sales' => 0.0, 'room_charged' => 0.0, 'methods' => []];
            }
            $cashierRows[$cName]['methods'][$method] = (float)$r['total'];
        }
    }
    foreach ($cashierRows as $cName => $row) {
        if ($row['room_charged'] > 0) {
            $cashierRows[$cName]['methods']['Room / Folio Charge'] = $row['room_charged'];
        }
    }

    /* Void reconciliation: what was cancelled during the same window/cashier filter */
    $voidWhere = "ro.status = 'void' AND ro.order_type = 'front_office' AND COALESCE(ro.closed_at, ro.updated_at, ro.opened_at) BETWEEN :from AND :to" . $cashierFilterSql;
    $stmt = $pdo->prepare("
        SELECT COUNT(*) AS cnt, COALESCE(SUM(ro.total_amount),0) AS total
        FROM restaurant_orders ro
        WHERE $voidWhere
    ");
    $stmt->execute($params);
    $vr = $stmt->fetch(PDO::FETCH_ASSOC) ?: [];
    $voidSummary['order_count']     = (int)($vr['cnt'] ?? 0);
    $voidSummary['would_be_total']  = (float)($vr['total'] ?? 0);

    /* Detail list of closed orders in range for drill-down */
    $stmt = $pdo->prepare("
        SELECT ro.id, ro.order_no, ro.guest_name, ro.room_no, ro.total_amount, ro.payment_status, ro.close_method,
               $cashierExpr AS cashier_name, COALESCE(ro.closed_at, ro.updated_at, ro.opened_at) AS closed_when
        FROM restaurant_orders ro
        WHERE $closedWhere
        ORDER BY closed_when DESC
        LIMIT 500
    ");
    $stmt->execute($params);
    $detailOrders = $stmt->fetchAll(PDO::FETCH_ASSOC) ?: [];

    /*
       Front Desk collections:
       Read posted payment/receipt transactions captured directly on PMS folios.
       Restaurant transactions are excluded so Restaurant Cashup remains separate.
       Front Office POS Spa/Curio payments are already included above through
       restaurant_payments and must not be counted again here.
    */
    if ($hasFolioPayments) {
        $ftDateCol = ro_first_existing_column($pdo, 'folio_transactions', ['tx_date','transaction_date','payment_date','created_at']);
        $ftTypeCol = ro_first_existing_column($pdo, 'folio_transactions', ['tx_type','transaction_type','type']);
        $ftCreditCol = ro_first_existing_column($pdo, 'folio_transactions', ['credit','amount']);
        $ftDebitCol = ro_first_existing_column($pdo, 'folio_transactions', ['debit']);
        $ftDescCol = ro_first_existing_column($pdo, 'folio_transactions', ['description','notes','reference']);
        $ftSourceTableCol = ro_first_existing_column($pdo, 'folio_transactions', ['source_table']);
        $ftSourceIdCol = ro_first_existing_column($pdo, 'folio_transactions', ['source_id']);
        $ftCreatedByCol = ro_first_existing_column($pdo, 'folio_transactions', ['created_by','user_id','cashier_id']);
        $ftVoidedCol = ro_first_existing_column($pdo, 'folio_transactions', ['is_voided','voided','is_void']);
        $ftMethodCol = ro_first_existing_column($pdo, 'folio_transactions', ['payment_method','method','payment_type']);

        if ($ftDateCol && $ftTypeCol && $ftCreditCol) {
            $dateIdent = ro_sql_ident($ftDateCol);
            $typeIdent = ro_sql_ident($ftTypeCol);
            $creditIdent = ro_sql_ident($ftCreditCol);
            $debitExpr = $ftDebitCol ? "COALESCE(ft." . ro_sql_ident($ftDebitCol) . ",0)" : "0";
            $descExpr = $ftDescCol ? "COALESCE(ft." . ro_sql_ident($ftDescCol) . ",'')" : "''";
            $sourceTableExpr = $ftSourceTableCol ? "LOWER(COALESCE(ft." . ro_sql_ident($ftSourceTableCol) . ",''))" : "''";
            $sourceIdExpr = $ftSourceIdCol ? "ft." . ro_sql_ident($ftSourceIdCol) : "NULL";
            $createdByExpr = $ftCreatedByCol ? "ft." . ro_sql_ident($ftCreatedByCol) : "NULL";
            $methodExpr = $ftMethodCol
                ? "COALESCE(NULLIF(TRIM(ft." . ro_sql_ident($ftMethodCol) . "),''),'Front Desk Payment')"
                : "CASE
                     WHEN LOWER($descExpr) LIKE '%cash%' THEN 'Cash'
                     WHEN LOWER($descExpr) LIKE '%visa%' OR LOWER($descExpr) LIKE '%mastercard%' OR LOWER($descExpr) LIKE '%card%' OR LOWER($descExpr) LIKE '%pos%' THEN 'Card / POS'
                     WHEN LOWER($descExpr) LIKE '%transfer%' OR LOWER($descExpr) LIKE '%bank%' THEN 'Bank Transfer'
                     ELSE 'Front Desk Payment'
                   END";

            $voidFilter = $ftVoidedCol
                ? " AND COALESCE(ft." . ro_sql_ident($ftVoidedCol) . ",0)=0"
                : "";

            $sourceExclusions = "";
            if ($ftSourceTableCol) {
                $sourceExclusions = "
                  AND $sourceTableExpr NOT LIKE '%restaurant%'
                  AND $sourceTableExpr NOT LIKE '%front_office_pos%'
                  AND $sourceTableExpr NOT LIKE '%spa%'
                  AND $sourceTableExpr NOT LIKE '%curio%'";
            }

            $paymentTypes = "LOWER(TRIM(COALESCE(ft.$typeIdent,''))) IN
                ('payment','payments','receipt','deposit','payment_received',
                 'folio_payment','guest_payment','cash','card','pos',
                 'bank_transfer','transfer')";

            $amountExpr = "CASE
                WHEN COALESCE(ft.$creditIdent,0) > 0 THEN COALESCE(ft.$creditIdent,0)
                WHEN $debitExpr < 0 THEN ABS($debitExpr)
                ELSE 0
            END";

            $sqlFrontDesk = "
                SELECT
                    ft.id,
                    ft.$dateIdent AS collected_at,
                    $methodExpr AS payment_method,
                    $amountExpr AS amount,
                    $descExpr AS description,
                    $sourceTableExpr AS source_table,
                    $sourceIdExpr AS source_id,
                    $createdByExpr AS created_by,
                    ft.folio_id,
                    ft.order_id
                FROM folio_transactions ft
                WHERE ft.$dateIdent BETWEEN :fd_from AND :fd_to
                  AND $paymentTypes
                  AND ($amountExpr) > 0
                  $voidFilter
                  $sourceExclusions
                ORDER BY ft.$dateIdent DESC, ft.id DESC
                LIMIT 5000
            ";

            $stmtFd = $pdo->prepare($sqlFrontDesk);
            $stmtFd->execute([
                ':fd_from' => $dateFrom . ' 00:00:00',
                ':fd_to' => $dateTo . ' 23:59:59',
            ]);
            $frontDeskCollections = $stmtFd->fetchAll(PDO::FETCH_ASSOC) ?: [];

            foreach ($frontDeskCollections as $fdRow) {
                $amount = (float)($fdRow['amount'] ?? 0);
                $method = trim((string)($fdRow['payment_method'] ?? '')) ?: 'Front Desk Payment';
                $frontDeskTotal += $amount;
                $frontDeskCount++;
                if (!isset($frontDeskMethodTotals[$method])) {
                    $frontDeskMethodTotals[$method] = ['count'=>0,'amount'=>0.0];
                }
                $frontDeskMethodTotals[$method]['count']++;
                $frontDeskMethodTotals[$method]['amount'] += $amount;
            }
        }
    }
} catch (Throwable $e) {
    $error = $e->getMessage();
}

/* Build the ordered list of payment-method columns for the cashier pivot table */
$allMethods = array_keys($methodTotals);
foreach ($cashierRows as $row) {
    foreach (array_keys($row['methods']) as $m) {
        if (!in_array($m, $allMethods, true)) $allMethods[] = $m;
    }
}
usort($allMethods, function ($a, $b) {
    if ($a === 'Room / Folio Charge') return 1;
    if ($b === 'Room / Folio Charge') return -1;
    return strcmp($a, $b);
});

$spaCurioCollected = 0.0;
foreach ($methodTotals as $m) $spaCurioCollected += $m['amount'];

/* Combined Front Office collection totals: Spa/Curio POS + direct Front Desk PMS collections. */
$combinedMethodTotals = $methodTotals;
foreach ($frontDeskMethodTotals as $method => $row) {
    if (!isset($combinedMethodTotals[$method])) {
        $combinedMethodTotals[$method] = ['count'=>0,'amount'=>0.0];
    }
    $combinedMethodTotals[$method]['count'] += (int)$row['count'];
    $combinedMethodTotals[$method]['amount'] += (float)$row['amount'];
}
$totalCollected = $spaCurioCollected + $frontDeskTotal;
ksort($combinedMethodTotals);

require_once __DIR__ . '/../../includes/header.php';
?>

<div class="hero-band compact-restaurant-hero cashup-print-hide">
    <div class="d-flex justify-content-between align-items-center flex-wrap gap-2">
        <div>
            <div class="page-eyebrow text-white-50"><i class="bi bi-cash-stack"></i> Front Office</div>
            <div class="hero-title mt-1">Front Office Cashup</div>
            <div class="hero-subtitle mt-1">All non-restaurant collections: Front Desk payments plus Spa and Curio sales.</div>
        </div>
        <div class="d-flex gap-2 flex-wrap">
            <button type="button" class="btn btn-light btn-sm" onclick="window.print()"><i class="bi bi-printer me-1"></i>Print Cashup</button>
            <a class="btn btn-outline-light btn-sm" href="front_office_pos.php"><i class="bi bi-shop me-1"></i>Front Office POS</a>
            <a class="btn btn-outline-light btn-sm" href="restaurant_cashup.php"><i class="bi bi-receipt me-1"></i>Restaurant Cashup</a>
        </div>
    </div>
</div>

<?php if ($error): ?>
    <div class="alert alert-danger">Could not load cashup: <?php echo h($error); ?></div>
<?php endif; ?>

<div class="card panel-card mb-3 cashup-print-hide">
    <div class="card-body">
        <form method="get" class="row g-3 align-items-end">
            <div class="col-auto">
                <label class="form-label small mb-1">From</label>
                <input type="date" name="from" value="<?php echo h($dateFrom); ?>" class="form-control form-control-sm">
            </div>
            <div class="col-auto">
                <label class="form-label small mb-1">To</label>
                <input type="date" name="to" value="<?php echo h($dateTo); ?>" class="form-control form-control-sm">
            </div>
            <div class="col-12 col-md-auto flex-grow-1">
                <label class="form-label small mb-1 d-flex justify-content-between align-items-center">
                    <span>Cashiers</span>
                    <span class="cashier-toggle-links">
                        <a href="#" id="cashupSelectAll">All</a> ·
                        <a href="#" id="cashupSelectNone">None</a>
                    </span>
                </label>
                <div class="cashier-picker">
                    <?php if (!$availableCashiers): ?>
                        <span class="text-muted small">No cashiers found in the last 120 days.</span>
                    <?php else: foreach ($availableCashiers as $c): ?>
                        <label class="cashier-chip">
                            <input type="checkbox" name="cashiers[]" value="<?php echo h($c); ?>" <?php echo in_array($c, $selectedCashiers, true) ? 'checked' : ''; ?>>
                            <?php echo h($c); ?>
                        </label>
                    <?php endforeach; endif; ?>
                </div>
                <div class="form-text small">Leave everything unchecked to include <strong>all cashiers</strong>.</div>
            </div>
            <div class="col-auto">
                <button class="btn btn-primary btn-sm"><i class="bi bi-funnel me-1"></i>Run Cashup</button>
            </div>
        </form>
    </div>
</div>

<div class="cashup-scope mb-3">
    <strong><?php echo h(date('d M Y', strtotime($dateFrom))); ?><?php echo $dateFrom !== $dateTo ? ' – ' . h(date('d M Y', strtotime($dateTo))) : ''; ?></strong>
    &nbsp;|&nbsp;
    <?php if ($allCashiersMode): ?>
        <span>All Cashiers</span>
    <?php else: ?>
        <span>Cashier<?php echo count($selectedCashiers) > 1 ? 's' : ''; ?>: <?php echo h(implode(', ', $selectedCashiers)); ?></span>
    <?php endif; ?>
</div>

<div class="row g-3 mb-3 cashup-summary-cards">
    <div class="col-6 col-md-3">
        <div class="summary-card">
            <div class="summary-label">Total Front Office Collections</div>
            <div class="summary-value"><?php echo money_fmt($totalCollected); ?></div>
            <div class="summary-note">All non-restaurant money collected</div>
        </div>
    </div>
    <div class="col-6 col-md-3">
        <div class="summary-card">
            <div class="summary-label">Spa &amp; Curio Collections</div>
            <div class="summary-value"><?php echo money_fmt($spaCurioCollected); ?></div>
            <div class="summary-note"><?php echo number_format(array_sum(array_column($combinedMethodTotals, 'count'))); ?> payment entries</div>
        </div>
    </div>
    <div class="col-6 col-md-3">
        <div class="summary-card">
            <div class="summary-label">Front Desk Collections</div>
            <div class="summary-value"><?php echo money_fmt($frontDeskTotal); ?></div>
            <div class="summary-note"><?php echo number_format($frontDeskCount); ?> PMS payment transactions</div>
        </div>
    </div>
    <div class="col-6 col-md-3">
        <div class="summary-card">
            <div class="summary-label">Room / Folio Charges</div>
            <div class="summary-value"><?php echo money_fmt($summary['room_charged_total']); ?></div>
            <div class="summary-note">Not included in cash collected</div>
        </div>
    </div>
</div>

<?php
    $variance = round($summary['gross_sales'] - $spaCurioCollected, 2);
?>
<?php if (abs($variance) > 0.01): ?>
    <div class="alert alert-warning cashup-print-hide">
        <i class="bi bi-exclamation-triangle-fill me-1"></i>
        Gross sales (<?php echo money_fmt($summary['gross_sales']); ?>) and Spa/Curio accounted payments (<?php echo money_fmt($spaCurioCollected); ?>) differ by <?php echo money_fmt(abs($variance)); ?>.
        This can happen if a closed order has no posted payment on file &mdash; check the detail list below.
    </div>
<?php endif; ?>

<div class="card panel-card mb-3">
    <div class="card-header"><h5 class="mb-0">Payment Method Breakdown</h5></div>
    <div class="card-body p-0">
        <table class="table table-modern align-middle mb-0">
            <thead><tr><th>Method</th><th class="text-end">Transactions</th><th class="text-end">Amount</th><th class="text-end">% of Total</th></tr></thead>
            <tbody>
            <?php if (!$combinedMethodTotals): ?>
                <tr><td colspan="4" class="text-center text-muted py-4">No payments recorded for this filter.</td></tr>
            <?php else: foreach ($combinedMethodTotals as $method => $m): ?>
                <tr>
                    <td><?php echo h($method); ?></td>
                    <td class="text-end"><?php echo number_format($m['count']); ?></td>
                    <td class="text-end fw-bold"><?php echo money_fmt($m['amount']); ?></td>
                    <td class="text-end text-muted"><?php echo $totalCollected > 0 ? number_format(($m['amount'] / $totalCollected) * 100, 1) : '0.0'; ?>%</td>
                </tr>
            <?php endforeach; endif; ?>
            </tbody>
            <?php if ($combinedMethodTotals): ?>
            <tfoot>
                <tr class="table-light fw-bold">
                    <td>Total</td>
                    <td class="text-end"><?php echo number_format(array_sum(array_column($methodTotals, 'count'))); ?></td>
                    <td class="text-end"><?php echo money_fmt($totalCollected); ?></td>
                    <td class="text-end">100.0%</td>
                </tr>
            </tfoot>
            <?php endif; ?>
        </table>
    </div>
</div>

<div class="card panel-card mb-3">
    <div class="card-header"><h5 class="mb-0">Collection Source Breakdown</h5></div>
    <div class="card-body p-0">
        <table class="table table-modern align-middle mb-0">
            <thead><tr><th>Source</th><th class="text-end">Transactions</th><th class="text-end">Collected</th></tr></thead>
            <tbody>
                <tr>
                    <td><strong>Spa &amp; Curio POS</strong><div class="small text-muted">Front Office POS payments only</div></td>
                    <td class="text-end"><?php echo number_format(array_sum(array_column($methodTotals, 'count'))); ?></td>
                    <td class="text-end fw-bold"><?php echo money_fmt($spaCurioCollected); ?></td>
                </tr>
                <tr>
                    <td><strong>Front Desk / PMS</strong><div class="small text-muted">Direct folio payments and receipts; restaurant sources excluded</div></td>
                    <td class="text-end"><?php echo number_format($frontDeskCount); ?></td>
                    <td class="text-end fw-bold"><?php echo money_fmt($frontDeskTotal); ?></td>
                </tr>
            </tbody>
            <tfoot><tr class="table-light fw-bold"><td>Total Front Office Collections</td><td class="text-end"><?php echo number_format(array_sum(array_column($combinedMethodTotals, 'count'))); ?></td><td class="text-end"><?php echo money_fmt($totalCollected); ?></td></tr></tfoot>
        </table>
    </div>
</div>

<div class="card panel-card mb-3">
    <div class="card-header d-flex justify-content-between align-items-center">
        <h5 class="mb-0">Front Desk Collection Detail</h5>
        <small class="text-muted"><?php echo number_format($frontDeskCount); ?> transactions</small>
    </div>
    <div class="card-body p-0">
        <div class="table-responsive cashup-detail-wrap">
            <table class="table table-modern align-middle mb-0">
                <thead><tr><th>Date</th><th>Method</th><th>Description</th><th>Folio</th><th>Order</th><th class="text-end">Amount</th></tr></thead>
                <tbody>
                <?php if (!$frontDeskCollections): ?>
                    <tr><td colspan="6" class="text-center text-muted py-4">No direct Front Desk collections for this period.</td></tr>
                <?php else: foreach ($frontDeskCollections as $fd): ?>
                    <tr>
                        <td><?php echo h(ro_format_dt($fd['collected_at'] ?? '')); ?></td>
                        <td><?php echo h($fd['payment_method'] ?? 'Front Desk Payment'); ?></td>
                        <td><?php echo h($fd['description'] ?? ''); ?></td>
                        <td><?php echo !empty($fd['folio_id']) ? '#' . (int)$fd['folio_id'] : '-'; ?></td>
                        <td><?php echo !empty($fd['order_id']) ? '#' . (int)$fd['order_id'] : '-'; ?></td>
                        <td class="text-end fw-bold"><?php echo money_fmt($fd['amount'] ?? 0); ?></td>
                    </tr>
                <?php endforeach; endif; ?>
                </tbody>
            </table>
        </div>
    </div>
</div>

<div class="card panel-card mb-3">
    <div class="card-header"><h5 class="mb-0">Spa &amp; Curio POS Breakdown by Cashier</h5></div>
    <div class="card-body p-0">
        <div class="table-responsive">
            <table class="table table-modern align-middle mb-0">
                <thead>
                <tr>
                    <th>Cashier</th>
                    <th class="text-end">Orders</th>
                    <?php foreach ($allMethods as $m): ?><th class="text-end"><?php echo h($m); ?></th><?php endforeach; ?>
                    <th class="text-end">Gross Sales</th>
                </tr>
                </thead>
                <tbody>
                <?php if (!$cashierRows): ?>
                    <tr><td colspan="<?php echo 3 + count($allMethods); ?>" class="text-center text-muted py-4">No closed orders for this filter.</td></tr>
                <?php else: foreach ($cashierRows as $cName => $row): ?>
                    <tr>
                        <td class="fw-bold"><?php echo h($cName); ?></td>
                        <td class="text-end"><?php echo number_format($row['order_count']); ?></td>
                        <?php foreach ($allMethods as $m): ?>
                            <td class="text-end"><?php echo isset($row['methods'][$m]) && $row['methods'][$m] > 0 ? money_fmt($row['methods'][$m]) : '-'; ?></td>
                        <?php endforeach; ?>
                        <td class="text-end fw-bold"><?php echo money_fmt($row['gross_sales']); ?></td>
                    </tr>
                <?php endforeach; endif; ?>
                </tbody>
            </table>
        </div>
    </div>
</div>

<?php if ($voidSummary['order_count'] > 0): ?>
<div class="card panel-card mb-3">
    <div class="card-header"><h5 class="mb-0">Voided Orders (Reconciliation)</h5></div>
    <div class="card-body">
        <p class="mb-0">
            <strong><?php echo number_format($voidSummary['order_count']); ?></strong> order<?php echo $voidSummary['order_count'] === 1 ? '' : 's'; ?> voided in this period,
            with a would-be total of <strong><?php echo money_fmt($voidSummary['would_be_total']); ?></strong>. These are excluded from Gross Sales above.
        </p>
    </div>
</div>
<?php endif; ?>

<div class="card panel-card">
    <div class="card-header d-flex justify-content-between align-items-center flex-wrap gap-2">
        <h5 class="mb-0">Spa &amp; Curio Closed Sales (Detail)</h5>
        <small class="text-muted"><?php echo number_format(count($detailOrders)); ?> orders</small>
    </div>
    <div class="card-body p-0">
        <div class="table-responsive cashup-detail-wrap">
            <table class="table table-modern align-middle mb-0">
                <thead>
                <tr>
                    <th>Order</th>
                    <th>Guest / Client</th>
                    <th>Cashier</th>
                    <th>Room</th>
                    <th>Payment</th>
                    <th>Close Method</th>
                    <th class="text-end">Total</th>
                    <th>Closed</th>
                </tr>
                </thead>
                <tbody>
                <?php if (!$detailOrders): ?>
                    <tr><td colspan="8" class="text-center text-muted py-4">No closed orders found for this filter.</td></tr>
                <?php else: foreach ($detailOrders as $o): ?>
                    <tr>
                        <td><a href="front_office_pos.php?front_order_id=<?php echo (int)$o['id']; ?>"><?php echo h($o['order_no'] ?: ('#' . (int)$o['id'])); ?></a></td>
                        <td><?php echo h($o['guest_name'] ?: '-'); ?></td>
                        <td><?php echo h($o['cashier_name']); ?></td>
                        <td><?php echo h($o['room_no'] ?: 'Walk-in'); ?></td>
                        <td><span class="badge text-bg-<?php echo h(ro_status_badge_class((string)$o['payment_status'])); ?>"><?php echo h(ucwords(str_replace('_', ' ', (string)$o['payment_status'] ?: 'unpaid'))); ?></span></td>
                        <td><?php echo h($o['close_method'] ?: '-'); ?></td>
                        <td class="text-end fw-bold"><?php echo money_fmt($o['total_amount']); ?></td>
                        <td><?php echo h(ro_format_dt($o['closed_when'])); ?></td>
                    </tr>
                <?php endforeach; endif; ?>
                </tbody>
            </table>
        </div>
    </div>
</div>

<style>
.compact-restaurant-hero{padding:12px 16px!important;margin-bottom:10px!important}
.panel-card{border-radius:16px;box-shadow:0 12px 30px rgba(15,23,42,.07);border:1px solid #e5e7eb}
.table-modern thead th{font-size:.70rem;text-transform:uppercase;letter-spacing:.05em;color:#64748b;background:#f8fafc;white-space:nowrap}
.table-modern td,.table-modern th{padding:.55rem .7rem;border-bottom:1px solid #eef2f7;font-size:.83rem;vertical-align:middle}
.cashup-detail-wrap{max-height:480px;overflow:auto}

.cashier-picker{display:flex;flex-wrap:wrap;gap:6px;border:1px solid #e5e7eb;border-radius:10px;padding:8px;max-height:120px;overflow:auto}
.cashier-chip{display:inline-flex;align-items:center;gap:5px;background:#f8fafc;border:1px solid #e5e7eb;border-radius:999px;padding:4px 10px;font-size:.78rem;cursor:pointer}
.cashier-chip input{margin:0}
.cashier-toggle-links a{font-size:.75rem;text-decoration:none}

.cashup-scope{font-size:.85rem;color:#334155}

.summary-card{background:#fff;border:1px solid #e5e7eb;border-radius:14px;padding:14px 16px;height:100%}
.summary-label{font-size:.7rem;text-transform:uppercase;letter-spacing:.06em;color:#64748b}
.summary-value{font-size:1.35rem;font-weight:800;color:#111827;margin-top:2px}
.summary-note{font-size:.72rem;color:#64748b;margin-top:3px}

@media print{
    .cashup-print-hide{display:none!important}
    .cashier-picker{border:none}
    .cashup-detail-wrap{max-height:none;overflow:visible}
}
</style>

<script>
document.addEventListener('DOMContentLoaded', function () {
    var selectAll = document.getElementById('cashupSelectAll');
    var selectNone = document.getElementById('cashupSelectNone');
    var boxes = document.querySelectorAll('.cashier-picker input[type="checkbox"]');

    if (selectAll) {
        selectAll.addEventListener('click', function (e) {
            e.preventDefault();
            boxes.forEach(function (b) { b.checked = true; });
        });
    }
    if (selectNone) {
        selectNone.addEventListener('click', function (e) {
            e.preventDefault();
            boxes.forEach(function (b) { b.checked = false; });
        });
    }
});
</script>

<?php require_once __DIR__ . '/../../includes/footer.php'; ?>
