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

$pageTitle = 'Check Out';

if (!function_exists('h')) {
    function h($value): string
    {
        return htmlspecialchars((string)$value, ENT_QUOTES, 'UTF-8');
    }
}

if (!function_exists('money_fmt')) {
    function money_fmt($amount): string
    {
        return number_format((float)$amount, 2);
    }
}

if (!function_exists('folio_type_badge')) {
    function folio_type_badge(string $type): string
    {
        $type = strtolower(trim($type));

        switch ($type) {
            case 'master':
                return '<span class="badge text-bg-dark">Master</span>';
            case 'room':
                return '<span class="badge text-bg-primary">Room</span>';
            case 'guest':
                return '<span class="badge text-bg-info text-dark">Guest</span>';
            default:
                return '<span class="badge text-bg-secondary">' . h(ucfirst($type !== '' ? $type : 'Unknown')) . '</span>';
        }
    }
}


if (!function_exists('co_table_exists')) {
    function co_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 = :table_name
            ");
            $stmt->execute([':table_name' => $table]);
            $cache[$table] = ((int)$stmt->fetchColumn() > 0);
        } catch (Throwable $e) {
            $cache[$table] = false;
        }
        return $cache[$table];
    }
}

if (!function_exists('co_column_exists')) {
    function co_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 = :table_name
                  AND COLUMN_NAME = :column_name
            ");
            $stmt->execute([':table_name' => $table, ':column_name' => $column]);
            $cache[$key] = ((int)$stmt->fetchColumn() > 0);
        } catch (Throwable $e) {
            $cache[$key] = false;
        }
        return $cache[$key];
    }
}

if (!function_exists('co_payment_tx_types_sql')) {
    function co_payment_tx_types_sql(): string
    {
        return "'payment','receipt','deposit','payment_received','folio_payment','guest_payment'";
    }
}

if (!function_exists('co_reversal_tx_types_sql')) {
    function co_reversal_tx_types_sql(): string
    {
        return "'payment_void','void_payment','payment_reversal','reversal','refund','payment_refund'";
    }
}

if (!function_exists('co_extra_join_sql')) {
    function co_extra_join_sql(PDO $pdo): array
    {
        if (!co_table_exists($pdo, 'extra_charge_items')) {
            return ['', "''", "''"];
        }

        $itemNameExpr = co_column_exists($pdo, 'extra_charge_items', 'item_name') ? 'eci.item_name' : "''";
        $categoryExpr = co_column_exists($pdo, 'extra_charge_items', 'category_name') ? 'eci.category_name' : "''";
        $sourceExpr = co_column_exists($pdo, 'extra_charge_items', 'source_table') ? 'eci.source_table' : "''";

        return [
            ' LEFT JOIN extra_charge_items eci ON eci.folio_transaction_id = ft.id ',
            "LOWER(COALESCE($itemNameExpr, ''))",
            "LOWER(CONCAT(COALESCE($categoryExpr, ''), ' ', COALESCE($sourceExpr, '')))"
        ];
    }
}

if (!function_exists('co_category_case_sql')) {
    function co_category_case_sql(string $extraTextExpr = "''"): string
    {
        $tx = "LOWER(COALESCE(ft.tx_type,''))";
        $src = "LOWER(COALESCE(ft.source_table,''))";
        $desc = "LOWER(COALESCE(ft.description,''))";
        $x = $extraTextExpr;
        return "
            CASE
                WHEN $tx IN ('room_charge','accommodation','room','accommodation_charge','nightly','room_night')
                     OR $desc LIKE '%accommodation%' OR $desc LIKE '%room charge%' OR $desc LIKE '%night%'
                THEN 'Accommodation'
                WHEN $tx = 'restaurant' OR $src LIKE '%restaurant%' OR $desc LIKE '%restaurant%' OR $x LIKE '%restaurant%' OR $x LIKE '%food%'
                THEN 'Restaurant'
                WHEN $tx = 'bar' OR $desc LIKE '%bar%' OR $x LIKE '%bar%' OR $x LIKE '%drink%'
                THEN 'Bar'
                WHEN $tx IN ('spa','spar') OR $desc LIKE '%spa%' OR $desc LIKE '%spar%' OR $x LIKE '%spa%' OR $x LIKE '%spar%'
                THEN 'Spa'
                WHEN $tx = 'curio' OR $desc LIKE '%curio%' OR $src LIKE '%inventory%' OR $x LIKE '%curio%'
                THEN 'Curio'
                WHEN $tx IN ('extra','extras','extra_charge','addon','add_on','minibar','laundry','transfer','park_fee','activity','service')
                     OR $src IN ('tblservices','services','extras','order_extras','booking_extras','reservation_extras','order_extra_items','manual_extra','restaurant_menu_items','inventory_items')
                THEN 'Extras'
                ELSE 'Other'
            END
        ";
    }
}

if (!function_exists('co_empty_breakdown')) {
    function co_empty_breakdown(): array
    {
        $base = [
            'count' => 0,
            'charges' => 0.0,
            'payments' => 0.0,
            'balance' => 0.0,
            'categories' => [
                'Accommodation' => 0.0,
                'Restaurant' => 0.0,
                'Bar' => 0.0,
                'Spa' => 0.0,
                'Curio' => 0.0,
                'Extras' => 0.0,
                'Other' => 0.0,
            ],
        ];
        return [
            'master' => $base,
            'room'   => $base,
            'guest'  => $base,
            'other'  => $base,
            'total'  => $base,
        ];
    }
}

if (!function_exists('co_render_category_chips')) {
    function co_render_category_chips(array $categories): void
    {
        $labels = ['Accommodation', 'Restaurant', 'Bar', 'Spa', 'Curio', 'Extras', 'Other'];
        echo '<div class="category-chip-wrap">';
        foreach ($labels as $label) {
            $amount = (float)($categories[$label] ?? 0);
            if (abs($amount) <= 0.00001) {
                continue;
            }
            echo '<span class="category-chip category-' . h(strtolower($label)) . '"><small>' . h($label) . '</small><strong>' . money_fmt($amount) . '</strong></span>';
        }
        echo '</div>';
    }
}

if (!function_exists('co_fetch_live_folio_totals_map')) {
    function co_fetch_live_folio_totals_map(PDO $pdo, int $orderId): array
    {
        if ($orderId <= 0 || !co_table_exists($pdo, 'folios')) {
            return [];
        }

        [$extraJoin, $extraNameExpr, $extraTextExpr] = co_extra_join_sql($pdo);
        $categoryCase = co_category_case_sql("CONCAT($extraNameExpr, ' ', $extraTextExpr)");
        $paymentTypes = co_payment_tx_types_sql();
        $reversalTypes = co_reversal_tx_types_sql();

        $stmt = $pdo->prepare("
            SELECT
                x.folio_id,
                SUM(x.charge_amount) AS charges,
                SUM(x.payment_amount) AS payments,
                SUM(x.balance_amount) AS balance,
                SUM(CASE WHEN x.category = 'Accommodation' THEN x.charge_amount ELSE 0 END) AS accommodation_total,
                SUM(CASE WHEN x.category = 'Restaurant' THEN x.charge_amount ELSE 0 END) AS restaurant_total,
                SUM(CASE WHEN x.category = 'Bar' THEN x.charge_amount ELSE 0 END) AS bar_total,
                SUM(CASE WHEN x.category = 'Spa' THEN x.charge_amount ELSE 0 END) AS spa_total,
                SUM(CASE WHEN x.category = 'Curio' THEN x.charge_amount ELSE 0 END) AS curio_total,
                SUM(CASE WHEN x.category = 'Extras' THEN x.charge_amount ELSE 0 END) AS extras_total,
                SUM(CASE WHEN x.category = 'Other' THEN x.charge_amount ELSE 0 END) AS other_total
            FROM (
                SELECT
                    f.id AS folio_id,
                    CASE
                        WHEN ft.id IS NOT NULL
                             AND COALESCE(ft.is_voided,0) = 0
                             AND COALESCE(ft.debit,0) > 0
                             AND LOWER(COALESCE(ft.tx_type,'')) NOT IN ($paymentTypes,$reversalTypes)
                             AND LOWER(COALESCE(ft.description,'')) NOT LIKE '%void%'
                             AND LOWER(COALESCE(ft.description,'')) NOT LIKE '%reversal%'
                             AND LOWER(COALESCE(ft.description,'')) NOT LIKE '%refund%'
                        THEN COALESCE(ft.debit,0)
                        ELSE 0
                    END AS charge_amount,
                    CASE
                        WHEN ft.id IS NOT NULL
                             AND COALESCE(ft.is_voided,0) = 0
                             AND (
                                LOWER(COALESCE(ft.tx_type,'')) IN ($paymentTypes)
                                OR LOWER(COALESCE(ft.source_table,'')) IN ('payments','payment','receipts','receipt')
                             )
                        THEN COALESCE(ft.credit,0)
                        WHEN ft.id IS NOT NULL
                             AND COALESCE(ft.is_voided,0) = 0
                             AND LOWER(COALESCE(ft.tx_type,'')) IN ($reversalTypes)
                        THEN -1 * ABS(COALESCE(ft.debit,0) + LEAST(COALESCE(ft.credit,0),0))
                        ELSE 0
                    END AS payment_amount,
                    CASE
                        WHEN ft.id IS NOT NULL AND COALESCE(ft.is_voided,0) = 0
                        THEN COALESCE(ft.debit,0) - COALESCE(ft.credit,0)
                        ELSE 0
                    END AS balance_amount,
                    $categoryCase AS category
                FROM folios f
                LEFT JOIN folio_transactions ft ON ft.folio_id = f.id
                $extraJoin
                WHERE f.order_id = :order_id
            ) x
            GROUP BY x.folio_id
        ");
        $stmt->execute([':order_id' => $orderId]);
        $rows = $stmt->fetchAll(PDO::FETCH_ASSOC) ?: [];

        $map = [];
        foreach ($rows as $row) {
            $fid = (int)($row['folio_id'] ?? 0);
            if ($fid <= 0) {
                continue;
            }
            $map[$fid] = [
                'total_charges' => (float)($row['charges'] ?? 0),
                'total_payments' => max(0, (float)($row['payments'] ?? 0)),
                'balance' => (float)($row['balance'] ?? 0),
                'category_breakdown' => [
                    'Accommodation' => (float)($row['accommodation_total'] ?? 0),
                    'Restaurant' => (float)($row['restaurant_total'] ?? 0),
                    'Bar' => (float)($row['bar_total'] ?? 0),
                    'Spa' => (float)($row['spa_total'] ?? 0),
                    'Curio' => (float)($row['curio_total'] ?? 0),
                    'Extras' => (float)($row['extras_total'] ?? 0),
                    'Other' => (float)($row['other_total'] ?? 0),
                ],
            ];
        }
        return $map;
    }
}

if (!function_exists('fetch_order_room_mix')) {
    function fetch_order_room_mix(PDO $pdo, int $orderId): array
    {
        $stmt = $pdo->prepare("
            SELECT
                rmg.room_type_id,
                rt.title AS room_type_title,
                COUNT(*) AS qty_rooms,
                COALESCE(SUM(rmg.adults),0) AS adults,
                COALESCE(SUM(rmg.children),0) AS children
            FROM order_rooming rmg
            LEFT JOIN room_types rt ON rt.id = rmg.room_type_id
            WHERE rmg.order_id = :order_id
            GROUP BY rmg.room_type_id, rt.title
            ORDER BY rt.title ASC, rmg.room_type_id ASC
        ");
        $stmt->execute([':order_id' => $orderId]);
        $rows = $stmt->fetchAll(PDO::FETCH_ASSOC) ?: [];

        $parts = [];
        foreach ($rows as $row) {
            $label = trim((string)($row['room_type_title'] ?? ''));
            if ($label === '') {
                $label = 'Unknown';
            }
            $parts[] = $label . ' x ' . (int)($row['qty_rooms'] ?? 0);
        }

        return [
            'rows' => $rows,
            'text' => implode(', ', $parts),
        ];
    }
}


if (!function_exists('fetch_folio_balance_breakdown')) {
    function fetch_folio_balance_breakdown(PDO $pdo, int $orderId, int $roomingId = 0): array
    {
        $out = co_empty_breakdown();

        if ($orderId <= 0 || !co_table_exists($pdo, 'folios')) {
            return $out;
        }

        [$extraJoin, $extraNameExpr, $extraTextExpr] = co_extra_join_sql($pdo);
        $categoryCase = co_category_case_sql("CONCAT($extraNameExpr, ' ', $extraTextExpr)");
        $paymentTypes = co_payment_tx_types_sql();
        $reversalTypes = co_reversal_tx_types_sql();

        $whereRooming = '';
        $params = [':order_id' => $orderId];
        if ($roomingId > 0) {
            $whereRooming = ' AND f.rooming_id = :rooming_id ';
            $params[':rooming_id'] = $roomingId;
        }

        $stmt = $pdo->prepare("
            SELECT
                x.folio_type,
                COUNT(DISTINCT x.folio_id) AS folio_count,
                SUM(x.charge_amount) AS total_charges,
                SUM(x.payment_amount) AS total_payments,
                SUM(x.balance_amount) AS total_balance,
                SUM(CASE WHEN x.category = 'Accommodation' THEN x.charge_amount ELSE 0 END) AS accommodation_total,
                SUM(CASE WHEN x.category = 'Restaurant' THEN x.charge_amount ELSE 0 END) AS restaurant_total,
                SUM(CASE WHEN x.category = 'Bar' THEN x.charge_amount ELSE 0 END) AS bar_total,
                SUM(CASE WHEN x.category = 'Spa' THEN x.charge_amount ELSE 0 END) AS spa_total,
                SUM(CASE WHEN x.category = 'Curio' THEN x.charge_amount ELSE 0 END) AS curio_total,
                SUM(CASE WHEN x.category = 'Extras' THEN x.charge_amount ELSE 0 END) AS extras_total,
                SUM(CASE WHEN x.category = 'Other' THEN x.charge_amount ELSE 0 END) AS other_total
            FROM (
                SELECT
                    f.id AS folio_id,
                    LOWER(COALESCE(f.folio_type, 'other')) AS folio_type,
                    CASE
                        WHEN ft.id IS NOT NULL
                             AND COALESCE(ft.is_voided,0) = 0
                             AND COALESCE(ft.debit,0) > 0
                             AND LOWER(COALESCE(ft.tx_type,'')) NOT IN ($paymentTypes,$reversalTypes)
                             AND LOWER(COALESCE(ft.description,'')) NOT LIKE '%void%'
                             AND LOWER(COALESCE(ft.description,'')) NOT LIKE '%reversal%'
                             AND LOWER(COALESCE(ft.description,'')) NOT LIKE '%refund%'
                        THEN COALESCE(ft.debit,0)
                        ELSE 0
                    END AS charge_amount,
                    CASE
                        WHEN ft.id IS NOT NULL
                             AND COALESCE(ft.is_voided,0) = 0
                             AND (
                                LOWER(COALESCE(ft.tx_type,'')) IN ($paymentTypes)
                                OR LOWER(COALESCE(ft.source_table,'')) IN ('payments','payment','receipts','receipt')
                             )
                        THEN COALESCE(ft.credit,0)
                        WHEN ft.id IS NOT NULL
                             AND COALESCE(ft.is_voided,0) = 0
                             AND LOWER(COALESCE(ft.tx_type,'')) IN ($reversalTypes)
                        THEN -1 * ABS(COALESCE(ft.debit,0) + LEAST(COALESCE(ft.credit,0),0))
                        ELSE 0
                    END AS payment_amount,
                    CASE
                        WHEN ft.id IS NOT NULL AND COALESCE(ft.is_voided,0) = 0
                        THEN COALESCE(ft.debit,0) - COALESCE(ft.credit,0)
                        ELSE 0
                    END AS balance_amount,
                    $categoryCase AS category
                FROM folios f
                LEFT JOIN folio_transactions ft ON ft.folio_id = f.id
                $extraJoin
                WHERE f.order_id = :order_id
                {$whereRooming}
            ) x
            GROUP BY x.folio_type
        ");
        $stmt->execute($params);
        $rows = $stmt->fetchAll(PDO::FETCH_ASSOC) ?: [];

        foreach ($rows as $row) {
            $type = strtolower(trim((string)($row['folio_type'] ?? 'other')));
            if (!isset($out[$type])) {
                $type = 'other';
            }

            $count = (int)($row['folio_count'] ?? 0);
            $charges = (float)($row['total_charges'] ?? 0);
            $payments = max(0, (float)($row['total_payments'] ?? 0));
            $balance = (float)($row['total_balance'] ?? 0);
            $categories = [
                'Accommodation' => (float)($row['accommodation_total'] ?? 0),
                'Restaurant' => (float)($row['restaurant_total'] ?? 0),
                'Bar' => (float)($row['bar_total'] ?? 0),
                'Spa' => (float)($row['spa_total'] ?? 0),
                'Curio' => (float)($row['curio_total'] ?? 0),
                'Extras' => (float)($row['extras_total'] ?? 0),
                'Other' => (float)($row['other_total'] ?? 0),
            ];

            $out[$type]['count'] += $count;
            $out[$type]['charges'] += $charges;
            $out[$type]['payments'] += $payments;
            $out[$type]['balance'] += $balance;

            $out['total']['count'] += $count;
            $out['total']['charges'] += $charges;
            $out['total']['payments'] += $payments;
            $out['total']['balance'] += $balance;

            foreach ($categories as $label => $amount) {
                $out[$type]['categories'][$label] += $amount;
                $out['total']['categories'][$label] += $amount;
            }
        }

        return $out;
    }
}

if (!function_exists('fetch_open_balance_folios')) {
    function fetch_open_balance_folios(PDO $pdo, int $orderId, int $roomingId = 0): array
    {
        if ($orderId <= 0 || !co_table_exists($pdo, 'folios')) {
            return [];
        }

        $whereRooming = '';
        $params = [':order_id' => $orderId];
        if ($roomingId > 0) {
            $whereRooming = ' AND f.rooming_id = :rooming_id ';
            $params[':rooming_id'] = $roomingId;
        }

        $stmt = $pdo->prepare("
            SELECT
                f.id,
                f.folio_no,
                f.folio_name,
                f.folio_type,
                f.rooming_id,
                COALESCE(SUM(CASE WHEN COALESCE(ft.is_voided,0)=0 THEN COALESCE(ft.debit,0) - COALESCE(ft.credit,0) ELSE 0 END),0) AS balance
            FROM folios f
            LEFT JOIN folio_transactions ft ON ft.folio_id = f.id
            WHERE f.order_id = :order_id
              {$whereRooming}
            GROUP BY f.id, f.folio_no, f.folio_name, f.folio_type, f.rooming_id
            HAVING ABS(balance) > 0.00001
            ORDER BY
                CASE f.folio_type
                    WHEN 'master' THEN 1
                    WHEN 'room' THEN 2
                    WHEN 'guest' THEN 3
                    ELSE 9
                END,
                f.id ASC
        ");
        $stmt->execute($params);
        return $stmt->fetchAll(PDO::FETCH_ASSOC) ?: [];
    }
}


if (!function_exists('co_mark_order_checked_out_if_all_rooms_out')) {
    function co_mark_order_checked_out_if_all_rooms_out(PDO $pdo, int $orderId): bool
    {
        if ($orderId <= 0 || !co_table_exists($pdo, 'orders') || !co_table_exists($pdo, 'order_rooming')) {
            return false;
        }

        $stmt = $pdo->prepare("
            SELECT COUNT(*)
            FROM order_rooming
            WHERE order_id = :order_id
              AND COALESCE(checked_out_status, 0) <> 1
        ");
        $stmt->execute([':order_id' => $orderId]);
        $pendingRooms = (int)$stmt->fetchColumn();

        if ($pendingRooms > 0) {
            return false;
        }

        $sets = [];

        /*
           Use numeric 4 because this system stores checkout as status=4 in
           booking colour rules and status normalization. This avoids the issue
           where a text value like 'checked_out' can fail silently on numeric/enum
           status columns and leave the booking as provisional/part-paid colour.
        */
        if (co_column_exists($pdo, 'orders', 'status')) {
            $sets[] = "status = 4";
        }

        if (co_column_exists($pdo, 'orders', 'checked_out_status')) {
            $sets[] = "checked_out_status = 1";
        }

        if (co_column_exists($pdo, 'orders', 'checked_out_at')) {
            $sets[] = "checked_out_at = COALESCE(checked_out_at, NOW())";
        }

        if (co_column_exists($pdo, 'orders', 'updated_at')) {
            $sets[] = "updated_at = NOW()";
        }

        if (!$sets) {
            return false;
        }

        $stmt = $pdo->prepare("
            UPDATE orders
            SET " . implode(",\n                ", $sets) . "
            WHERE id = :order_id
        ");
        $stmt->execute([':order_id' => $orderId]);

        return true;
    }
}

if (!function_exists('mark_checked_out_rooms_dirty')) {
    function mark_checked_out_rooms_dirty(PDO $pdo, int $orderId, int $roomingId = 0): void
    {
        if ($orderId <= 0) {
            return;
        }

        $whereRooming = '';
        $params = [':order_id' => $orderId];

        if ($roomingId > 0) {
            $whereRooming = ' AND orm.id = :rooming_id ';
            $params[':rooming_id'] = $roomingId;
        }

        /*
           After checkout, the assigned physical room must become Dirty for housekeeping.
           We attempt housekeeping_status first. If an older rooms table does not have that
           column, we fall back to the generic status column.
        */
        try {
            $sql = "
                UPDATE rooms r
                INNER JOIN order_rooming orm ON orm.room_id = r.id
                SET r.housekeeping_status = 'dirty'
                WHERE orm.order_id = :order_id
                  AND COALESCE(orm.room_id, 0) > 0
                  {$whereRooming}
            ";
            $stmt = $pdo->prepare($sql);
            $stmt->execute($params);
        } catch (Throwable $e) {
            $sql = "
                UPDATE rooms r
                INNER JOIN order_rooming orm ON orm.room_id = r.id
                SET r.status = 'dirty'
                WHERE orm.order_id = :order_id
                  AND COALESCE(orm.room_id, 0) > 0
                  {$whereRooming}
            ";
            $stmt = $pdo->prepare($sql);
            $stmt->execute($params);
        }
    }
}

$orderId = (int)($_GET['order_id'] ?? $_POST['order_id'] ?? 0);
$errors = [];
$success = '';
$order = null;
$roomingRows = [];
$occupantMap = [];
$folioMap = [];
$guestFolioMap = [];
$roomBalanceMap = [];
$bookingFolios = [];
$bookingFolioBreakdown = [];
$roomMix = ['rows' => [], 'text' => ''];

if ($_SERVER['REQUEST_METHOD'] === 'POST' && isset($_POST['process_checkout'])) {
    $orderId = (int)($_POST['order_id'] ?? 0);
    $roomingId = (int)($_POST['rooming_id'] ?? 0);
    $forceCheckout = !empty($_POST['force_checkout']) ? 1 : 0;

    if ($orderId <= 0 || $roomingId <= 0) {
        $errors[] = 'Invalid booking or room slot.';
    }

    if (!$errors) {
        try {
            $stmt = $pdo->prepare("
                SELECT rmg.*
                FROM order_rooming rmg
                WHERE rmg.id = :id
                  AND rmg.order_id = :order_id
                LIMIT 1
            ");
            $stmt->execute([
                ':id'       => $roomingId,
                ':order_id' => $orderId,
            ]);
            $rooming = $stmt->fetch(PDO::FETCH_ASSOC);

            if (!$rooming) {
                throw new RuntimeException('Room slot not found.');
            }

            $roomBreakdown = fetch_folio_balance_breakdown($pdo, $orderId, $roomingId);
            $roomDepartureBalance = (float)($roomBreakdown['total']['balance'] ?? 0);
            $openRoomFolios = fetch_open_balance_folios($pdo, $orderId, $roomingId);

            if (!$forceCheckout && abs($roomDepartureBalance) > 0.00001) {
                $labels = [];
                foreach ($openRoomFolios as $of) {
                    $labels[] = ucfirst((string)$of['folio_type']) . ' ' . ($of['folio_no'] ?: ('#' . $of['id'])) . ' = ' . money_fmt($of['balance']);
                }
                throw new RuntimeException(
                    'This room still has unsettled room/guest folio balance(s): ' . implode('; ', $labels) . '. Tick "Force checkout" only if you intentionally want to close occupancy before settlement.'
                );
            }

            $pdo->beginTransaction();

            $pdo->prepare("
                UPDATE order_rooming
                SET
                    checked_out_status = 1,
                    checked_out_at = NOW()
                WHERE id = :id
                  AND order_id = :order_id
            ")->execute([
                ':id'       => $roomingId,
                ':order_id' => $orderId,
            ]);

            $pdo->prepare("
                UPDATE order_rooming_guests
                SET checked_out_at = NOW()
                WHERE rooming_id = :rooming_id
                  AND order_id = :order_id
                  AND checked_out_at IS NULL
            ")->execute([
                ':rooming_id' => $roomingId,
                ':order_id'   => $orderId,
            ]);

            mark_checked_out_rooms_dirty($pdo, $orderId, $roomingId);

            $pdo->prepare("
                UPDATE folios
                SET status = 0,
                    updated_at = NOW()
                WHERE order_id = :order_id
                  AND rooming_id = :rooming_id
                  AND folio_type IN ('room','guest')
            ")->execute([
                ':order_id'   => $orderId,
                ':rooming_id' => $roomingId,
            ]);

            /*
               If this was the last room to check out, update the main booking too.
               This is what drives the calendar colour rule ACTIVE_OUT
               (CHECKED_OUT + has_balance = red).
            */
            $bookingNowCheckedOut = co_mark_order_checked_out_if_all_rooms_out($pdo, $orderId);

            $pdo->commit();

            header('Location: check_out.php?order_id=' . $orderId . '&saved=1' . ($bookingNowCheckedOut ? '&booking_status_updated=1' : ''));
            exit;
        } catch (Throwable $e) {
            if ($pdo->inTransaction()) {
                $pdo->rollBack();
            }
            $errors[] = $e->getMessage();
        }
    }
}

if ($_SERVER['REQUEST_METHOD'] === 'POST' && isset($_POST['complete_booking_checkout'])) {
    $orderId = (int)($_POST['order_id'] ?? 0);
    $forceBookingCheckout = !empty($_POST['force_booking_checkout']) ? 1 : 0;

    if ($orderId <= 0) {
        $errors[] = 'Invalid booking selected.';
    }

    if (!$errors) {
        try {
            $stmt = $pdo->prepare("
                SELECT *
                FROM order_rooming
                WHERE order_id = :order_id
                ORDER BY id ASC
            ");
            $stmt->execute([':order_id' => $orderId]);
            $roomRows = $stmt->fetchAll(PDO::FETCH_ASSOC);

            $stmt = $pdo->prepare("
                SELECT *
                FROM folios
                WHERE order_id = :order_id
                ORDER BY id ASC
            ");
            $stmt->execute([':order_id' => $orderId]);
            $folioRows = $stmt->fetchAll(PDO::FETCH_ASSOC);
            $bookingBalanceBreakdown = fetch_folio_balance_breakdown($pdo, $orderId);

            $openRooms = [];
            foreach ($roomRows as $rr) {
                if ((int)($rr['checked_out_status'] ?? 0) !== 1) {
                    $openRooms[] = $rr;
                }
            }

            $openBalanceFolios = fetch_open_balance_folios($pdo, $orderId);

            if (!$forceBookingCheckout && !empty($openRooms)) {
                throw new RuntimeException('Some room slots are not yet checked out. Tick "Force complete booking checkout" only if you intentionally want to close the full booking.');
            }

            if (!$forceBookingCheckout && !empty($openBalanceFolios)) {
                $labels = [];
                foreach ($openBalanceFolios as $of) {
                    $labels[] = ucfirst((string)$of['folio_type']) . ' ' . ($of['folio_no'] ?: ('#' . $of['id'])) . ' = ' . money_fmt($of['balance']);
                }
                throw new RuntimeException(
                    'Some Master/Room/Guest folios still have balances: ' . implode('; ', $labels) . '. Tick "Force complete booking checkout" only if you intentionally want to close the full booking with unsettled balances.'
                );
            }

            $pdo->beginTransaction();

            $pdo->prepare("
                UPDATE order_rooming
                SET checked_out_status = 1,
                    checked_out_at = COALESCE(checked_out_at, NOW())
                WHERE order_id = :order_id
            ")->execute([
                ':order_id' => $orderId,
            ]);

            $pdo->prepare("
                UPDATE order_rooming_guests
                SET checked_out_at = COALESCE(checked_out_at, NOW())
                WHERE order_id = :order_id
            ")->execute([
                ':order_id' => $orderId,
            ]);

            mark_checked_out_rooms_dirty($pdo, $orderId);

            $pdo->prepare("
                UPDATE folios
                SET status = 0,
                    updated_at = NOW()
                WHERE order_id = :order_id
            ")->execute([
                ':order_id' => $orderId,
            ]);

            co_mark_order_checked_out_if_all_rooms_out($pdo, $orderId);

            $pdo->commit();

            header('Location: check_out.php?order_id=' . $orderId . '&booking_closed=1');
            exit;
        } catch (Throwable $e) {
            if ($pdo->inTransaction()) {
                $pdo->rollBack();
            }
            $errors[] = $e->getMessage();
        }
    }
}

if (isset($_GET['saved']) && (int)$_GET['saved'] === 1) {
    $success = 'Room checked out successfully.';
    if (isset($_GET['booking_status_updated']) && (int)$_GET['booking_status_updated'] === 1) {
        $success .= ' All rooms are now checked out, so the booking status was updated to Checked Out.';
    }
}
if (isset($_GET['booking_closed']) && (int)$_GET['booking_closed'] === 1) {
    $success = 'Booking checked out successfully.';
}

if ($orderId > 0) {
    $stmt = $pdo->prepare("
        SELECT
            o.*,
            g.firstname,
            g.lastname,
            rt.title AS room_type,
            p.name AS property_name,
            p.code AS property_code,
            CONCAT(COALESCE(a.firstname,''), ' ') AS agent_name
        FROM orders o
        LEFT JOIN guests g ON g.id = o.guest_id
        LEFT JOIN room_types rt ON rt.id = o.room_type_id
        LEFT JOIN properties p ON p.id = o.property_id
        LEFT JOIN agents a ON a.id = o.agent_id
        WHERE o.id = :id
        LIMIT 1
    ");
    $stmt->execute([':id' => $orderId]);
    $order = $stmt->fetch(PDO::FETCH_ASSOC);

    if (!$order) {
        $errors[] = 'Booking not found.';
        $orderId = 0;
    } else {
        $stmt = $pdo->prepare("
            SELECT rmg.*, rm.room_no AS actual_room_no, rt.title AS requested_room_type
            FROM order_rooming rmg
            LEFT JOIN rooms rm ON rm.id = rmg.room_id
            LEFT JOIN room_types rt ON rt.id = rmg.room_type_id
            WHERE rmg.order_id = :order_id
            ORDER BY
                CAST(COALESCE(NULLIF(TRIM(CAST(rm.room_no AS CHAR)), ''), NULLIF(TRIM(CAST(rmg.room_no AS CHAR)), ''), '999999') AS UNSIGNED),
                COALESCE(rm.room_no, rmg.room_no),
                rmg.id ASC
        ");
        $stmt->execute([':order_id' => $orderId]);
        $roomingRows = $stmt->fetchAll(PDO::FETCH_ASSOC);

        if ($roomingRows) {
            $roomingIds = array_map(function ($r) {
                return (int)$r['id'];
            }, $roomingRows);

            $placeholders = implode(',', array_fill(0, count($roomingIds), '?'));

            $stmt = $pdo->prepare("
                SELECT *
                FROM order_rooming_guests
                WHERE rooming_id IN ($placeholders)
                ORDER BY rooming_id ASC, is_primary DESC, id ASC
            ");
            $stmt->execute($roomingIds);
            $guestRows = $stmt->fetchAll(PDO::FETCH_ASSOC);

            foreach ($guestRows as $gr) {
                $rid = (int)$gr['rooming_id'];
                if (!isset($occupantMap[$rid])) {
                    $occupantMap[$rid] = [];
                }
                $occupantMap[$rid][] = $gr;
            }
        }

        $stmt = $pdo->prepare("
            SELECT *
            FROM folios
            WHERE order_id = :order_id
            ORDER BY
                CASE folio_type
                    WHEN 'master' THEN 1
                    WHEN 'room' THEN 2
                    WHEN 'guest' THEN 3
                    ELSE 9
                END,
                id ASC
        ");
        $stmt->execute([':order_id' => $orderId]);
        $bookingFolios = $stmt->fetchAll(PDO::FETCH_ASSOC);

        $liveFolioTotals = co_fetch_live_folio_totals_map($pdo, $orderId);
        foreach ($bookingFolios as &$bfLive) {
            $live = $liveFolioTotals[(int)($bfLive['id'] ?? 0)] ?? null;
            if ($live) {
                $bfLive['total_charges'] = $live['total_charges'];
                $bfLive['total_payments'] = $live['total_payments'];
                $bfLive['balance'] = $live['balance'];
                $bfLive['category_breakdown'] = $live['category_breakdown'];
            } else {
                $bfLive['category_breakdown'] = [];
            }
        }
        unset($bfLive);

        $bookingFolioBreakdown = fetch_folio_balance_breakdown($pdo, $orderId);

        foreach ($bookingFolios as $fr) {
            $rid = (int)($fr['rooming_id'] ?? 0);
            if ($rid > 0 && (string)($fr['folio_type'] ?? '') === 'room') {
                $folioMap[$rid] = $fr;
            }
            if ($rid > 0 && (string)($fr['folio_type'] ?? '') === 'guest') {
                if (!isset($guestFolioMap[$rid])) {
                    $guestFolioMap[$rid] = [];
                }
                $guestFolioMap[$rid][] = $fr;
            }
        }

        foreach ($roomingRows as $rr) {
            $roomBalanceMap[(int)$rr['id']] = fetch_folio_balance_breakdown($pdo, $orderId, (int)$rr['id']);
        }

        $roomMix = fetch_order_room_mix($pdo, $orderId);
    }
}

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

<div class="hero-band">
    <div class="row g-4 align-items-center">
        <div class="col-lg-8">
            <div class="page-eyebrow text-white-50"><i class="bi bi-door-closed"></i> Departure Desk</div>
            <div class="hero-title mt-2">Check Out</div>
            <div class="hero-subtitle mt-2">
                Review room occupants and folio balances before completing departure for each room slot or for the whole booking.
            </div>
        </div>
        <div class="col-lg-4 text-lg-end">
            <a href="/rooms/modules/reservations/reservation_list.php" class="btn btn-outline-light">
                <i class="bi bi-arrow-left me-2"></i>Back to Reservations
            </a>
        </div>
    </div>
</div>

<?php if ($success): ?>
    <div class="alert alert-success"><?php echo h($success); ?></div>
<?php endif; ?>

<?php if ($errors): ?>
    <div class="alert alert-danger">
        <div class="fw-bold mb-2">Please fix the following:</div>
        <ul class="mb-0">
            <?php foreach ($errors as $err): ?>
                <li><?php echo h($err); ?></li>
            <?php endforeach; ?>
        </ul>
    </div>
<?php endif; ?>

<div class="card panel-card mb-4">
    <div class="card-body">
        <form method="get" class="row g-3 align-items-end">
            <div class="col-md-8">
                <label class="form-label">Booking ID</label>
                <input type="number" name="order_id" class="form-control" value="<?php echo (int)$orderId; ?>" placeholder="Enter booking ID">
            </div>
            <div class="col-md-4 d-grid">
                <button class="btn btn-primary">Load Booking</button>
            </div>
        </form>
    </div>
</div>

<?php if ($order): ?>
    <?php
    $guestName = trim(($order['firstname'] ?? '') . ' ' . ($order['lastname'] ?? ''));
    if ($guestName === '') {
        $guestName = 'Guest';
    }

    $agentName = trim((string)($order['agent_name'] ?? ''));
    if ($agentName === '') {
        $agentName = 'Direct';
    }

    $propertyName = trim((string)($order['property_name'] ?? ''));
    if ($propertyName === '') {
        $propertyName = 'Not set';
    }
    $propertyLabel = $propertyName;
    if (!empty($order['property_code'])) {
        $propertyLabel .= ' (' . $order['property_code'] . ')';
    }

    $grandCharges = (float)($bookingFolioBreakdown['total']['charges'] ?? 0);
    $grandPayments = (float)($bookingFolioBreakdown['total']['payments'] ?? 0);
    $grandBalance = (float)($bookingFolioBreakdown['total']['balance'] ?? 0);
    $masterBalance = (float)($bookingFolioBreakdown['master']['balance'] ?? 0);
    $roomFoliosBalance = (float)($bookingFolioBreakdown['room']['balance'] ?? 0);
    $guestFoliosBalance = (float)($bookingFolioBreakdown['guest']['balance'] ?? 0);
    $allRoomsCheckedOut = true;

    foreach ($roomingRows as $rr) {
        if ((int)($rr['checked_out_status'] ?? 0) !== 1) {
            $allRoomsCheckedOut = false;
            break;
        }
    }
    ?>

    <div class="row g-4 mb-4">
        <div class="col-xl-4">
            <div class="form-section booking-summary-card compact-summary">
                <div class="form-section-title">
                    <i class="bi bi-journal-text"></i>
                    Booking Summary
                </div>

                <div class="summary-grid">
                    <div class="mini-stat summary-wide"><span>Property</span><strong><?php echo h($propertyLabel); ?></strong></div>
                    <div class="mini-stat"><span>Booking</span><strong><?php echo h($order['order_no'] ?: ('#' . $order['id'])); ?></strong></div>
                    <div class="mini-stat"><span>Guest</span><strong><?php echo h($guestName); ?></strong></div>
                    <div class="mini-stat"><span>Agent</span><strong><?php echo h($agentName); ?></strong></div>
                    <div class="mini-stat"><span>Total Rooms</span><strong><?php echo (int)($order['totalrooms'] ?? 1); ?></strong></div>
                    <div class="mini-stat"><span>Adults / Children</span><strong><?php echo (int)($order['adults'] ?? 0); ?>A / <?php echo (int)($order['kids'] ?? 0); ?>C</strong></div>
                    <div class="mini-stat summary-wide"><span>Stay</span><strong><?php echo h($order['check_in']); ?> to <?php echo h($order['check_out']); ?></strong></div>
                    <div class="mini-stat summary-wide"><span>Room Mix</span><strong><?php echo h($roomMix['text'] !== '' ? $roomMix['text'] : ($order['room_type'] ?: 'Not set')); ?></strong></div>
                </div>

                <div class="soft-divider"></div>

                <div class="summary-grid totals-grid">
                    <div class="mini-stat"><span>Charges</span><strong><?php echo money_fmt($grandCharges); ?></strong></div>
                    <div class="mini-stat"><span>Payments</span><strong><?php echo money_fmt($grandPayments); ?></strong></div>
                    <div class="mini-stat"><span>Balance</span><strong class="<?php echo abs($grandBalance) > 0.00001 ? 'balance-positive' : 'balance-zero'; ?>"><?php echo money_fmt($grandBalance); ?></strong></div>
                    <div class="mini-stat"><span>Master Balance</span><strong class="<?php echo abs($masterBalance) > 0.00001 ? 'balance-positive' : 'balance-zero'; ?>"><?php echo money_fmt($masterBalance); ?></strong></div>
                    <div class="mini-stat"><span>Room Folios</span><strong class="<?php echo abs($roomFoliosBalance) > 0.00001 ? 'balance-positive' : 'balance-zero'; ?>"><?php echo money_fmt($roomFoliosBalance); ?></strong></div>
                    <div class="mini-stat"><span>Guest Folios</span><strong class="<?php echo abs($guestFoliosBalance) > 0.00001 ? 'balance-positive' : 'balance-zero'; ?>"><?php echo money_fmt($guestFoliosBalance); ?></strong></div>
                    <div class="mini-stat"><span>Rooms Out</span><strong class="<?php echo $allRoomsCheckedOut ? 'balance-zero' : 'status-warning'; ?>"><?php echo $allRoomsCheckedOut ? 'Yes' : 'No'; ?></strong></div>
                </div>

                <?php if (!empty($bookingFolioBreakdown['total']['categories'])): ?>
                    <div class="soft-divider"></div>
                    <div class="category-breakdown-title">Live charge breakdown</div>
                    <?php co_render_category_chips($bookingFolioBreakdown['total']['categories']); ?>
                <?php endif; ?>
            </div>

            <?php if (!empty($roomMix['rows'])): ?>
                <div class="form-section mt-2 room-mix-section compact-summary">
                    <div class="form-section-title">
                        <i class="bi bi-grid-1x2"></i>
                        Room Mix Breakdown
                    </div>
                    <?php foreach ($roomMix['rows'] as $mx): ?>
                        <div class="mini-stat mb-3">
                            <span><?php echo h((string)($mx['room_type_title'] ?? 'Unknown')); ?></span>
                            <strong>
                                <?php echo (int)($mx['qty_rooms'] ?? 0); ?> room(s) •
                                <?php echo (int)($mx['adults'] ?? 0); ?>A /
                                <?php echo (int)($mx['children'] ?? 0); ?>C
                            </strong>
                        </div>
                    <?php endforeach; ?>
                </div>
            <?php endif; ?>

            <div class="form-section mt-3 checkout-action-section">
                <div class="form-section-title">
                    <i class="bi bi-door-closed"></i>
                    Complete Booking Checkout
                </div>

                <form method="post">
                    <input type="hidden" name="order_id" value="<?php echo (int)$order['id']; ?>">

                    <div class="mb-3 text-muted small">
                        This will mark all room slots and occupants as checked out and close all booking folios.
                    </div>

                    <div class="form-check mb-3">
                        <input class="form-check-input" type="checkbox" name="force_booking_checkout" value="1" id="force_booking_checkout">
                        <label class="form-check-label" for="force_booking_checkout">
                            Force complete booking checkout even if rooms or folios are not fully settled
                        </label>
                    </div>

                    <div class="d-grid">
                        <button type="submit" name="complete_booking_checkout" value="1" class="btn btn-danger btn-lg"
                                onclick="return confirm('Complete checkout for the entire booking?');">
                            <i class="bi bi-box-arrow-right me-2"></i>Complete Booking Checkout
                        </button>
                    </div>
                </form>
            </div>
        </div>

        <div class="col-xl-8">
            <div class="card panel-card">
                <div class="card-header">
                    <h5 class="mb-0">Room Departure Control</h5>
                </div>
                <div class="card-body">
                    <?php if (!$roomingRows): ?>
                        <div class="text-center text-muted py-4">No room slots found for this booking.</div>
                    <?php else: ?>
                        <div class="accordion" id="checkoutAccordion">
                            <?php foreach ($roomingRows as $idx => $room): ?>
                                <?php
                                $rid = (int)$room['id'];
                                $roomFolio = $folioMap[$rid] ?? null;
                                $guestFoliosForRoom = $guestFolioMap[$rid] ?? [];
                                $roomBreakdown = $roomBalanceMap[$rid] ?? fetch_folio_balance_breakdown($pdo, $orderId, $rid);
                                $occupants = $occupantMap[$rid] ?? [];
                                $collapseId = 'roomCollapse' . $rid;
                                $headingId = 'roomHeading' . $rid;
                                $isOpen = $idx === 0 ? 'show' : '';
                                $btnState = $idx === 0 ? '' : 'collapsed';
                                $roomAccountBalance = (float)($roomBreakdown['room']['balance'] ?? 0);
                                $guestAccountBalance = (float)($roomBreakdown['guest']['balance'] ?? 0);
                                $roomDepartureBalance = (float)($roomBreakdown['total']['balance'] ?? 0);
                                $checkedOut = (int)($room['checked_out_status'] ?? 0) === 1;
                                $requestedType = trim((string)($room['requested_room_type'] ?? ''));
                                ?>
                                <div class="accordion-item mb-3 border rounded-3 overflow-hidden">
                                    <h2 class="accordion-header" id="<?php echo $headingId; ?>">
                                        <button class="accordion-button <?php echo $btnState; ?>" type="button"
                                                data-bs-toggle="collapse"
                                                data-bs-target="#<?php echo $collapseId; ?>"
                                                aria-expanded="<?php echo $idx === 0 ? 'true' : 'false'; ?>"
                                                aria-controls="<?php echo $collapseId; ?>">
                                            <div class="w-100 d-flex justify-content-between align-items-center pe-3">
                                                <div>
                                                    <strong>Room Slot <?php echo (int)$idx + 1; ?></strong>
                                                    <div class="small text-muted">
                                                        Requested Type:
                                                        <?php echo h($requestedType !== '' ? $requestedType : 'Not set'); ?>
                                                        • Assigned Room:
                                                        <?php echo !empty($room['actual_room_no']) ? h($room['actual_room_no']) : 'Unassigned'; ?>
                                                        • <?php echo (int)($room['adults'] ?? 0); ?>A /
                                                        <?php echo (int)($room['children'] ?? 0); ?>C
                                                    </div>
                                                </div>
                                                <div class="text-end">
                                                    <?php if ($checkedOut): ?>
                                                        <span class="badge text-bg-success">Checked Out</span>
                                                    <?php else: ?>
                                                        <span class="badge text-bg-warning text-dark">In House</span>
                                                    <?php endif; ?>
                                                </div>
                                            </div>
                                        </button>
                                    </h2>

                                    <div id="<?php echo $collapseId; ?>"
                                         class="accordion-collapse collapse <?php echo $isOpen; ?>"
                                         aria-labelledby="<?php echo $headingId; ?>"
                                         data-bs-parent="#checkoutAccordion">
                                        <div class="accordion-body">
                                            <div class="row g-4">
                                                <div class="col-lg-7">
                                                    <h6 class="mb-3">Occupants</h6>
                                                    <?php if (!$occupants): ?>
                                                        <div class="text-muted">No occupants captured for this room slot.</div>
                                                    <?php else: ?>
                                                        <div class="table-responsive">
                                                            <table class="table table-modern align-middle mb-0">
                                                                <thead>
                                                                    <tr>
                                                                        <th>Name</th>
                                                                        <th>Primary</th>
                                                                        <th>Checked In</th>
                                                                        <th>Checked Out</th>
                                                                    </tr>
                                                                </thead>
                                                                <tbody>
                                                                    <?php foreach ($occupants as $occ): ?>
                                                                        <tr>
                                                                            <td><?php echo h(trim(($occ['first_name'] ?? '') . ' ' . ($occ['last_name'] ?? ''))); ?></td>
                                                                            <td>
                                                                                <?php if (!empty($occ['is_primary'])): ?>
                                                                                    <span class="badge text-bg-primary">Primary</span>
                                                                                <?php else: ?>
                                                                                    <span class="text-muted">—</span>
                                                                                <?php endif; ?>
                                                                            </td>
                                                                            <td><?php echo !empty($occ['checked_in_at']) ? h($occ['checked_in_at']) : '—'; ?></td>
                                                                            <td><?php echo !empty($occ['checked_out_at']) ? h($occ['checked_out_at']) : '—'; ?></td>
                                                                        </tr>
                                                                    <?php endforeach; ?>
                                                                </tbody>
                                                            </table>
                                                        </div>
                                                    <?php endif; ?>
                                                </div>

                                                <div class="col-lg-5">
                                                    <h6 class="mb-3">Folio & Departure</h6>

                                                    <div class="folio-box mb-3">
                                                        <div class="folio-line"><span>Requested Type</span><strong><?php echo h($requestedType !== '' ? $requestedType : 'Not set'); ?></strong></div>
                                                        <div class="folio-line"><span>Folio</span><strong><?php echo $roomFolio ? h($roomFolio['folio_no']) : 'No room folio'; ?></strong></div>
                                                        <div class="folio-line"><span>Type</span><strong><?php echo $roomFolio ? strip_tags(folio_type_badge((string)$roomFolio['folio_type'])) : '—'; ?></strong></div>
                                                        <div class="folio-line"><span>Room Charges</span><strong><?php echo money_fmt($roomBreakdown['room']['charges'] ?? 0); ?></strong></div>
                                                        <div class="folio-line"><span>Room Payments</span><strong><?php echo money_fmt($roomBreakdown['room']['payments'] ?? 0); ?></strong></div>
                                                        <div class="folio-line"><span>Room Account Balance</span><strong class="<?php echo abs($roomAccountBalance) > 0.00001 ? 'balance-positive' : 'balance-zero'; ?>"><?php echo money_fmt($roomAccountBalance); ?></strong></div>
                                                        <div class="folio-line"><span>Guest Folios Balance</span><strong class="<?php echo abs($guestAccountBalance) > 0.00001 ? 'balance-positive' : 'balance-zero'; ?>"><?php echo money_fmt($guestAccountBalance); ?></strong></div>
                                                        <div class="folio-line"><span>Total Departure Balance</span><strong class="<?php echo abs($roomDepartureBalance) > 0.00001 ? 'balance-positive' : 'balance-zero'; ?>"><?php echo money_fmt($roomDepartureBalance); ?></strong></div>
                                                        <?php if (!empty($roomBreakdown['total']['categories'])): ?>
                                                            <div class="folio-line folio-line-stack"><span>Charge Breakdown</span><div><?php co_render_category_chips($roomBreakdown['total']['categories']); ?></div></div>
                                                        <?php endif; ?>
                                                    </div>

                                                    <?php if ($roomFolio): ?>
                                                        <div class="d-grid gap-2 mb-3">
                                                            <a href="/rooms/modules/payments/folio_view.php?folio_id=<?php echo (int)$roomFolio['id']; ?>" class="btn btn-outline-primary">
                                                                <i class="bi bi-receipt me-2"></i>Open Folio
                                                            </a>
                                                        </div>
                                                    <?php endif; ?>

                                                    <?php if (!empty($guestFoliosForRoom)): ?>
                                                        <div class="guest-folio-mini mb-3">
                                                            <div class="small fw-bold mb-2">Guest Folios</div>
                                                            <?php foreach ($guestFoliosForRoom as $gf): ?>
                                                                <a href="/rooms/modules/payments/folio_view.php?folio_id=<?php echo (int)$gf['id']; ?>" class="guest-folio-link">
                                                                    <span><?php echo h($gf['occupant_name'] ?: $gf['folio_name']); ?></span>
                                                                    <strong class="<?php echo abs((float)($gf['balance'] ?? 0)) > 0.00001 ? 'balance-positive' : 'balance-zero'; ?>"><?php echo money_fmt($gf['balance'] ?? 0); ?></strong>
                                                                </a>
                                                            <?php endforeach; ?>
                                                        </div>
                                                    <?php endif; ?>

                                                    <?php if ($checkedOut): ?>
                                                        <div class="alert alert-success mb-0">
                                                            This room slot has already been checked out.
                                                        </div>
                                                    <?php else: ?>
                                                        <form method="post">
                                                            <input type="hidden" name="order_id" value="<?php echo (int)$order['id']; ?>">
                                                            <input type="hidden" name="rooming_id" value="<?php echo $rid; ?>">

                                                            <div class="form-check mb-3">
                                                                <input class="form-check-input" type="checkbox" name="force_checkout" value="1" id="force_checkout_<?php echo $rid; ?>">
                                                                <label class="form-check-label" for="force_checkout_<?php echo $rid; ?>">
                                                                    Force checkout even if Room or Guest folio still has balance
                                                                </label>
                                                            </div>

                                                            <div class="d-grid">
                                                                <button type="submit" name="process_checkout" value="1" class="btn btn-danger">
                                                                    <i class="bi bi-door-closed me-2"></i>Check Out This Room
                                                                </button>
                                                            </div>
                                                        </form>
                                                    <?php endif; ?>
                                                </div>
                                            </div>
                                        </div>
                                    </div>
                                </div>
                            <?php endforeach; ?>
                        </div>
                    <?php endif; ?>
                </div>
            </div>

            <?php if ($bookingFolios): ?>
                <div class="card panel-card mt-4">
                    <div class="card-header">
                        <h5 class="mb-0">Booking Folio Summary</h5>
                    </div>
                    <div class="card-body p-0">
                        <div class="table-responsive">
                            <table class="table table-modern align-middle mb-0">
                                <thead>
                                    <tr>
                                        <th>Folio</th>
                                        <th>Type</th>
                                        <th class="text-end">Charges</th>
                                        <th class="text-end">Payments</th>
                                        <th class="text-end">Balance</th>
                                        <th>Breakdown</th>
                                        <th class="text-end">Action</th>
                                    </tr>
                                </thead>
                                <tbody>
                                    <?php foreach ($bookingFolios as $bf): ?>
                                        <tr>
                                            <td>
                                                <div class="data-stack">
                                                    <strong><?php echo h($bf['folio_no']); ?></strong>
                                                    <small><?php echo h($bf['folio_name']); ?></small>
                                                </div>
                                            </td>
                                            <td><?php echo folio_type_badge((string)$bf['folio_type']); ?></td>
                                            <td class="text-end"><?php echo money_fmt($bf['total_charges']); ?></td>
                                            <td class="text-end"><?php echo money_fmt($bf['total_payments']); ?></td>
                                            <td class="text-end"><?php echo money_fmt($bf['balance']); ?></td>
                                            <td><?php co_render_category_chips($bf['category_breakdown'] ?? []); ?></td>
                                            <td class="text-end">
                                                <a href="/rooms/modules/payments/folio_view.php?folio_id=<?php echo (int)$bf['id']; ?>" class="btn btn-sm btn-outline-primary">
                                                    Open
                                                </a>
                                            </td>
                                        </tr>
                                    <?php endforeach; ?>
                                </tbody>
                                <tfoot>
                                    <tr>
                                        <th colspan="2" class="text-end">Totals</th>
                                        <th class="text-end"><?php echo money_fmt($grandCharges); ?></th>
                                        <th class="text-end"><?php echo money_fmt($grandPayments); ?></th>
                                        <th class="text-end"><?php echo money_fmt($grandBalance); ?></th>
                                        <th><?php co_render_category_chips($bookingFolioBreakdown['total']['categories'] ?? []); ?></th>
                                        <th></th>
                                    </tr>
                                </tfoot>
                            </table>
                        </div>
                    </div>
                </div>
            <?php endif; ?>

        </div>
    </div>

    <style>
        .form-section {
            height: auto !important;
            min-height: 0 !important;
            padding: 14px 16px !important;
            border-radius: 18px;
            background: #fff;
            border: 1px solid #eef2f7;
            box-shadow: 0 10px 28px rgba(15, 23, 42, 0.055);
        }

        .form-section-title {
            display: flex;
            align-items: center;
            gap: 8px;
            margin-bottom: 10px;
            font-size: 14px;
            font-weight: 800;
            color: #111827;
            letter-spacing: -0.01em;
        }

        .summary-grid {
            display: grid;
            grid-template-columns: 1fr;
            gap: 6px;
        }

        .mini-stat {
            display: flex;
            align-items: center;
            justify-content: space-between;
            gap: 12px;
            padding: 7px 0;
            margin-bottom: 0 !important;
            border-bottom: 1px dashed #edf1f5;
            line-height: 1.25;
        }

        .summary-grid .mini-stat {
            padding: 7px 8px;
            border: 1px solid #f1f5f9;
            border-radius: 12px;
            background: #fbfdff;
        }

        .mini-stat:last-child {
            margin-bottom: 0 !important;
        }

        .mini-stat span {
            color: #6b7280;
            font-size: 12px;
            font-weight: 600;
            white-space: nowrap;
        }

        .mini-stat strong {
            font-size: 13px;
            font-weight: 800;
            color: #111827;
            text-align: right;
        }

        .soft-divider {
            height: 1px;
            background: linear-gradient(to right, transparent, #dfe5ec, transparent);
            margin: 9px 0;
        }

        .room-mix-section {
            margin-top: 10px !important;
        }

        .room-mix-section .mini-stat {
            padding: 7px 8px;
            border: 1px solid #f1f5f9;
            border-radius: 12px;
            background: #fbfdff;
            margin-bottom: 6px !important;
        }

        .room-mix-section .mini-stat:last-child {
            margin-bottom: 0 !important;
        }

        .checkout-action-section {
            margin-top: 12px !important;
        }

        .checkout-action-section .text-muted.small {
            margin-bottom: 10px !important;
        }

        @media (min-width: 1400px) {
            .booking-summary-card .summary-grid {
                grid-template-columns: repeat(2, minmax(0, 1fr));
            }

            .booking-summary-card .summary-wide {
                grid-column: 1 / -1;
            }
        }

        @media (min-width: 1200px) {
            .col-xl-4 > .form-section:first-child {
                position: sticky;
                top: 92px;
            }
        }

        .balance-positive {
            color: #dc2626 !important;
        }

        .balance-zero {
            color: #16a34a !important;
        }

        .status-warning {
            color: #d97706 !important;
        }


        .guest-folio-mini{
            border:1px solid #eef2f7;
            border-radius:14px;
            padding:10px 12px;
            background:#fbfdff;
        }
        .guest-folio-link{
            display:flex;
            align-items:center;
            justify-content:space-between;
            gap:12px;
            padding:6px 0;
            border-top:1px dashed #e5e7eb;
            color:#111827;
            text-decoration:none;
        }
        .guest-folio-link:first-of-type{
            border-top:none;
        }
        .guest-folio-link span{
            font-size:12px;
            font-weight:700;
        }

        .folio-box{
            border:1px solid #e9ecef;
            border-radius:16px;
            padding:14px 16px;
            background:#fff;
        }
        .folio-line{
            display:flex;
            justify-content:space-between;
            gap:16px;
            padding:7px 0;
            border-bottom:1px dashed #eef2f7;
        }
        .folio-line:last-child{
            border-bottom:none;
        }
        .folio-line span{
            color:#6b7280;
        }


        .category-breakdown-title{
            font-size:12px;
            font-weight:900;
            color:#475569;
            text-transform:uppercase;
            letter-spacing:.05em;
            margin-bottom:7px;
        }
        .category-chip-wrap{
            display:flex;
            flex-wrap:wrap;
            gap:5px;
            justify-content:flex-start;
        }
        .category-chip{
            display:inline-flex;
            align-items:center;
            gap:5px;
            padding:4px 7px;
            border-radius:999px;
            border:1px solid #e5e7eb;
            background:#f8fafc;
            line-height:1;
            white-space:nowrap;
        }
        .category-chip small{
            font-size:10px;
            font-weight:800;
            color:#64748b;
            text-transform:uppercase;
        }
        .category-chip strong{
            font-size:11px;
            font-weight:900;
            color:#0f172a;
        }
        .category-restaurant{background:#fff7ed;border-color:#fed7aa;}
        .category-bar{background:#eff6ff;border-color:#bfdbfe;}
        .category-spa{background:#fdf2f8;border-color:#fbcfe8;}
        .category-curio{background:#f5f3ff;border-color:#ddd6fe;}
        .category-accommodation{background:#ecfdf5;border-color:#bbf7d0;}
        .folio-line-stack{align-items:flex-start;}
        .folio-line-stack > div{flex:1;display:flex;justify-content:flex-end;}
    </style>
<?php endif; ?>

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