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

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('na_table_exists')) {
    function na_table_exists(PDO $pdo, string $tableName): bool {
        $stmt = $pdo->prepare("SELECT COUNT(*) FROM information_schema.tables WHERE table_schema = DATABASE() AND table_name = :t");
        $stmt->execute([':t' => $tableName]);
        return (int)$stmt->fetchColumn() > 0;
    }
}
if (!function_exists('na_column_exists')) {
    function na_column_exists(PDO $pdo, string $tableName, string $columnName): bool {
        $stmt = $pdo->prepare("SELECT COUNT(*) FROM information_schema.columns WHERE table_schema = DATABASE() AND table_name = :t AND column_name = :c");
        $stmt->execute([':t' => $tableName, ':c' => $columnName]);
        return (int)$stmt->fetchColumn() > 0;
    }
}
if (!function_exists('na_guest_name')) {
    function na_guest_name(array $row): string {
        $name = trim((string)($row['firstname'] ?? '') . ' ' . (string)($row['lastname'] ?? ''));
        return $name !== '' ? $name : 'Guest';
    }
}
if (!function_exists('na_property_label')) {
    function na_property_label(array $row): string {
        $name = trim((string)($row['property_name'] ?? ''));
        $code = trim((string)($row['property_code'] ?? ''));
        if ($name !== '' && $code !== '') return $name . ' (' . $code . ')';
        return $name !== '' ? $name : ($code !== '' ? $code : '—');
    }
}
if (!function_exists('na_agent_name')) {
    function na_agent_name(array $row): string {
        $name = trim((string)($row['agent_name'] ?? ''));
        return $name !== '' ? $name : 'Direct';
    }
}
if (!function_exists('na_safe_date')) {
    function na_safe_date(string $date): string {
        return strtotime($date) !== false ? date('Y-m-d', strtotime($date)) : date('Y-m-d');
    }
}

$auditDate = na_safe_date(trim((string)($_GET['audit_date'] ?? date('Y-m-d'))));
$propertyId = (int)($_GET['property_id'] ?? 0);
$generatedAt = date('Y-m-d H:i:s');

$errors = [];
$properties = [];
$propertyName = 'All Properties';

$summary = [
    'rooms_total' => 0,
    'rooms_occupied' => 0,
    'rooms_vacant' => 0,
    'occupancy_pct' => 0,
    'arrivals_pending' => 0,
    'departures_pending' => 0,
    'dirty_rooms' => 0,
    'ooo_rooms' => 0,
    'open_balance_bookings' => 0,
    'charges_total' => 0,
    'payments_total' => 0,
    'balance_total' => 0,
];

$arrivalsPending = [];
$departuresPending = [];
$openBalanceBookings = [];
$dirtyRooms = [];
$outOfOrderRooms = [];

$restaurantSummary = [
    'orders_total' => 0,
    'orders_closed' => 0,
    'orders_open' => 0,
    'gross_sales' => 0,
    'room_charged_total' => 0,
    'direct_payments_total' => 0,
    'open_order_total' => 0,
];
$restaurantOrders = [];
$restaurantPaymentRows = [];

try {
    if (na_table_exists($pdo, 'properties')) {
        $stmt = $pdo->query("SELECT id, name, code FROM properties WHERE is_active = 1 ORDER BY name ASC");
        $properties = $stmt->fetchAll(PDO::FETCH_ASSOC);
        if ($propertyId > 0) {
            foreach ($properties as $p) {
                if ((int)$p['id'] === $propertyId) {
                    $propertyName = trim((string)$p['name'] . (!empty($p['code']) ? ' (' . $p['code'] . ')' : ''));
                    break;
                }
            }
        }
    }
} catch (Throwable $e) {
    $errors[] = 'Properties: ' . $e->getMessage();
}

$roomPropertySql = '';
$orderPropertySql = '';
$paramsBase = [];
if ($propertyId > 0) {
    $roomPropertySql = " AND r.property_id = ? ";
    $orderPropertySql = " AND o.property_id = ? ";
    $paramsBase[] = $propertyId;
}

try {
    $stmt = $pdo->prepare("SELECT COUNT(*) FROM rooms r WHERE 1=1 $roomPropertySql");
    $stmt->execute($paramsBase);
    $summary['rooms_total'] = (int)$stmt->fetchColumn();
} catch (Throwable $e) { $errors[] = 'Rooms Total: ' . $e->getMessage(); }

try {
    $sql = "
        SELECT COUNT(DISTINCT rmg.room_id)
        FROM order_rooming rmg
        INNER JOIN orders o ON o.id = rmg.order_id
        INNER JOIN rooms r ON r.id = rmg.room_id
        WHERE DATE(o.check_in) <= ?
          AND DATE(o.check_out) >= ?
          AND rmg.room_id IS NOT NULL
          $orderPropertySql
    ";
    $params = [$auditDate, $auditDate];
    if ($propertyId > 0) $params[] = $propertyId;
    $stmt = $pdo->prepare($sql);
    $stmt->execute($params);
    $summary['rooms_occupied'] = (int)$stmt->fetchColumn();
} catch (Throwable $e) { $errors[] = 'Rooms Occupied: ' . $e->getMessage(); }

$summary['rooms_vacant'] = max(0, $summary['rooms_total'] - $summary['rooms_occupied']);
$summary['occupancy_pct'] = $summary['rooms_total'] > 0 ? round(($summary['rooms_occupied'] / $summary['rooms_total']) * 100, 2) : 0;

try {
    $sql = "
        SELECT o.*, p.name AS property_name, p.code AS property_code, g.firstname, g.lastname,
               CONCAT(COALESCE(a.firstname,''), ' ', COALESCE(a.lastname,'')) AS agent_name,
               (SELECT COUNT(*) FROM order_rooming r1 WHERE r1.order_id = o.id) AS room_slots_total,
               (SELECT COUNT(*) FROM order_rooming r2 WHERE r2.order_id = o.id AND COALESCE(r2.checked_in_status,0) = 1) AS room_slots_checked_in
        FROM orders o
        LEFT JOIN properties p ON p.id = o.property_id
        LEFT JOIN guests g ON g.id = o.guest_id
        LEFT JOIN agents a ON a.id = o.agent_id
        WHERE DATE(o.check_in) = ? $orderPropertySql
        ORDER BY p.name ASC, o.id DESC
    ";
    $params = [$auditDate];
    if ($propertyId > 0) $params[] = $propertyId;
    $stmt = $pdo->prepare($sql);
    $stmt->execute($params);
    foreach ($stmt->fetchAll(PDO::FETCH_ASSOC) as $row) {
        $total = (int)($row['room_slots_total'] ?? 0);
        $checked = (int)($row['room_slots_checked_in'] ?? 0);
        if ($total === 0 || $checked < $total) $arrivalsPending[] = $row;
    }
    $summary['arrivals_pending'] = count($arrivalsPending);
} catch (Throwable $e) { $errors[] = 'Arrivals Pending: ' . $e->getMessage(); }

try {
    $sql = "
        SELECT o.*, p.name AS property_name, p.code AS property_code, g.firstname, g.lastname,
               CONCAT(COALESCE(a.firstname,''), ' ', COALESCE(a.lastname,'')) AS agent_name,
               (SELECT COUNT(*) FROM order_rooming r1 WHERE r1.order_id = o.id) AS room_slots_total,
               (SELECT COUNT(*) FROM order_rooming r2 WHERE r2.order_id = o.id AND COALESCE(r2.checked_out_status,0) = 1) AS room_slots_checked_out,
               (SELECT COALESCE(SUM(f.balance),0) FROM folios f WHERE f.order_id = o.id) AS booking_balance
        FROM orders o
        LEFT JOIN properties p ON p.id = o.property_id
        LEFT JOIN guests g ON g.id = o.guest_id
        LEFT JOIN agents a ON a.id = o.agent_id
        WHERE DATE(o.check_out) = ? $orderPropertySql
        ORDER BY p.name ASC, o.id DESC
    ";
    $params = [$auditDate];
    if ($propertyId > 0) $params[] = $propertyId;
    $stmt = $pdo->prepare($sql);
    $stmt->execute($params);
    foreach ($stmt->fetchAll(PDO::FETCH_ASSOC) as $row) {
        $total = (int)($row['room_slots_total'] ?? 0);
        $checked = (int)($row['room_slots_checked_out'] ?? 0);
        if ($total === 0 || $checked < $total) $departuresPending[] = $row;
    }
    $summary['departures_pending'] = count($departuresPending);
} catch (Throwable $e) { $errors[] = 'Departures Pending: ' . $e->getMessage(); }

try {
    $sql = "
        SELECT o.*, p.name AS property_name, p.code AS property_code, g.firstname, g.lastname,
               CONCAT(COALESCE(a.firstname,''), ' ', COALESCE(a.lastname,'')) AS agent_name,
               (SELECT COALESCE(SUM(f.total_charges),0) FROM folios f WHERE f.order_id = o.id) AS booking_charges,
               (SELECT COALESCE(SUM(f.total_payments),0) FROM folios f WHERE f.order_id = o.id) AS booking_payments,
               (SELECT COALESCE(SUM(f.balance),0) FROM folios f WHERE f.order_id = o.id) AS booking_balance
        FROM orders o
        LEFT JOIN properties p ON p.id = o.property_id
        LEFT JOIN guests g ON g.id = o.guest_id
        LEFT JOIN agents a ON a.id = o.agent_id
        WHERE DATE(o.check_in) <= ? AND DATE(o.check_out) >= ? $orderPropertySql
        ORDER BY p.name ASC, o.check_out ASC, o.id DESC
    ";
    $params = [$auditDate, $auditDate];
    if ($propertyId > 0) $params[] = $propertyId;
    $stmt = $pdo->prepare($sql);
    $stmt->execute($params);
    foreach ($stmt->fetchAll(PDO::FETCH_ASSOC) as $row) {
        $summary['charges_total'] += (float)($row['booking_charges'] ?? 0);
        $summary['payments_total'] += (float)($row['booking_payments'] ?? 0);
        $summary['balance_total'] += (float)($row['booking_balance'] ?? 0);
        if (abs((float)($row['booking_balance'] ?? 0)) > 0.00001) $openBalanceBookings[] = $row;
    }
    $summary['open_balance_bookings'] = count($openBalanceBookings);
} catch (Throwable $e) { $errors[] = 'Open Balance Bookings: ' . $e->getMessage(); }

try {
    $statusExpr = na_column_exists($pdo, 'rooms', 'housekeeping_status') ? "COALESCE(LOWER(r.housekeeping_status), LOWER(r.status), '')" : "LOWER(r.status)";
    $sql = "
        SELECT r.*, p.name AS property_name, p.code AS property_code, rt.title AS room_type
        FROM rooms r
        LEFT JOIN properties p ON p.id = r.property_id
        LEFT JOIN room_types rt ON rt.id = r.room_type_id
        WHERE $statusExpr = 'dirty' $roomPropertySql
        ORDER BY p.name ASC, r.room_no ASC
    ";
    $stmt = $pdo->prepare($sql);
    $stmt->execute($paramsBase);
    $dirtyRooms = $stmt->fetchAll(PDO::FETCH_ASSOC);
    $summary['dirty_rooms'] = count($dirtyRooms);
} catch (Throwable $e) { $errors[] = 'Dirty Rooms: ' . $e->getMessage(); }

try {
    $statusExpr = na_column_exists($pdo, 'rooms', 'housekeeping_status') ? "COALESCE(LOWER(r.housekeeping_status), LOWER(r.status), '')" : "LOWER(r.status)";
    $sql = "
        SELECT r.*, p.name AS property_name, p.code AS property_code, rt.title AS room_type
        FROM rooms r
        LEFT JOIN properties p ON p.id = r.property_id
        LEFT JOIN room_types rt ON rt.id = r.room_type_id
        WHERE $statusExpr IN ('out_of_order','ooo','maintenance','blocked') $roomPropertySql
        ORDER BY p.name ASC, r.room_no ASC
    ";
    $stmt = $pdo->prepare($sql);
    $stmt->execute($paramsBase);
    $outOfOrderRooms = $stmt->fetchAll(PDO::FETCH_ASSOC);
    $summary['ooo_rooms'] = count($outOfOrderRooms);
} catch (Throwable $e) { $errors[] = 'Out Of Order Rooms: ' . $e->getMessage(); }


try {
    if (na_table_exists($pdo, 'restaurant_orders')) {
        /*
            Restaurant audit uses positional placeholders only.
            This avoids PDO HY093 on servers where repeated named parameters
            like :audit_date are not allowed inside one prepared statement.
        */
        $restaurantPropertySql = '';
        $restaurantParams = [$auditDate, $auditDate];
        if ($propertyId > 0 && na_column_exists($pdo, 'restaurant_orders', 'property_id')) {
            $restaurantPropertySql = " AND (ro.property_id = ? OR ro.property_id IS NULL) ";
            $restaurantParams[] = $propertyId;
        }

        $orderNameExpr = na_column_exists($pdo, 'restaurant_orders', 'order_name') ? "COALESCE(ro.order_name,'') AS order_name," : "'' AS order_name,";
        $mealExpr = na_column_exists($pdo, 'restaurant_orders', 'meal_period') ? "COALESCE(ro.meal_period,'') AS meal_period," : "'' AS meal_period,";
        $closeMethodExpr = na_column_exists($pdo, 'restaurant_orders', 'close_method') ? "COALESCE(ro.close_method,'') AS close_method," : "'' AS close_method,";
        $cashierExpr = na_column_exists($pdo, 'restaurant_orders', 'cashier_name') ? "COALESCE(ro.cashier_name,'') AS cashier_name," : "'' AS cashier_name,";

        $paymentStatusExpr = na_column_exists($pdo, 'restaurant_orders', 'payment_status') ? "COALESCE(ro.payment_status,'')" : "''";
        $closeMethodField = na_column_exists($pdo, 'restaurant_orders', 'close_method') ? "COALESCE(ro.close_method,'')" : "''";

        $stmt = $pdo->prepare("
            SELECT
                COUNT(*) AS orders_total,
                COALESCE(SUM(CASE WHEN ro.status='closed' THEN 1 ELSE 0 END),0) AS orders_closed,
                COALESCE(SUM(CASE WHEN ro.status IN ('open','sent','preparing','served','bill_requested') THEN 1 ELSE 0 END),0) AS orders_open,
                COALESCE(SUM(CASE WHEN ro.status='closed' THEN ro.total_amount ELSE 0 END),0) AS gross_sales,
                COALESCE(SUM(CASE WHEN ro.status='closed'
                    AND ({$paymentStatusExpr}='room_charged'
                         OR LOWER({$closeMethodField}) LIKE '%account%'
                         OR LOWER({$closeMethodField}) LIKE '%folio%'
                         OR LOWER({$closeMethodField}) LIKE '%room%')
                    THEN ro.total_amount ELSE 0 END),0) AS room_charged_total,
                COALESCE(SUM(CASE WHEN ro.status IN ('open','sent','preparing','served','bill_requested') THEN ro.total_amount ELSE 0 END),0) AS open_order_total
            FROM restaurant_orders ro
            WHERE (
                    DATE(COALESCE(ro.closed_at, ro.opened_at, ro.created_at)) = ?
                 OR (ro.status IN ('open','sent','preparing','served','bill_requested')
                     AND DATE(COALESCE(ro.opened_at, ro.created_at)) <= ?)
            )
            {$restaurantPropertySql}
        ");
        $stmt->execute($restaurantParams);
        $rs = $stmt->fetch(PDO::FETCH_ASSOC) ?: [];
        $restaurantSummary['orders_total'] = (int)($rs['orders_total'] ?? 0);
        $restaurantSummary['orders_closed'] = (int)($rs['orders_closed'] ?? 0);
        $restaurantSummary['orders_open'] = (int)($rs['orders_open'] ?? 0);
        $restaurantSummary['gross_sales'] = (float)($rs['gross_sales'] ?? 0);
        $restaurantSummary['room_charged_total'] = (float)($rs['room_charged_total'] ?? 0);
        $restaurantSummary['open_order_total'] = (float)($rs['open_order_total'] ?? 0);

        if (na_table_exists($pdo, 'restaurant_payments')) {
            $paymentPropertySql = '';
            $paymentParams = [$auditDate];
            if ($propertyId > 0 && na_column_exists($pdo, 'restaurant_orders', 'property_id')) {
                $paymentPropertySql = " AND (ro.property_id = ? OR ro.property_id IS NULL) ";
                $paymentParams[] = $propertyId;
            }
            $stmt = $pdo->prepare("
                SELECT COALESCE(SUM(rp.amount),0)
                FROM restaurant_payments rp
                INNER JOIN restaurant_orders ro ON ro.id = rp.restaurant_order_id
                WHERE COALESCE(rp.status,'posted')='posted'
                  AND DATE(COALESCE(rp.payment_date, rp.created_at)) = ?
                {$paymentPropertySql}
            ");
            $stmt->execute($paymentParams);
            $restaurantSummary['direct_payments_total'] = (float)$stmt->fetchColumn();
        }

        $ordersPropertySql = '';
        $ordersParams = [$auditDate, $auditDate];
        if ($propertyId > 0 && na_column_exists($pdo, 'restaurant_orders', 'property_id')) {
            $ordersPropertySql = " AND (ro.property_id = ? OR ro.property_id IS NULL) ";
            $ordersParams[] = $propertyId;
        }

        $tableJoin = na_table_exists($pdo, 'restaurant_tables') ? "LEFT JOIN restaurant_tables rt ON rt.id=ro.table_id" : "";
        $tableNoExpr = na_table_exists($pdo, 'restaurant_tables') ? "COALESCE(rt.table_no,'') AS table_no," : "'' AS table_no,";
        $joinedTablesJoin = na_table_exists($pdo, 'restaurant_order_tables') && na_table_exists($pdo, 'restaurant_tables') ? "
            LEFT JOIN restaurant_order_tables rot ON rot.restaurant_order_id=ro.id
            LEFT JOIN restaurant_tables rtj ON rtj.id=rot.table_id
        " : "";
        $joinedTablesExpr = na_table_exists($pdo, 'restaurant_order_tables') && na_table_exists($pdo, 'restaurant_tables') ? "GROUP_CONCAT(DISTINCT rtj.table_no ORDER BY rtj.table_no SEPARATOR ', ') AS joined_tables" : "'' AS joined_tables";
        $paymentStatusSelect = na_column_exists($pdo, 'restaurant_orders', 'payment_status') ? "ro.payment_status" : "''";

        $stmt = $pdo->prepare("
            SELECT
                ro.id,
                ro.order_no,
                {$orderNameExpr}
                {$mealExpr}
                {$closeMethodExpr}
                {$cashierExpr}
                {$tableNoExpr}
                ro.order_type,
                COALESCE(ro.guest_name,'') AS guest_name,
                COALESCE(ro.room_no,'') AS room_no,
                COALESCE(ro.covers,0) AS covers,
                ro.status,
                {$paymentStatusSelect} AS payment_status,
                COALESCE(ro.total_amount,0) AS total_amount,
                ro.opened_at,
                ro.closed_at,
                ro.created_at,
                {$joinedTablesExpr}
            FROM restaurant_orders ro
            {$tableJoin}
            {$joinedTablesJoin}
            WHERE (
                    DATE(COALESCE(ro.closed_at, ro.opened_at, ro.created_at)) = ?
                 OR (ro.status IN ('open','sent','preparing','served','bill_requested')
                     AND DATE(COALESCE(ro.opened_at, ro.created_at)) <= ?)
            )
            {$ordersPropertySql}
            GROUP BY ro.id
            ORDER BY COALESCE(ro.opened_at, ro.created_at) ASC, ro.id ASC
        ");
        $stmt->execute($ordersParams);
        $restaurantOrders = $stmt->fetchAll(PDO::FETCH_ASSOC);
    }
} catch (Throwable $e) {
    $errors[] = 'Restaurant Audit: ' . $e->getMessage();
}

function na_rows_table(string $title, array $headers, array $rowsHtml): string {
    $html = '<h3>' . h($title) . '</h3><table class="data-table"><thead><tr>';
    foreach ($headers as $head) $html .= '<th>' . h($head) . '</th>';
    $html .= '</tr></thead><tbody>';
    if (!$rowsHtml) {
        $html .= '<tr><td colspan="' . count($headers) . '" class="empty">No records found.</td></tr>';
    } else {
        $html .= implode('', $rowsHtml);
    }
    return $html . '</tbody></table>';
}

$arrivalRows = [];
foreach ($arrivalsPending as $r) {
    $arrivalRows[] = '<tr><td>' . h($r['order_no'] ?: ('#' . $r['id'])) . '</td><td>' . h(na_property_label($r)) . '</td><td>' . h(na_guest_name($r)) . '</td><td>' . h(na_agent_name($r)) . '</td><td align="right">' . (int)($r['room_slots_checked_in'] ?? 0) . '/' . (int)($r['room_slots_total'] ?? 0) . '</td></tr>';
}
$departureRows = [];
foreach ($departuresPending as $r) {
    $departureRows[] = '<tr><td>' . h($r['order_no'] ?: ('#' . $r['id'])) . '</td><td>' . h(na_property_label($r)) . '</td><td>' . h(na_guest_name($r)) . '</td><td>' . h(na_agent_name($r)) . '</td><td align="right">' . (int)($r['room_slots_checked_out'] ?? 0) . '/' . (int)($r['room_slots_total'] ?? 0) . '</td><td align="right">' . money_fmt($r['booking_balance'] ?? 0) . '</td></tr>';
}
$balanceRows = [];
foreach ($openBalanceBookings as $r) {
    $balanceRows[] = '<tr><td>' . h($r['order_no'] ?: ('#' . $r['id'])) . '</td><td>' . h(na_property_label($r)) . '</td><td>' . h(na_guest_name($r)) . '</td><td>' . h(na_agent_name($r)) . '</td><td align="right">' . money_fmt($r['booking_charges'] ?? 0) . '</td><td align="right">' . money_fmt($r['booking_payments'] ?? 0) . '</td><td align="right">' . money_fmt($r['booking_balance'] ?? 0) . '</td></tr>';
}
$dirtyRows = [];
foreach ($dirtyRooms as $r) {
    $dirtyRows[] = '<tr><td>' . h($r['room_no'] ?? '') . '</td><td>' . h(na_property_label($r)) . '</td><td>' . h($r['room_type'] ?? '') . '</td></tr>';
}
$oooRows = [];
foreach ($outOfOrderRooms as $r) {
    $oooRows[] = '<tr><td>' . h($r['room_no'] ?? '') . '</td><td>' . h(na_property_label($r)) . '</td><td>' . h($r['room_type'] ?? '') . '</td></tr>';
}

$restaurantRows = [];
foreach ($restaurantOrders as $r) {
    $opened = !empty($r['opened_at']) ? date('H:i', strtotime($r['opened_at'])) : (!empty($r['created_at']) ? date('H:i', strtotime($r['created_at'])) : '—');
    $closed = !empty($r['closed_at']) ? date('H:i', strtotime($r['closed_at'])) : '—';
    $tableLabel = trim((string)($r['joined_tables'] ?? ''));
    if ($tableLabel === '') $tableLabel = trim((string)($r['table_no'] ?? ''));
    if ($tableLabel === '') $tableLabel = '—';
    $guest = trim((string)($r['guest_name'] ?? ''));
    if ($guest === '') $guest = trim((string)($r['order_name'] ?? '')) ?: 'Guest';
    $room = trim((string)($r['room_no'] ?? ''));
    $restaurantRows[] = '<tr>'
        . '<td>' . h($r['order_no'] ?: ('#' . $r['id'])) . '</td>'
        . '<td>' . h($opened) . '</td>'
        . '<td>' . h($closed) . '</td>'
        . '<td>' . h($tableLabel) . '</td>'
        . '<td>' . h($guest . ($room !== '' ? ' / Room ' . $room : '')) . '</td>'
        . '<td>' . h(ucwords(str_replace('_',' ', (string)($r['meal_period'] ?: $r['order_type'])))) . '</td>'
        . '<td>' . h(ucwords(str_replace('_',' ', (string)($r['status'] ?? '')))) . '</td>'
        . '<td>' . h(ucwords(str_replace('_',' ', (string)($r['payment_status'] ?? '')))) . '</td>'
        . '<td>' . h($r['close_method'] ?: '—') . '</td>'
        . '<td align="right">' . money_fmt($r['total_amount'] ?? 0) . '</td>'
        . '</tr>';
}

$errorRows = [];
foreach ($errors as $err) $errorRows[] = '<tr><td>' . h($err) . '</td></tr>';

$html = '<!doctype html><html><head><meta charset="utf-8"><style>
body{font-family:helvetica,arial,sans-serif;color:#111827;font-size:9px;}
.header{border-bottom:3px solid #111827;padding-bottom:8px;margin-bottom:10px;}
.title{font-size:20px;font-weight:bold;letter-spacing:.3px;color:#111827;}
.subtitle{font-size:10px;color:#6b7280;margin-top:3px;}
.meta{font-size:9px;color:#374151;margin-top:6px;}
.kpi-table{width:100%;border-collapse:collapse;margin:8px 0 12px;}
.kpi-table td{border:1px solid #d1d5db;padding:7px;background:#f9fafb;}
.kpi-label{font-size:8px;color:#6b7280;text-transform:uppercase;font-weight:bold;}
.kpi-value{font-size:15px;color:#111827;font-weight:bold;margin-top:3px;}
h3{font-size:12px;background:#111827;color:#fff;padding:6px 8px;margin:12px 0 0;border-radius:4px;}
.data-table{width:100%;border-collapse:collapse;margin-bottom:8px;}
.data-table th{background:#f3f4f6;color:#374151;border:1px solid #d1d5db;font-size:8px;padding:5px;text-align:left;font-weight:bold;}
.data-table td{border:1px solid #e5e7eb;padding:5px;font-size:8.5px;}
.empty{text-align:center;color:#6b7280;padding:10px;}
.signoff{margin-top:18px;width:100%;border-collapse:collapse;}
.signoff td{border:1px solid #d1d5db;padding:10px;height:34px;}
.small-note{font-size:8px;color:#6b7280;margin-top:8px;}
@media print{.no-print{display:none!important;} body{margin:0;}}
</style></head><body>';

$html .= '<div class="header"><div class="title">Night Audit Report</div><div class="subtitle">End-of-day operational control report</div><div class="meta"><b>Audit Date:</b> ' . h($auditDate) . ' &nbsp; | &nbsp; <b>Property:</b> ' . h($propertyName) . ' &nbsp; | &nbsp; <b>Generated:</b> ' . h($generatedAt) . '</div></div>';
$html .= '<table class="kpi-table"><tr>';
foreach ([
    ['Rooms', $summary['rooms_total']], ['Occupied', $summary['rooms_occupied']], ['Vacant', $summary['rooms_vacant']], ['Occupancy %', money_fmt($summary['occupancy_pct']) . '%'],
    ['Pending Arrivals', $summary['arrivals_pending']], ['Pending Departures', $summary['departures_pending']], ['Open Balances', $summary['open_balance_bookings']], ['Dirty Rooms', $summary['dirty_rooms']],
] as $i => $kpi) {
    if ($i > 0 && $i % 4 === 0) $html .= '</tr><tr>';
    $html .= '<td><div class="kpi-label">' . h($kpi[0]) . '</div><div class="kpi-value">' . h($kpi[1]) . '</div></td>';
}
$html .= '</tr></table>';

$html .= '<table class="kpi-table"><tr>';
$html .= '<td><div class="kpi-label">In-house Charges</div><div class="kpi-value">' . money_fmt($summary['charges_total']) . '</div></td>';
$html .= '<td><div class="kpi-label">In-house Payments</div><div class="kpi-value">' . money_fmt($summary['payments_total']) . '</div></td>';
$html .= '<td><div class="kpi-label">Open Balance Total</div><div class="kpi-value">' . money_fmt($summary['balance_total']) . '</div></td>';
$html .= '<td><div class="kpi-label">Out of Order</div><div class="kpi-value">' . number_format($summary['ooo_rooms']) . '</div></td>';
$html .= '</tr></table>';

$html .= '<table class="kpi-table"><tr>';
$html .= '<td><div class="kpi-label">Restaurant Orders</div><div class="kpi-value">' . number_format($restaurantSummary['orders_total']) . '</div></td>';
$html .= '<td><div class="kpi-label">Restaurant Closed</div><div class="kpi-value">' . number_format($restaurantSummary['orders_closed']) . '</div></td>';
$html .= '<td><div class="kpi-label">Restaurant Open</div><div class="kpi-value">' . number_format($restaurantSummary['orders_open']) . '</div></td>';
$html .= '<td><div class="kpi-label">Restaurant Sales</div><div class="kpi-value">' . money_fmt($restaurantSummary['gross_sales']) . '</div></td>';
$html .= '</tr><tr>';
$html .= '<td><div class="kpi-label">Room / Lodge Charged</div><div class="kpi-value">' . money_fmt($restaurantSummary['room_charged_total']) . '</div></td>';
$html .= '<td><div class="kpi-label">Restaurant Payments</div><div class="kpi-value">' . money_fmt($restaurantSummary['direct_payments_total']) . '</div></td>';
$html .= '<td><div class="kpi-label">Open Order Value</div><div class="kpi-value">' . money_fmt($restaurantSummary['open_order_total']) . '</div></td>';
$html .= '<td><div class="kpi-label">Restaurant Variance Check</div><div class="kpi-value">' . money_fmt($restaurantSummary['gross_sales'] - $restaurantSummary['direct_payments_total'] - $restaurantSummary['room_charged_total']) . '</div></td>';
$html .= '</tr></table>';

if ($errors) $html .= na_rows_table('Audit Query Warnings', ['Warning'], $errorRows);
$html .= na_rows_table('Pending Arrivals', ['Booking','Property','Guest','Agent','Checked In'], $arrivalRows);
$html .= na_rows_table('Pending Departures', ['Booking','Property','Guest','Agent','Checked Out','Balance'], $departureRows);
$html .= na_rows_table('In-House Bookings with Open Balances', ['Booking','Property','Guest','Agent','Charges','Payments','Balance'], $balanceRows);
$html .= na_rows_table('Restaurant Orders / POS Audit', ['Order','Opened','Closed','Table(s)','Guest / Room','Meal / Type','Status','Payment','Close Method','Total'], $restaurantRows);
$html .= na_rows_table('Dirty Rooms', ['Room','Property','Room Type'], $dirtyRows);
$html .= na_rows_table('Out of Order / Maintenance Rooms', ['Room','Property','Room Type'], $oooRows);

$html .= '<h3>Night Audit Sign Off</h3><table class="signoff"><tr><td><b>Prepared By</b><br><br>Signature: __________________________</td><td><b>Reviewed By</b><br><br>Signature: __________________________</td><td><b>Manager Approval</b><br><br>Signature: __________________________</td></tr></table>';
$html .= '<div class="small-note">Report generated by RoomZ Night Audit. Please review pending arrivals, departures, open balances, restaurant orders/POS charges, dirty rooms, and out-of-order rooms before closing the business day.</div>';
$html .= '</body></html>';

$tcpdfLoaded = false;
foreach ([
    __DIR__ . '/../../vendor/autoload.php',
    __DIR__ . '/../../tcpdf/tcpdf.php',
    __DIR__ . '/../../../tcpdf/tcpdf.php',
    __DIR__ . '/../../libraries/tcpdf/tcpdf.php',
] as $path) {
    if (file_exists($path)) {
        require_once $path;
        $tcpdfLoaded = true;
        break;
    }
}

$downloadName = 'Night_Audit_' . preg_replace('/[^0-9A-Za-z_-]/', '_', $auditDate . '_' . $propertyName) . '.pdf';

if ($tcpdfLoaded && class_exists('TCPDF')) {
    $pdf = new TCPDF('L', PDF_UNIT, 'A4', true, 'UTF-8', false);
    $pdf->SetCreator('RoomZ');
    $pdf->SetAuthor('RoomZ');
    $pdf->SetTitle('Night Audit ' . $auditDate);
    $pdf->SetSubject('Night Audit Report');
    $pdf->SetKeywords('night audit, report, rooms');
    $pdf->setPrintHeader(false);
    $pdf->setPrintFooter(true);
    $pdf->SetMargins(8, 8, 8);
    $pdf->SetAutoPageBreak(true, 10);
    $pdf->AddPage();
    $pdf->SetFont('helvetica', '', 8);
    $pdf->writeHTML($html, true, false, true, false, '');
    $pdf->Output($downloadName, 'I');
    exit;
}

header('Content-Type: text/html; charset=utf-8');
echo str_replace('<body>', '<body><div class="no-print" style="padding:10px;background:#f3f4f6;border-bottom:1px solid #d1d5db;font-family:Arial,sans-serif;"><button onclick="window.print()" style="padding:8px 12px;border:0;background:#111827;color:#fff;border-radius:6px;cursor:pointer;">Print / Save as PDF</button> <span style="font-size:12px;color:#6b7280;margin-left:8px;">TCPDF was not found, so this printable browser report is shown.</span></div>', $html);
exit;
