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

$pageTitle = 'Availability Calendar';

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

if (!function_exists('cal_display_date')) {
    function cal_display_date($value, $format = 'd M Y')
    {
        if (!$value) {
            return '';
        }
        $ts = strtotime((string)$value);
        return $ts ? date($format, $ts) : (string)$value;
    }
}

if (!function_exists('cal_cell_class')) {
    function cal_cell_class(int $total, int $occupied): string
    {
        if ($total <= 0) {
            return 'cell-no-stock';
        }

        if ($occupied <= 0) {
            return 'cell-zero-booked';
        }

        $ratio = $occupied / max(1, $total);

        if ($ratio >= 1) {
            return 'cell-100-full';
        }

        if ($ratio > 0.75) {
            return 'cell-deep-red';
        }

        if ($ratio > 0.50) {
            return 'cell-light-red';
        }

        return 'cell-teal';
    }
}

if (!function_exists('cal_is_family_room')) {
    function cal_is_family_room(string $roomType): bool
    {
        return stripos($roomType, 'family') !== false;
    }
}

if (!function_exists('cal_room_occupancy_meta')) {
    function cal_room_occupancy_meta(string $roomType, int $adults, int $children, int $higherOccupancy = 0): array
    {
        $totalPax = max(0, $adults) + max(0, $children);
        $isFamily = cal_is_family_room($roomType);

        if ($isFamily) {
            return ['label' => 'Family Room', 'class' => 'family-room', 'is_triple' => false, 'is_family' => true];
        }

        if ($totalPax >= 3 && ($higherOccupancy >= 3 || $totalPax === 3)) {
            return ['label' => 'Triple / Extra Bed', 'class' => 'triple-room', 'is_triple' => true, 'is_family' => false];
        }

        if ($totalPax === 2) {
            return ['label' => 'Double', 'class' => 'double-room', 'is_triple' => false, 'is_family' => false];
        }

        if ($totalPax === 1) {
            return ['label' => 'Single', 'class' => 'single-room', 'is_triple' => false, 'is_family' => false];
        }

        return ['label' => 'Empty', 'class' => 'empty-room', 'is_triple' => false, 'is_family' => false];
    }
}

if (!function_exists('count_available_rooms_by_type')) {
    function count_available_rooms_by_type(PDO $pdo, int $propertyId, int $roomTypeId, string $checkIn, string $checkOut, int $excludeOrderId = 0): array
    {
        if ($propertyId <= 0 || $roomTypeId <= 0 || $checkIn === '' || $checkOut === '') {
            return [
                'total_rooms'     => 0,
                'occupied_rooms'  => 0,
                'available_rooms' => 0,
            ];
        }

        /*
           Correct PMS availability logic:
           - Count physical rooms of this property + room type.
           - Count occupied PHYSICAL rooms per night.
           - Checkout date is available again:
                 rmg.check_in <= night_date AND rmg.check_out > night_date
           - For a multi-night stay, use the busiest night.
        */

        $stmtTotal = $pdo->prepare("
            SELECT COUNT(*)
            FROM rooms
            WHERE property_id = :property_id
              AND room_type_id = :room_type_id
        ");
        $stmtTotal->execute([
            ':property_id'  => $propertyId,
            ':room_type_id' => $roomTypeId,
        ]);
        $totalRooms = (int)$stmtTotal->fetchColumn();

        $startTs = strtotime($checkIn);
        $endTs   = strtotime($checkOut);
        if (!$startTs || !$endTs || $endTs <= $startTs) {
            return [
                'total_rooms'     => $totalRooms,
                'occupied_rooms'  => 0,
                'available_rooms' => $totalRooms,
            ];
        }

        $days = [];
        for ($ts = $startTs; $ts < $endTs; $ts = strtotime('+1 day', $ts)) {
            $days[] = date('Y-m-d', $ts);
        }

        if (!$days) {
            return [
                'total_rooms'     => $totalRooms,
                'occupied_rooms'  => 0,
                'available_rooms' => $totalRooms,
            ];
        }

        $dayUnion = [];
        $params = [
            ':property_id'  => $propertyId,
            ':room_type_id' => $roomTypeId,
        ];

        foreach ($days as $i => $day) {
            $dayUnion[] = "SELECT :night_{$i} AS day_date";
            $params[":night_{$i}"] = $day;
        }

        $excludeSql = '';
        if ($excludeOrderId > 0) {
            $excludeSql = ' AND o.id <> :exclude_order_id ';
            $params[':exclude_order_id'] = $excludeOrderId;
        }

        $stmtOcc = $pdo->prepare("
            SELECT COALESCE(MAX(occupied_rooms), 0)
            FROM (
                SELECT
                    d.day_date,
                    COUNT(DISTINCT r.id) AS occupied_rooms
                FROM (" . implode(" UNION ALL ", $dayUnion) . ") d
                LEFT JOIN rooms r
                    ON r.property_id = :property_id
                   AND r.room_type_id = :room_type_id
                LEFT JOIN order_rooming rmg
                    ON rmg.room_id = r.id
                   AND rmg.room_id > 0
                   AND rmg.check_in <= d.day_date
                   AND rmg.check_out > d.day_date
                LEFT JOIN orders o
                    ON o.id = rmg.order_id
                   AND o.property_id = r.property_id
                   AND LOWER(TRIM(CAST(COALESCE(o.status, 1) AS CHAR))) NOT IN
                       ('0','cancelled','canceled','void','deleted','no_show','noshow')
                   {$excludeSql}
                WHERE o.id IS NOT NULL
                GROUP BY d.day_date
            ) x
        ");
        $stmtOcc->execute($params);
        $occupiedRooms = (int)$stmtOcc->fetchColumn();

        return [
            'total_rooms'     => $totalRooms,
            'occupied_rooms'  => $occupiedRooms,
            'available_rooms' => max(0, $totalRooms - $occupiedRooms),
        ];
    }
}

if (file_exists(__DIR__ . '/waitlist_support.php')) {
    require_once __DIR__ . '/waitlist_support.php';
}

if (!function_exists('cal_waitlist_url')) {
    function cal_waitlist_url(array $params = []): string
    {
        return '/rooms/modules/reservations/waitlist.php' . (!empty($params) ? '?' . http_build_query($params) : '');
    }
}

$properties = $pdo->query("
    SELECT id, name, code
    FROM properties
    WHERE is_active = 1
    ORDER BY name ASC
")->fetchAll(PDO::FETCH_ASSOC);

$selectedPropertyId = (int)($_GET['property_id'] ?? 0);
$dateFrom = trim((string)($_GET['from'] ?? date('Y-m-01')));
$dateTo   = trim((string)($_GET['to'] ?? date('Y-m-t')));
$viewMode = trim((string)($_GET['view_mode'] ?? 'detailed'));
$export   = trim((string)($_GET['export'] ?? ''));

if (!in_array($viewMode, ['detailed', 'compact'], true)) {
    $viewMode = 'detailed';
}

/* ---------------------------------
   Safe DateTime setup
--------------------------------- */
try {
    $fromDateObj = new DateTime($dateFrom ?: date('Y-m-01'));
} catch (Throwable $e) {
    $fromDateObj = new DateTime(date('Y-m-01'));
}

try {
    $toDateObj = new DateTime($dateTo ?: date('Y-m-t'));
} catch (Throwable $e) {
    $toDateObj = new DateTime($fromDateObj->format('Y-m-t'));
}

if ($toDateObj < $fromDateObj) {
    $toDateObj = new DateTime($fromDateObj->format('Y-m-t'));
}

/* ---------------------------------
   Date range + Month navigation
   IMPORTANT:
   Do not force the selected range back to month start/end.
   The user may select custom ranges like 24 May - 30 May
   or cross-month ranges like 29 May - 14 June.
--------------------------------- */
$rangeStartObj = clone $fromDateObj;
$rangeEndObj   = clone $toDateObj;

$dateFrom = $rangeStartObj->format('Y-m-d');
$dateTo   = $rangeEndObj->format('Y-m-d');

$currentMonthStartObj = new DateTime($rangeStartObj->format('Y-m-01'));
$currentMonthEndObj   = new DateTime($rangeStartObj->format('Y-m-t'));

$prevMonthStart = (clone $currentMonthStartObj)->modify('-1 month')->format('Y-m-01');
$prevMonthEnd   = (clone $currentMonthStartObj)->modify('-1 month')->format('Y-m-t');
$thisMonthStart = date('Y-m-01');
$thisMonthEnd   = date('Y-m-t');
$nextMonthStart = (clone $currentMonthStartObj)->modify('+1 month')->format('Y-m-01');
$nextMonthEnd   = (clone $currentMonthStartObj)->modify('+1 month')->format('Y-m-t');

$currentMonthStartTs = $rangeStartObj->getTimestamp();
$currentMonthEndTs   = $rangeEndObj->getTimestamp();

$navBase = [
    'property_id' => $selectedPropertyId,
    'view_mode'   => $viewMode,
];

$prevMonthUrl = 'availability_calendar.php?' . http_build_query(array_merge($navBase, [
    'from' => $prevMonthStart,
    'to'   => $prevMonthEnd,
]));
$thisMonthUrl = 'availability_calendar.php?' . http_build_query(array_merge($navBase, [
    'from' => $thisMonthStart,
    'to'   => $thisMonthEnd,
]));
$nextMonthUrl = 'availability_calendar.php?' . http_build_query(array_merge($navBase, [
    'from' => $nextMonthStart,
    'to'   => $nextMonthEnd,
]));

$days = [];
$periodEnd = (clone $rangeEndObj)->modify('+1 day');
$period = new DatePeriod($rangeStartObj, new DateInterval('P1D'), $periodEnd);
$todayYmd = date('Y-m-d');

foreach ($period as $dayObj) {
    $dayDate = $dayObj->format('Y-m-d');
    $days[] = [
        'date'     => $dayDate,
        'day'      => $dayObj->format('D'),
        'num'      => $dayObj->format('d'),
        'mon'      => $dayObj->format('M'),
        'is_today' => ($todayYmd === $dayDate),
    ];
}

$totalDays = count($days);

if ($viewMode === 'compact') {
    $dayWidth = 64;
    $labelWidth = 260;
} else {
    $dayWidth = 104;
    $labelWidth = 300;
}

$tableMinWidth = $labelWidth + ($totalDays * $dayWidth);

/* ---------------------------------
   Load room stock by property/type
--------------------------------- */
$sqlRoomTypes = "
    SELECT
        r.property_id,
        p.name AS property_name,
        p.code AS property_code,
        r.room_type_id,
        rt.title AS room_type,
        COALESCE(rt.higher_occupancy, 0) AS higher_occupancy,
        COUNT(*) AS total_rooms
    FROM rooms r
    INNER JOIN properties p ON p.id = r.property_id
    LEFT JOIN room_types rt ON rt.id = r.room_type_id
    WHERE 1=1
";
$paramsRoomTypes = [];

if ($selectedPropertyId > 0) {
    $sqlRoomTypes .= " AND r.property_id = :property_id ";
    $paramsRoomTypes[':property_id'] = $selectedPropertyId;
}

$sqlRoomTypes .= "
    GROUP BY
        r.property_id,
        p.name,
        p.code,
        r.room_type_id,
        rt.title,
        rt.higher_occupancy
    ORDER BY
        p.name ASC,
        rt.title ASC
";

$stmt = $pdo->prepare($sqlRoomTypes);
$stmt->execute($paramsRoomTypes);
$roomTypeRows = $stmt->fetchAll(PDO::FETCH_ASSOC);

/* ---------------------------------
   Load occupied room counts by day
--------------------------------- */
$sqlOcc = "
    SELECT
        r.property_id,
        r.room_type_id,
        d.day_date,
        COUNT(DISTINCT r.id) AS occupied_rooms
    FROM
    (
";
$unionParts = [];
foreach ($days as $i => $day) {
    $unionParts[] = "SELECT :d{$i} AS day_date";
}
$sqlOcc .= implode(" UNION ALL ", $unionParts);

$sqlOcc .= "
    ) d
    INNER JOIN rooms r
        ON 1=1
    INNER JOIN order_rooming orm
        ON orm.room_id = r.id
       AND orm.room_id > 0
       AND orm.check_in <= d.day_date
       AND orm.check_out > d.day_date
    INNER JOIN orders o
        ON o.id = orm.order_id
       AND o.property_id = r.property_id
    WHERE LOWER(TRIM(CAST(COALESCE(o.status, 1) AS CHAR))) NOT IN
          ('0','cancelled','canceled','void','deleted','no_show','noshow')
";

$paramsOcc = [];
foreach ($days as $i => $day) {
    $paramsOcc[":d{$i}"] = $day['date'];
}

if ($selectedPropertyId > 0) {
    $sqlOcc .= " AND r.property_id = :occ_property_id ";
    $paramsOcc[':occ_property_id'] = $selectedPropertyId;
}

$sqlOcc .= "
    GROUP BY
        r.property_id,
        r.room_type_id,
        d.day_date
";

$stmt = $pdo->prepare($sqlOcc);
$stmt->execute($paramsOcc);
$occupiedRows = $stmt->fetchAll(PDO::FETCH_ASSOC);

$occupiedMap = [];
foreach ($occupiedRows as $row) {
    $p = (int)$row['property_id'];
    $rt = (int)$row['room_type_id'];
    $d = (string)$row['day_date'];
    $occupiedMap[$p][$rt][$d] = (int)$row['occupied_rooms'];
}

/* ---------------------------------
   Load booking details for clickable cells
--------------------------------- */
$sqlBookings = "
    SELECT
        o.property_id,
        rm.room_type_id,
        orm.room_id,
        r.room_no,
        orm.order_id,
        orm.room_no AS slot_no,
        orm.adults,
        orm.children,
        orm.check_in,
        orm.check_out,
        o.order_no,
        o.status,
        o.totalamount,
        g.firstname,
        g.lastname,
        COALESCE(rt.title, '') AS room_type_title,
        COALESCE(rt.higher_occupancy, 0) AS higher_occupancy
    FROM order_rooming orm
    INNER JOIN orders o ON o.id = orm.order_id
    INNER JOIN rooms r ON r.id = orm.room_id
    INNER JOIN rooms rm ON rm.id = orm.room_id
    LEFT JOIN room_types rt ON rt.id = rm.room_type_id
    LEFT JOIN guests g ON g.id = o.guest_id
    WHERE orm.room_id > 0
      AND orm.check_in < DATE_ADD(:toDate, INTERVAL 1 DAY)
      AND orm.check_out > :fromDate
      AND LOWER(TRIM(CAST(COALESCE(o.status, 1) AS CHAR))) NOT IN ('0','cancelled','canceled','void','deleted','no_show','noshow')
";
$paramsBookings = [
    ':fromDate' => $dateFrom,
    ':toDate'   => $dateTo,
];

if ($selectedPropertyId > 0) {
    $sqlBookings .= " AND o.property_id = :book_property_id ";
    $paramsBookings[':book_property_id'] = $selectedPropertyId;
}

$sqlBookings .= "
    ORDER BY o.property_id, rm.room_type_id, orm.check_in, o.id
";

$stmt = $pdo->prepare($sqlBookings);
$stmt->execute($paramsBookings);
$bookingRows = $stmt->fetchAll(PDO::FETCH_ASSOC);

$bookingMap = [];
foreach ($bookingRows as $row) {
    $propertyId = (int)$row['property_id'];
    $roomTypeId = (int)$row['room_type_id'];

    $occMeta = cal_room_occupancy_meta(
        (string)($row['room_type_title'] ?? ''),
        (int)($row['adults'] ?? 0),
        (int)($row['children'] ?? 0),
        (int)($row['higher_occupancy'] ?? 0)
    );
    $row['occupancy_label'] = $occMeta['label'];
    $row['occupancy_class'] = $occMeta['class'];
    $row['is_triple'] = $occMeta['is_triple'] ? 1 : 0;
    $row['is_family'] = $occMeta['is_family'] ? 1 : 0;

    $startTs = strtotime((string)$row['check_in']);
    $endTs   = strtotime((string)$row['check_out']);
    if (!$startTs || !$endTs) {
        continue;
    }

    $cursorTs = $startTs;
    while ($cursorTs < $endTs) {
        $d = date('Y-m-d', $cursorTs);
        if ($d >= $dateFrom && $d <= $dateTo) {
            $bookingMap[$propertyId][$roomTypeId][$d][] = $row;
        }
        $cursorTs = strtotime('+1 day', $cursorTs);
    }
}

/* ---------------------------------
   Group rows by property
--------------------------------- */
$calendarRows = [];
foreach ($roomTypeRows as $row) {
    $propertyId = (int)$row['property_id'];
    if (!isset($calendarRows[$propertyId])) {
        $calendarRows[$propertyId] = [
            'property_name' => (string)$row['property_name'],
            'property_code' => (string)$row['property_code'],
            'rows' => [],
        ];
    }
    $calendarRows[$propertyId]['rows'][] = $row;
}

$totalRoomTypes = count($roomTypeRows);
$totalRooms = 0;
foreach ($roomTypeRows as $row) {
    $totalRooms += (int)$row['total_rooms'];
}

$currentPropertyLabel = 'All Properties';
if ($selectedPropertyId > 0) {
    foreach ($properties as $prop) {
        if ((int)$prop['id'] === $selectedPropertyId) {
            $currentPropertyLabel = trim($prop['name'] . (!empty($prop['code']) ? ' (' . $prop['code'] . ')' : ''));
            break;
        }
    }
}

$notifiedWaitlists = [];
if (function_exists('refresh_waitlist_matches')) {
    refresh_waitlist_matches($pdo, $selectedPropertyId > 0 ? $selectedPropertyId : null, null);
}
if (function_exists('fetch_notified_waitlists')) {
    $notifiedWaitlists = fetch_notified_waitlists($pdo, 12);
}
$notifiedWaitlistCount = count($notifiedWaitlists);

$selectedStayCheckOut = date('Y-m-d', strtotime('+1 day', strtotime($dateTo)));

$selectedStayWaitlistUrl = cal_waitlist_url([
    'property_id' => $selectedPropertyId > 0 ? $selectedPropertyId : '',
    'check_in'    => $dateFrom,
    'check_out'   => $selectedStayCheckOut,
    'source'      => 'availability_calendar',
]);

$waitlistQuickRows = [];
foreach ($calendarRows as $propertyId => $propertyBlock) {
    foreach ($propertyBlock['rows'] as $row) {
        $rtId = (int)$row['room_type_id'];
        $stayAvailability = count_available_rooms_by_type(
            $pdo,
            (int)$propertyId,
            $rtId,
            $dateFrom,
            date('Y-m-d', strtotime('+1 day', strtotime($dateTo)))
        );

        $waitlistQuickRows[$propertyId][$rtId] = [
            'total_rooms'     => (int)($stayAvailability['total_rooms'] ?? 0),
            'occupied_rooms'  => (int)($stayAvailability['occupied_rooms'] ?? 0),
            'available_rooms' => (int)($stayAvailability['available_rooms'] ?? 0),
            'waitlist_url'    => cal_waitlist_url([
                'property_id' => (int)$propertyId,
                'room_type_id'=> $rtId,
                'check_in'    => $dateFrom,
                'check_out'   => $selectedStayCheckOut,
                'source'      => 'availability_calendar',
            ]),
            'book_url'        => '/rooms/modules/reservations/reservation_form.php?' . http_build_query([
                'property_id'  => (int)$propertyId,
                'room_type_id' => $rtId,
                'check_in'     => $dateFrom,
                'check_out'    => $selectedStayCheckOut,
            ]),
        ];
    }
}

/* ---------------------------------
   Build property-level daily summaries
--------------------------------- */
$propertySummaryMap = [];
$propertyTotalsBar = [];

foreach ($calendarRows as $propertyId => $propertyBlock) {
    $propertyTotalRooms = 0;
    foreach ($propertyBlock['rows'] as $row) {
        $propertyTotalRooms += (int)$row['total_rooms'];
    }

    $totalRoomNights = $propertyTotalRooms * $totalDays;
    $occupiedRoomNights = 0;

    foreach ($days as $day) {
        $d = $day['date'];
        $occupied = 0;

        foreach ($propertyBlock['rows'] as $row) {
            $rtId = (int)$row['room_type_id'];
            $occupied += (int)($occupiedMap[$propertyId][$rtId][$d] ?? 0);
        }

        $available = max(0, $propertyTotalRooms - $occupied);

        $propertySummaryMap[$propertyId][$d] = [
            'total'     => $propertyTotalRooms,
            'occupied'  => $occupied,
            'available' => $available,
        ];

        $occupiedRoomNights += $occupied;
    }

    $availableRoomNights = max(0, $totalRoomNights - $occupiedRoomNights);
    $occupancyPct = $totalRoomNights > 0 ? round(($occupiedRoomNights / $totalRoomNights) * 100, 1) : 0;

    $propertyTotalsBar[$propertyId] = [
        'total_room_nights'     => $totalRoomNights,
        'occupied_room_nights'  => $occupiedRoomNights,
        'available_room_nights' => $availableRoomNights,
        'occupancy_pct'         => $occupancyPct,
    ];
}

/* ---------------------------------
   Native Excel (.xlsx) export
   No external spreadsheet library is required. ZipArchive must be enabled.
--------------------------------- */
if (!function_exists('cal_xlsx_col')) {
    function cal_xlsx_col(int $number): string
    {
        $letters = '';
        while ($number > 0) {
            $number--;
            $letters = chr(65 + ($number % 26)) . $letters;
            $number = intdiv($number, 26);
        }
        return $letters;
    }
}

if (!function_exists('cal_xlsx_xml')) {
    function cal_xlsx_xml($value): string
    {
        $text = (string)$value;

        /*
           XML 1.0 does not allow most ASCII control characters. These can
           exist invisibly in imported property, room-type or guest text and
           make Excel report that sheet1.xml is corrupt.
        */
        $text = preg_replace('/[\x00-\x08\x0B\x0C\x0E-\x1F\x7F]/', '', $text);

        /* Replace malformed UTF-8 rather than writing invalid XML bytes. */
        if (function_exists('mb_convert_encoding')) {
            $text = mb_convert_encoding($text, 'UTF-8', 'UTF-8');
        } elseif (function_exists('iconv')) {
            $converted = @iconv('UTF-8', 'UTF-8//IGNORE', $text);
            if ($converted !== false) $text = $converted;
        }

        return htmlspecialchars($text, ENT_XML1 | ENT_QUOTES, 'UTF-8');
    }
}

if (!function_exists('cal_xlsx_safe_sheet_name')) {
    function cal_xlsx_safe_sheet_name(string $name, array &$used): string
    {
        $name = preg_replace('/[\\\\\/\?\*\[\]:]+/', ' ', trim($name));
        $name = trim(preg_replace('/\s+/', ' ', $name));
        if ($name === '') $name = 'Availability';
        $name = function_exists('mb_substr') ? mb_substr($name, 0, 31) : substr($name, 0, 31);
        $base = $name;
        $i = 2;
        while (isset($used[strtolower($name)])) {
            $suffix = ' ' . $i++;
            $limit = 31 - strlen($suffix);
            $name = (function_exists('mb_substr') ? mb_substr($base, 0, $limit) : substr($base, 0, $limit)) . $suffix;
        }
        $used[strtolower($name)] = true;
        return $name;
    }
}

if (!function_exists('cal_xlsx_cell')) {
    function cal_xlsx_cell(string $ref, $value, int $style = 0, string $type = 's'): string
    {
        $styleAttr = $style > 0 ? ' s="' . $style . '"' : '';
        if ($type === 'n') {
            return '<c r="' . $ref . '"' . $styleAttr . '><v>' . (0 + $value) . '</v></c>';
        }
        return '<c r="' . $ref . '" t="inlineStr"' . $styleAttr . '><is><t xml:space="preserve">' . cal_xlsx_xml($value) . '</t></is></c>';
    }
}

if (!function_exists('cal_xlsx_occupancy_style')) {
    function cal_xlsx_occupancy_style(int $total, int $occupied): int
    {
        if ($total <= 0) return 14;       // no inventory
        $ratio = $occupied / max(1, $total);
        if ($ratio >= 1) return 10;       // 100% full - dark red
        if ($ratio >= 0.75) return 11;    // 75-99% - red/orange
        if ($ratio >= 0.50) return 12;    // 50-74% - amber
        if ($ratio >= 0.25) return 13;    // 25-49% - pale green
        return 9;                         // under 25% - green
    }
}

if (!function_exists('cal_export_xlsx')) {
    function cal_export_xlsx(array $calendarRows, array $days, array $occupiedMap, array $propertySummaryMap, array $propertyTotalsBar, string $dateFrom, string $dateTo): void
    {
        if (!class_exists('ZipArchive')) {
            throw new RuntimeException('Excel export requires the PHP ZipArchive extension. Please enable php-zip on the server.');
        }

        $tmp = tempnam(sys_get_temp_dir(), 'availability_xlsx_');
        if ($tmp === false) throw new RuntimeException('Could not create temporary Excel file.');
        @unlink($tmp);
        $tmp .= '.xlsx';

        $zip = new ZipArchive();
        if ($zip->open($tmp, ZipArchive::CREATE | ZipArchive::OVERWRITE) !== true) {
            throw new RuntimeException('Could not create Excel workbook.');
        }

        $usedNames = [];
        $sheets = [];
        $sheetNo = 0;

        foreach ($calendarRows as $propertyId => $propertyBlock) {
            $sheetNo++;
            $sheetName = cal_xlsx_safe_sheet_name((string)$propertyBlock['property_name'], $usedNames);
            $sheets[] = ['name' => $sheetName, 'id' => $sheetNo];

            $lastColNo = 2 + count($days);
            $lastCol = cal_xlsx_col($lastColNo);
            $rowsXml = [];

            $rowsXml[] = '<row r="1" ht="28" customHeight="1">' . cal_xlsx_cell('A1', $propertyBlock['property_name'], 1) . '</row>';
            $rowsXml[] = '<row r="2" ht="23" customHeight="1">' . cal_xlsx_cell('A2', 'Availability by Product Type for ' . date('d/m/Y', strtotime($dateFrom)) . ' to ' . date('d/m/Y', strtotime($dateTo)), 2) . '</row>';
            $rowsXml[] = '<row r="3" ht="19" customHeight="1">' . cal_xlsx_cell('A3', 'Generated on: ' . date('d/m/Y H:i:s'), 3) . '</row>';
            $rowsXml[] = '<row r="4" ht="9" customHeight="1"></row>';
            $rowsXml[] = '<row r="5" ht="20" customHeight="1">' . cal_xlsx_cell('A5', 'Daily room availability. Cell colours show percentage occupied: green = open, amber = filling, red = full.', 4) . '</row>';
            $rowsXml[] = '<row r="6" ht="9" customHeight="1"></row>';

            $header = cal_xlsx_cell('A7', 'Product Type', 5) . cal_xlsx_cell('B7', 'Products', 5);
            foreach ($days as $i => $day) {
                $col = cal_xlsx_col(3 + $i);
                $header .= cal_xlsx_cell($col . '7', date('D', strtotime($day['date'])) . "\n" . date('d M', strtotime($day['date'])), 6);
            }
            $rowsXml[] = '<row r="7" ht="38" customHeight="1">' . $header . '</row>';

            $rowNo = 8;
            foreach ($propertyBlock['rows'] as $roomRow) {
                $rtId = (int)$roomRow['room_type_id'];
                $total = (int)$roomRow['total_rooms'];
                $cells = cal_xlsx_cell('A' . $rowNo, $roomRow['room_type'] ?: 'No type', 7);
                $cells .= cal_xlsx_cell('B' . $rowNo, $total, 8, 'n');
                foreach ($days as $i => $day) {
                    $occupied = (int)($occupiedMap[$propertyId][$rtId][$day['date']] ?? 0);
                    $available = max(0, $total - $occupied);
                    $style = cal_xlsx_occupancy_style($total, $occupied);
                    $cells .= cal_xlsx_cell(cal_xlsx_col(3 + $i) . $rowNo, $available, $style, 'n');
                }
                $rowsXml[] = '<row r="' . $rowNo . '" ht="24" customHeight="1">' . $cells . '</row>';
                $rowNo++;
            }

            $summary = $propertySummaryMap[$propertyId] ?? [];
            $propertyTotalRooms = 0;
            foreach ($propertyBlock['rows'] as $rr) $propertyTotalRooms += (int)$rr['total_rooms'];
            $cells = cal_xlsx_cell('A' . $rowNo, 'Totals', 15);
            $cells .= cal_xlsx_cell('B' . $rowNo, $propertyTotalRooms, 16, 'n');
            foreach ($days as $i => $day) {
                $sum = $summary[$day['date']] ?? ['total'=>0,'occupied'=>0,'available'=>0];
                $style = cal_xlsx_occupancy_style((int)$sum['total'], (int)$sum['occupied']);
                $cells .= cal_xlsx_cell(cal_xlsx_col(3 + $i) . $rowNo, (int)$sum['available'], $style, 'n');
            }
            $rowsXml[] = '<row r="' . $rowNo . '" ht="26" customHeight="1">' . $cells . '</row>';
            $rowNo += 2;

            $totals = $propertyTotalsBar[$propertyId] ?? ['total_room_nights'=>0,'occupied_room_nights'=>0,'available_room_nights'=>0,'occupancy_pct'=>0];
            $rowsXml[] = '<row r="' . $rowNo . '">' . cal_xlsx_cell('A'.$rowNo, 'Period Summary', 17) . '</row>';
            $rowNo++;
            $rowsXml[] = '<row r="'.$rowNo.'">' . cal_xlsx_cell('A'.$rowNo, 'Total Room Nights', 18) . cal_xlsx_cell('B'.$rowNo, (int)$totals['total_room_nights'], 19, 'n') . '</row>';
            $rowNo++;
            $rowsXml[] = '<row r="'.$rowNo.'">' . cal_xlsx_cell('A'.$rowNo, 'Occupied Room Nights', 18) . cal_xlsx_cell('B'.$rowNo, (int)$totals['occupied_room_nights'], 20, 'n') . '</row>';
            $rowNo++;
            $rowsXml[] = '<row r="'.$rowNo.'">' . cal_xlsx_cell('A'.$rowNo, 'Available Room Nights', 18) . cal_xlsx_cell('B'.$rowNo, (int)$totals['available_room_nights'], 21, 'n') . '</row>';
            $rowNo++;
            $rowsXml[] = '<row r="'.$rowNo.'">' . cal_xlsx_cell('A'.$rowNo, 'Occupancy %', 18) . cal_xlsx_cell('B'.$rowNo, (float)$totals['occupancy_pct'] / 100, 22, 'n') . '</row>';
            $rowNo += 2;

            $legend = cal_xlsx_cell('A'.$rowNo, 'Colour Key', 17)
                . cal_xlsx_cell('B'.$rowNo, 'Open (<25%)', 9)
                . cal_xlsx_cell('C'.$rowNo, '25-49%', 13)
                . cal_xlsx_cell('D'.$rowNo, '50-74%', 12)
                . cal_xlsx_cell('E'.$rowNo, '75-99%', 11)
                . cal_xlsx_cell('F'.$rowNo, 'Full (100%)', 10);
            $rowsXml[] = '<row r="'.$rowNo.'" ht="22" customHeight="1">'.$legend.'</row>';

            $cols = '<cols><col min="1" max="1" width="26" customWidth="1"/><col min="2" max="2" width="11" customWidth="1"/><col min="3" max="'.$lastColNo.'" width="12" customWidth="1"/></cols>';
            $merge = '<mergeCells count="4"><mergeCell ref="A1:'.$lastCol.'1"/><mergeCell ref="A2:'.$lastCol.'2"/><mergeCell ref="A3:'.$lastCol.'3"/><mergeCell ref="A5:'.$lastCol.'5"/></mergeCells>';
            /* Auto-filter covers the heading and actual room-type rows only. */
            $lastDataRow = max(7, 7 + count($propertyBlock['rows']));
            $autoFilter = '<autoFilter ref="A7:'.$lastCol.$lastDataRow.'"/>';
            $sheetXml = '<?xml version="1.0" encoding="UTF-8" standalone="yes"?>'
                . '<worksheet xmlns="http://schemas.openxmlformats.org/spreadsheetml/2006/main" xmlns:r="http://schemas.openxmlformats.org/officeDocument/2006/relationships">'
                . '<sheetViews><sheetView workbookViewId="0" showGridLines="0"><pane xSplit="2" ySplit="7" topLeftCell="C8" activePane="bottomRight" state="frozen"/></sheetView></sheetViews>'
                . '<sheetFormatPr defaultRowHeight="18"/>' . $cols
                . '<sheetData>' . implode('', $rowsXml) . '</sheetData>'
                /* SpreadsheetML requires autoFilter before mergeCells. */
                . $autoFilter . $merge
                . '<pageMargins left="0.25" right="0.25" top="0.5" bottom="0.5" header="0.2" footer="0.2"/>'
                . '<pageSetup orientation="landscape" fitToWidth="1" fitToHeight="0" paperSize="9"/>'
                . '</worksheet>';
            $zip->addFromString('xl/worksheets/sheet' . $sheetNo . '.xml', $sheetXml);
        }

        $sheetEntries = '';
        $relsEntries = '';
        $contentSheetEntries = '';
        foreach ($sheets as $sheet) {
            $sheetEntries .= '<sheet name="' . cal_xlsx_xml($sheet['name']) . '" sheetId="' . $sheet['id'] . '" r:id="rId' . $sheet['id'] . '"/>';
            $relsEntries .= '<Relationship Id="rId' . $sheet['id'] . '" Type="http://schemas.openxmlformats.org/officeDocument/2006/relationships/worksheet" Target="worksheets/sheet' . $sheet['id'] . '.xml"/>';
            $contentSheetEntries .= '<Override PartName="/xl/worksheets/sheet' . $sheet['id'] . '.xml" ContentType="application/vnd.openxmlformats-officedocument.spreadsheetml.worksheet+xml"/>';
        }
        $styleRelId = count($sheets) + 1;
        $relsEntries .= '<Relationship Id="rId' . $styleRelId . '" Type="http://schemas.openxmlformats.org/officeDocument/2006/relationships/styles" Target="styles.xml"/>';

        $zip->addFromString('[Content_Types].xml', '<?xml version="1.0" encoding="UTF-8" standalone="yes"?><Types xmlns="http://schemas.openxmlformats.org/package/2006/content-types"><Default Extension="rels" ContentType="application/vnd.openxmlformats-package.relationships+xml"/><Default Extension="xml" ContentType="application/xml"/><Override PartName="/xl/workbook.xml" ContentType="application/vnd.openxmlformats-officedocument.spreadsheetml.sheet.main+xml"/><Override PartName="/xl/styles.xml" ContentType="application/vnd.openxmlformats-officedocument.spreadsheetml.styles+xml"/>' . $contentSheetEntries . '</Types>');
        $zip->addFromString('_rels/.rels', '<?xml version="1.0" encoding="UTF-8" standalone="yes"?><Relationships xmlns="http://schemas.openxmlformats.org/package/2006/relationships"><Relationship Id="rId1" Type="http://schemas.openxmlformats.org/officeDocument/2006/relationships/officeDocument" Target="xl/workbook.xml"/></Relationships>');
        $zip->addFromString('xl/workbook.xml', '<?xml version="1.0" encoding="UTF-8" standalone="yes"?><workbook xmlns="http://schemas.openxmlformats.org/spreadsheetml/2006/main" xmlns:r="http://schemas.openxmlformats.org/officeDocument/2006/relationships"><bookViews><workbookView/></bookViews><sheets>' . $sheetEntries . '</sheets><calcPr calcId="191029"/></workbook>');
        $zip->addFromString('xl/_rels/workbook.xml.rels', '<?xml version="1.0" encoding="UTF-8" standalone="yes"?><Relationships xmlns="http://schemas.openxmlformats.org/package/2006/relationships">' . $relsEntries . '</Relationships>');

        $styles = '<?xml version="1.0" encoding="UTF-8" standalone="yes"?>'
        . '<styleSheet xmlns="http://schemas.openxmlformats.org/spreadsheetml/2006/main">'
        . '<numFmts count="1"><numFmt numFmtId="164" formatCode="0.0%"/></numFmts>'
        . '<fonts count="6">'
        . '<font><sz val="10"/><name val="Aptos"/><family val="2"/></font>'
        . '<font><b/><sz val="18"/><color rgb="FF17365D"/><name val="Aptos Display"/></font>'
        . '<font><b/><sz val="12"/><color rgb="FF1F4E78"/><name val="Aptos"/></font>'
        . '<font><i/><sz val="9"/><color rgb="FF64748B"/><name val="Aptos"/></font>'
        . '<font><b/><sz val="10"/><color rgb="FFFFFFFF"/><name val="Aptos"/></font>'
        . '<font><b/><sz val="10"/><color rgb="FF1F2937"/><name val="Aptos"/></font>'
        . '</fonts>'
        . '<fills count="10">'
        . '<fill><patternFill patternType="none"/></fill><fill><patternFill patternType="gray125"/></fill>'
        . '<fill><patternFill patternType="solid"><fgColor rgb="FF1F4E78"/><bgColor indexed="64"/></patternFill></fill>'
        . '<fill><patternFill patternType="solid"><fgColor rgb="FFD9EAF7"/><bgColor indexed="64"/></patternFill></fill>'
        . '<fill><patternFill patternType="solid"><fgColor rgb="FFE2F0D9"/><bgColor indexed="64"/></patternFill></fill>'
        . '<fill><patternFill patternType="solid"><fgColor rgb="FFC6E0B4"/><bgColor indexed="64"/></patternFill></fill>'
        . '<fill><patternFill patternType="solid"><fgColor rgb="FFFFE699"/><bgColor indexed="64"/></patternFill></fill>'
        . '<fill><patternFill patternType="solid"><fgColor rgb="FFF4B183"/><bgColor indexed="64"/></patternFill></fill>'
        . '<fill><patternFill patternType="solid"><fgColor rgb="FFC00000"/><bgColor indexed="64"/></patternFill></fill>'
        . '<fill><patternFill patternType="solid"><fgColor rgb="FFF2F2F2"/><bgColor indexed="64"/></patternFill></fill>'
        . '</fills>'
        . '<borders count="3"><border/><border><left style="thin"><color rgb="FFD9E2F3"/></left><right style="thin"><color rgb="FFD9E2F3"/></right><top style="thin"><color rgb="FFD9E2F3"/></top><bottom style="thin"><color rgb="FFD9E2F3"/></bottom></border><border><bottom style="medium"><color rgb="FF1F4E78"/></bottom></border></borders>'
        . '<cellStyleXfs count="1"><xf numFmtId="0" fontId="0" fillId="0" borderId="0"/></cellStyleXfs>'
        . '<cellXfs count="23">'
        . '<xf numFmtId="0" fontId="0" fillId="0" borderId="0" xfId="0"/>'
        . '<xf numFmtId="0" fontId="1" fillId="0" borderId="0" xfId="0"><alignment vertical="center"/></xf>'
        . '<xf numFmtId="0" fontId="2" fillId="0" borderId="0" xfId="0"><alignment vertical="center"/></xf>'
        . '<xf numFmtId="0" fontId="3" fillId="0" borderId="0" xfId="0"/>'
        . '<xf numFmtId="0" fontId="3" fillId="3" borderId="0" xfId="0"><alignment wrapText="1"/></xf>'
        . '<xf numFmtId="0" fontId="4" fillId="2" borderId="1" xfId="0"><alignment horizontal="center" vertical="center" wrapText="1"/></xf>'
        . '<xf numFmtId="0" fontId="4" fillId="2" borderId="1" xfId="0"><alignment horizontal="center" vertical="center" wrapText="1"/></xf>'
        . '<xf numFmtId="0" fontId="5" fillId="0" borderId="1" xfId="0"><alignment vertical="center"/></xf>'
        . '<xf numFmtId="0" fontId="5" fillId="0" borderId="1" xfId="0"><alignment horizontal="center" vertical="center"/></xf>'
        . '<xf numFmtId="0" fontId="5" fillId="4" borderId="1" xfId="0"><alignment horizontal="center" vertical="center"/></xf>'
        . '<xf numFmtId="0" fontId="4" fillId="8" borderId="1" xfId="0"><alignment horizontal="center" vertical="center"/></xf>'
        . '<xf numFmtId="0" fontId="5" fillId="7" borderId="1" xfId="0"><alignment horizontal="center" vertical="center"/></xf>'
        . '<xf numFmtId="0" fontId="5" fillId="6" borderId="1" xfId="0"><alignment horizontal="center" vertical="center"/></xf>'
        . '<xf numFmtId="0" fontId="5" fillId="5" borderId="1" xfId="0"><alignment horizontal="center" vertical="center"/></xf>'
        . '<xf numFmtId="0" fontId="3" fillId="9" borderId="1" xfId="0"><alignment horizontal="center" vertical="center"/></xf>'
        . '<xf numFmtId="0" fontId="5" fillId="3" borderId="2" xfId="0"/>'
        . '<xf numFmtId="0" fontId="5" fillId="3" borderId="2" xfId="0"><alignment horizontal="center"/></xf>'
        . '<xf numFmtId="0" fontId="5" fillId="2" borderId="1" xfId="0"/>'
        . '<xf numFmtId="0" fontId="5" fillId="0" borderId="1" xfId="0"/>'
        . '<xf numFmtId="0" fontId="5" fillId="3" borderId="1" xfId="0"><alignment horizontal="right"/></xf>'
        . '<xf numFmtId="0" fontId="5" fillId="7" borderId="1" xfId="0"><alignment horizontal="right"/></xf>'
        . '<xf numFmtId="0" fontId="5" fillId="4" borderId="1" xfId="0"><alignment horizontal="right"/></xf>'
        . '<xf numFmtId="164" fontId="5" fillId="3" borderId="1" xfId="0"><alignment horizontal="right"/></xf>'
        . '</cellXfs><cellStyles count="1"><cellStyle name="Normal" xfId="0" builtinId="0"/></cellStyles></styleSheet>';
        $zip->addFromString('xl/styles.xml', $styles);
        $zip->close();

        $filename = 'availability_by_product_type_' . $dateFrom . '_to_' . $dateTo . '.xlsx';
        header('Content-Type: application/vnd.openxmlformats-officedocument.spreadsheetml.sheet');
        header('Content-Disposition: attachment; filename="' . $filename . '"');
        header('Content-Length: ' . filesize($tmp));
        header('Cache-Control: max-age=0');
        readfile($tmp);
        @unlink($tmp);
        exit;
    }
}

if ($export === 'xlsx') {
    try {
        cal_export_xlsx($calendarRows, $days, $occupiedMap, $propertySummaryMap, $propertyTotalsBar, $dateFrom, $dateTo);
    } catch (Throwable $e) {
        http_response_code(500);
        header('Content-Type: text/plain; charset=utf-8');
        echo 'Excel export failed: ' . $e->getMessage();
        exit;
    }
}

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

<div class="card border-0 shadow-sm mb-2 overflow-hidden calendar-hero-compact" style="border-radius:18px;">
    <div class="card-body p-3">
        <div class="row g-2 align-items-center">
            <div class="col-lg-8">
                <div class="page-eyebrow mb-1 small">
                    <i class="bi bi-calendar3"></i> Inventory Calendar
                </div>
                <h4 class="mb-1 fw-bold">Availability Calendar <span class="badge text-bg-success ms-2">Physical-room per-day</span></h4>
                <div class="small text-muted">
                    View: <strong><?php echo cal_e($currentPropertyLabel); ?></strong>
                    • Mode: <strong><?php echo cal_e(ucfirst($viewMode)); ?></strong>
                    • Period: <strong><?php echo cal_e(cal_display_date($dateFrom) . ' to ' . cal_display_date($dateTo)); ?></strong>
                </div>
            </div>
            <div class="col-lg-4 no-print">
                <div class="d-flex flex-wrap justify-content-lg-end gap-2">
                    <a class="btn btn-sm btn-primary" href="/rooms/modules/reservations/reservation_form.php<?php echo $selectedPropertyId > 0 ? '?property_id=' . (int)$selectedPropertyId : ''; ?>">
                        <i class="bi bi-plus-circle me-2"></i>New Reservation
                    </a>
                    <a class="btn btn-sm btn-outline-danger" href="/rooms/modules/reservations/waitlist.php<?php echo $selectedPropertyId > 0 ? '?property_id=' . (int)$selectedPropertyId : ''; ?>">
                        <i class="bi bi-hourglass-split me-2"></i>Waitlist
                        <?php if ($notifiedWaitlistCount > 0): ?>
                            <span class="badge text-bg-danger ms-2"><?php echo (int)$notifiedWaitlistCount; ?></span>
                        <?php endif; ?>
                    </a>
                    <a class="btn btn-sm btn-outline-secondary" href="/rooms/modules/reservations/reservation_list.php<?php echo $selectedPropertyId > 0 ? '?property_id=' . (int)$selectedPropertyId : ''; ?>">
                        <i class="bi bi-journal-text me-2"></i>Reservations
                    </a>
                </div>
            </div>
        </div>

        <div class="row g-2 mt-2 calendar-stats-compact">
            <div class="col-md-4">
                <div class="inventory-stat">
                    <div class="inventory-stat-icon bg-primary-subtle text-primary"><i class="bi bi-buildings"></i></div>
                    <div>
                        <div class="inventory-stat-value"><?php echo $selectedPropertyId > 0 ? '1' : count($calendarRows); ?></div>
                        <div class="inventory-stat-label">Property Views</div>
                    </div>
                </div>
            </div>

            <div class="col-md-4">
                <div class="inventory-stat">
                    <div class="inventory-stat-icon bg-success-subtle text-success"><i class="bi bi-grid"></i></div>
                    <div>
                        <div class="inventory-stat-value"><?php echo (int)$totalRoomTypes; ?></div>
                        <div class="inventory-stat-label">Room Types</div>
                    </div>
                </div>
            </div>

            <div class="col-md-4">
                <div class="inventory-stat">
                    <div class="inventory-stat-icon bg-warning-subtle text-warning"><i class="bi bi-door-open"></i></div>
                    <div>
                        <div class="inventory-stat-value"><?php echo (int)$totalRooms; ?></div>
                        <div class="inventory-stat-label">Total Rooms</div>
                    </div>
                </div>
            </div>
        </div>
    </div>
</div>

<div class="card border-0 shadow-sm mb-2 no-print calendar-filter-compact">
    <div class="card-body p-3">
        <div class="d-flex flex-wrap justify-content-between align-items-center gap-2 mb-2">
            <div class="month-nav d-flex flex-wrap gap-2">
                <a href="<?php echo cal_e($prevMonthUrl); ?>" class="btn btn-sm btn-outline-secondary">
                    <i class="bi bi-chevron-left me-1"></i>Previous Month
                </a>
                <a href="<?php echo cal_e($thisMonthUrl); ?>" class="btn btn-sm btn-outline-primary">
                    <i class="bi bi-calendar-event me-1"></i>This Month
                </a>
                <a href="<?php echo cal_e($nextMonthUrl); ?>" class="btn btn-sm btn-outline-secondary">
                    Next Month<i class="bi bi-chevron-right ms-1"></i>
                </a>
            </div>
            <div class="d-flex flex-wrap gap-2">
                <a href="availability_calendar.php?<?php echo cal_e(http_build_query([
                    'property_id' => $selectedPropertyId,
                    'from' => $dateFrom,
                    'to' => $dateTo,
                    'view_mode' => $viewMode,
                    'export' => 'xlsx'
                ])); ?>" class="btn btn-sm btn-outline-success">
                    <i class="bi bi-file-earmark-spreadsheet me-1"></i>Export Excel
                </a>
                <button type="button" class="btn btn-sm btn-outline-dark" onclick="window.print();">
                    <i class="bi bi-printer me-1"></i>Print
                </button>
            </div>
        </div>

        <div class="d-flex flex-wrap gap-2 mb-2 compact-secondary-actions">
            <a href="<?php echo cal_e($selectedStayWaitlistUrl); ?>" class="btn btn-sm btn-outline-danger">
                <i class="bi bi-hourglass-split me-1"></i>Waitlist Selected Stay
            </a>
            <?php if ($notifiedWaitlistCount > 0): ?>
                <span class="badge text-bg-danger align-self-center px-3 py-2">
                    <?php echo (int)$notifiedWaitlistCount; ?> waitlist match<?php echo $notifiedWaitlistCount === 1 ? '' : 'es'; ?> ready
                </span>
            <?php endif; ?>
        </div>

        <div class="month-pill mb-2">
            <?php echo cal_e(cal_display_date($dateFrom) . ' to ' . cal_display_date($dateTo)); ?>
        </div>

        <form class="row g-2 align-items-end" method="get">
            <div class="col-xl-3 col-md-4">
                <label class="form-label fw-semibold">Property</label>
                <select class="form-select" name="property_id">
                    <option value="0">All properties</option>
                    <?php foreach ($properties as $property): ?>
                        <option value="<?php echo (int)$property['id']; ?>" <?php echo $selectedPropertyId === (int)$property['id'] ? 'selected' : ''; ?>>
                            <?php echo cal_e($property['name']); ?><?php echo !empty($property['code']) ? ' - ' . cal_e($property['code']) : ''; ?>
                        </option>
                    <?php endforeach; ?>
                </select>
            </div>

            <div class="col-xl-2 col-md-4">
                <label class="form-label fw-semibold">From</label>
                <input type="date" class="form-control" name="from" value="<?php echo cal_e($dateFrom); ?>">
            </div>

            <div class="col-xl-2 col-md-4">
                <label class="form-label fw-semibold">To</label>
                <input type="date" class="form-control" name="to" value="<?php echo cal_e($dateTo); ?>">
            </div>

            <div class="col-xl-3 col-md-6">
                <label class="form-label fw-semibold">View Mode</label>
                <select class="form-select" name="view_mode">
                    <option value="detailed" <?php echo $viewMode === 'detailed' ? 'selected' : ''; ?>>Detailed</option>
                    <option value="compact" <?php echo $viewMode === 'compact' ? 'selected' : ''; ?>>Compact Month View</option>
                </select>
            </div>

            <div class="col-xl-2 col-md-6">
                <div class="d-flex gap-2">
                    <button class="btn btn-sm btn-primary flex-fill">
                        <i class="bi bi-arrow-repeat me-2"></i>Refresh
                    </button>
                    <a class="btn btn-sm btn-outline-secondary" href="availability_calendar.php<?php echo $selectedPropertyId > 0 ? '?property_id=' . (int)$selectedPropertyId : ''; ?>">
                        Reset
                    </a>
                </div>
            </div>
        </form>
    </div>
</div>

<?php if ($calendarRows): ?>
    <div class="card border-0 shadow-sm mb-2 no-print compact-waitlist-panel">
        <div class="card-header bg-white border-0 p-4 pb-0 d-flex justify-content-between align-items-center">
            <div>
                <h5 class="mb-1">Waitlist actions for selected stay</h5>
                <div class="text-muted">For the stay from <?php echo cal_e($dateFrom); ?> to <?php echo cal_e((new DateTime($dateTo))->modify('+1 day')->format('Y-m-d')); ?>, book room types that have space and waitlist the ones that are full.</div>
            </div>
            <a href="/rooms/modules/reservations/waitlist.php" class="btn btn-outline-danger">
                <i class="bi bi-list-ul me-2"></i>Open Waitlist
            </a>
        </div>
        <div class="card-body pt-2">
            <div class="row g-3">
                <?php foreach ($calendarRows as $propertyId => $propertyBlock): ?>
                    <?php foreach ($propertyBlock['rows'] as $row): ?>
                        <?php
                        $rtId = (int)$row['room_type_id'];
                        $quick = $waitlistQuickRows[$propertyId][$rtId] ?? ['total_rooms'=>0,'occupied_rooms'=>0,'available_rooms'=>0,'waitlist_url'=>'#','book_url'=>'#'];
                        $hasAvailability = (int)$quick['available_rooms'] > 0;
                        ?>
                        <div class="col-xl-4 col-lg-6">
                            <div class="waitlist-quick-card h-100 <?php echo $hasAvailability ? 'has-availability' : 'is-full'; ?>">
                                <div class="d-flex justify-content-between align-items-start gap-3">
                                    <div>
                                        <div class="fw-bold"><?php echo cal_e($propertyBlock['property_name']); ?></div>
                                        <div class="text-muted small"><?php echo cal_e($row['room_type'] ?: 'No type'); ?></div>
                                        <?php if (!cal_is_family_room((string)($row['room_type'] ?? '')) && (int)($row['higher_occupancy'] ?? 0) >= 3): ?>
                                            <span class="badge occupancy-badge triple-room mt-2"><i class="bi bi-person-plus"></i> Triple possible</span>
                                        <?php elseif (cal_is_family_room((string)($row['room_type'] ?? ''))): ?>
                                            <span class="badge occupancy-badge family-room mt-2"><i class="bi bi-people"></i> Family Room</span>
                                        <?php endif; ?>
                                    </div>
                                    <span class="badge text-bg-<?php echo $hasAvailability ? 'success' : 'danger'; ?>">
                                        <?php echo $hasAvailability ? 'Available' : 'Full'; ?>
                                    </span>
                                </div>
                                <div class="waitlist-quick-stats mt-3">
                                    <div><span>Total</span><strong><?php echo (int)$quick['total_rooms']; ?></strong></div>
                                    <div><span>Occupied</span><strong><?php echo (int)$quick['occupied_rooms']; ?></strong></div>
                                    <div><span>Available</span><strong><?php echo (int)$quick['available_rooms']; ?></strong></div>
                                </div>
                                <div class="d-flex gap-2 mt-3">
                                    <?php if ($hasAvailability): ?>
                                        <a class="btn btn-primary flex-fill" href="<?php echo cal_e($quick['book_url']); ?>">
                                            <i class="bi bi-plus-circle me-1"></i>Book This Type
                                        </a>
                                    <?php else: ?>
                                        <a class="btn btn-outline-danger flex-fill" href="<?php echo cal_e($quick['waitlist_url']); ?>">
                                            <i class="bi bi-hourglass-split me-1"></i>Add to Waitlist
                                        </a>
                                    <?php endif; ?>
                                </div>
                            </div>
                        </div>
                    <?php endforeach; ?>
                <?php endforeach; ?>
            </div>
        </div>
    </div>
<?php endif; ?>

<?php if (!$calendarRows): ?>
    <div class="alert alert-warning">
        No room inventory found for the selected filter.
    </div>
<?php else: ?>
    <?php foreach ($calendarRows as $propertyId => $propertyBlock): ?>
        <?php $totals = $propertyTotalsBar[$propertyId] ?? ['total_room_nights' => 0, 'occupied_room_nights' => 0, 'available_room_nights' => 0, 'occupancy_pct' => 0]; ?>
        <div class="card border-0 shadow-sm mb-3 print-card calendar-main-card">
            <div class="card-header bg-white border-0 p-3 pb-0 calendar-property-header">
                <h5 class="mb-1">
                    <?php echo cal_e($propertyBlock['property_name']); ?>
                    <?php if (!empty($propertyBlock['property_code'])): ?>
                        <span class="text-muted"> (<?php echo cal_e($propertyBlock['property_code']); ?>)</span>
                    <?php endif; ?>
                </h5>
                <div class="text-muted">
                    Daily availability by room type
                </div>
            </div>

            <div class="card-body pt-2">
                <div class="row g-2 mb-2 property-totals-compact">
                    <div class="col-md-3">
                        <div class="property-total-box">
                            <div class="property-total-label">Total Room Nights</div>
                            <div class="property-total-value"><?php echo number_format((int)$totals['total_room_nights']); ?></div>
                        </div>
                    </div>
                    <div class="col-md-3">
                        <div class="property-total-box">
                            <div class="property-total-label">Occupied Room Nights</div>
                            <div class="property-total-value text-danger"><?php echo number_format((int)$totals['occupied_room_nights']); ?></div>
                        </div>
                    </div>
                    <div class="col-md-3">
                        <div class="property-total-box">
                            <div class="property-total-label">Available Room Nights</div>
                            <div class="property-total-value text-success"><?php echo number_format((int)$totals['available_room_nights']); ?></div>
                        </div>
                    </div>
                    <div class="col-md-3">
                        <div class="property-total-box">
                            <div class="property-total-label">Occupancy %</div>
                            <div class="property-total-value text-primary"><?php echo number_format((float)$totals['occupancy_pct'], 1); ?>%</div>
                        </div>
                    </div>
                </div>

                <div class="availability-wrap">
                    <div class="availability-table" style="min-width: <?php echo (int)$tableMinWidth; ?>px;">
                        <div class="availability-head">
                            <div class="availability-label-head">Room Type</div>
                            <div class="availability-days-head" style="width: <?php echo (int)($totalDays * $dayWidth); ?>px;">
                                <?php foreach ($days as $day): ?>
                                    <div class="availability-day-head <?php echo $day['is_today'] ? 'is-today' : ''; ?> <?php echo $viewMode === 'compact' ? 'compact-head' : ''; ?>" style="width: <?php echo (int)$dayWidth; ?>px;">
                                        <div class="day-name"><?php echo cal_e($day['day']); ?></div>
                                        <div class="day-num"><?php echo cal_e($day['num']); ?></div>
                                        <?php if ($viewMode !== 'compact'): ?>
                                            <div class="day-mon"><?php echo cal_e($day['mon']); ?></div>
                                        <?php endif; ?>
                                    </div>
                                <?php endforeach; ?>
                            </div>
                        </div>

                        <div class="availability-row summary-row">
                            <div class="availability-label-cell summary-label-cell">
                                <div class="type-title">Property Summary</div>
                                <div class="type-subtitle">All room types combined</div>
                            </div>

                            <div class="availability-days-row" style="width: <?php echo (int)($totalDays * $dayWidth); ?>px;">
                                <?php foreach ($days as $day): ?>
                                    <?php
                                    $d = $day['date'];
                                    $sum = $propertySummaryMap[$propertyId][$d] ?? ['total' => 0, 'occupied' => 0, 'available' => 0];
                                    $cellClass = cal_cell_class((int)$sum['total'], (int)$sum['occupied']);
                                    ?>
                                    <div class="availability-cell summary-cell <?php echo $cellClass; ?> <?php echo $day['is_today'] ? 'is-today' : ''; ?> <?php echo $viewMode === 'compact' ? 'compact-cell' : ''; ?>"
                                         style="width: <?php echo (int)$dayWidth; ?>px;"
                                         title="<?php echo cal_e('Property summary | ' . $d . ' | Total: ' . $sum['total'] . ' | Occupied: ' . $sum['occupied'] . ' | Available: ' . $sum['available']); ?>">
                                        <div class="cell-available"><?php echo (int)$sum['available']; ?></div>
                                        <?php if ($viewMode === 'compact'): ?>
                                            <div class="cell-mini"><?php echo (int)$sum['occupied']; ?>/<?php echo (int)$sum['total']; ?></div>
                                        <?php else: ?>
                                            <div class="cell-meta">
                                                <span>T <?php echo (int)$sum['total']; ?></span>
                                                <span>O <?php echo (int)$sum['occupied']; ?></span>
                                            </div>
                                        <?php endif; ?>
                                    </div>
                                <?php endforeach; ?>
                            </div>
                        </div>

                        <?php foreach ($propertyBlock['rows'] as $row): ?>
                            <?php
                            $rtId = (int)$row['room_type_id'];
                            $total = (int)$row['total_rooms'];
                            ?>
                            <div class="availability-row">
                                <div class="availability-label-cell">
                                    <div class="type-title"><?php echo cal_e($row['room_type'] ?: 'No type'); ?></div>
                                    <div class="type-subtitle">Total stock: <?php echo $total; ?></div>
                                    <?php if (!cal_is_family_room((string)($row['room_type'] ?? '')) && (int)($row['higher_occupancy'] ?? 0) >= 3): ?>
                                        <div class="mt-2"><span class="badge occupancy-badge triple-room"><i class="bi bi-person-plus"></i> Triple possible</span></div>
                                    <?php elseif (cal_is_family_room((string)($row['room_type'] ?? ''))): ?>
                                        <div class="mt-2"><span class="badge occupancy-badge family-room"><i class="bi bi-people"></i> Family Room</span></div>
                                    <?php endif; ?>
                                </div>

                                <div class="availability-days-row" style="width: <?php echo (int)($totalDays * $dayWidth); ?>px;">
                                    <?php foreach ($days as $day): ?>
                                        <?php
                                        $d = $day['date'];
                                        $occupied = (int)($occupiedMap[$propertyId][$rtId][$d] ?? 0);
                                        $available = max(0, $total - $occupied);
                                        $cellClass = cal_cell_class($total, $occupied);

                                        $cellBookings = $bookingMap[$propertyId][$rtId][$d] ?? [];
                                        $hasBookings = !empty($cellBookings);

                                        $payload = [
                                            'property_id'   => (int)$propertyId,
                                            'property_name' => (string)$propertyBlock['property_name'],
                                            'property_code' => (string)$propertyBlock['property_code'],
                                            'room_type_id'  => (int)$rtId,
                                            'room_type'     => (string)($row['room_type'] ?: 'No type'),
                                            'higher_occupancy' => (int)($row['higher_occupancy'] ?? 0),
                                            'triple_possible' => (!cal_is_family_room((string)($row['room_type'] ?? '')) && (int)($row['higher_occupancy'] ?? 0) >= 3) ? 1 : 0,
                                            'is_family_room' => cal_is_family_room((string)($row['room_type'] ?? '')) ? 1 : 0,
                                            'date'          => $d,
                                            'check_in'      => $d,
                                            'check_out'     => date('Y-m-d', strtotime('+1 day', strtotime($d))),
                                            'total'         => $total,
                                            'occupied'      => $occupied,
                                            'available'     => $available,
                                            'bookings'      => $cellBookings,
                                            'book_url'      => '/rooms/modules/reservations/reservation_form.php?' . http_build_query([
                                                'property_id'  => (int)$propertyId,
                                                'room_type_id' => (int)$rtId,
                                                'check_in'     => $d,
                                                'check_out'    => date('Y-m-d', strtotime('+1 day', strtotime($d))),
                                            ]),
                                            'waitlist_url'  => cal_waitlist_url([
                                                'property_id'  => (int)$propertyId,
                                                'room_type_id' => (int)$rtId,
                                                'check_in'     => $d,
                                                'check_out'    => date('Y-m-d', strtotime('+1 day', strtotime($d))),
                                                'source'       => 'availability_calendar',
                                            ]),
                                        ];
                                        ?>
                                        <button type="button"
                                                class="availability-cell <?php echo $cellClass; ?> <?php echo $day['is_today'] ? 'is-today' : ''; ?> <?php echo $hasBookings ? 'is-clickable' : ''; ?> <?php echo $viewMode === 'compact' ? 'compact-cell' : ''; ?>"
                                                style="width: <?php echo (int)$dayWidth; ?>px;"
                                                title="<?php echo cal_e(($row['room_type'] ?: 'No type') . ' | ' . $d . ' | Total: ' . $total . ' | Occupied: ' . $occupied . ' | Available: ' . $available); ?>"
                                                data-cell-payload="<?php echo cal_e(json_encode($payload, JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES)); ?>">
                                            <div class="cell-available"><?php echo $available; ?></div>
                                            <?php if ($viewMode === 'compact'): ?>
                                                <div class="cell-mini"><?php echo $occupied; ?>/<?php echo $total; ?></div>
                                            <?php else: ?>
                                                <div class="cell-meta">
                                                    <span>T <?php echo $total; ?></span>
                                                    <span>O <?php echo $occupied; ?></span>
                                                </div>
                                            <?php endif; ?>
                                        </button>
                                    <?php endforeach; ?>
                                </div>
                            </div>
                        <?php endforeach; ?>
                    </div>
                </div>
            </div>
        </div>
    <?php endforeach; ?>
<?php endif; ?>

<div class="modal fade" id="availabilityDetailsModal" tabindex="-1" aria-labelledby="availabilityDetailsModalLabel" aria-hidden="true">
    <div class="modal-dialog modal-xl modal-dialog-scrollable">
        <div class="modal-content">
            <div class="modal-header">
                <div>
                    <h5 class="modal-title mb-1" id="availabilityDetailsModalLabel">Occupancy Details</h5>
                    <div class="small text-muted" id="availabilityDetailsSubTitle"></div>
                </div>
                <button type="button" class="btn-close" data-bs-dismiss="modal" aria-label="Close"></button>
            </div>

            <div class="modal-body">
                <div class="row g-3 mb-4">
                    <div class="col-md-3">
                        <div class="modal-stat">
                            <div class="modal-stat-label">Total Rooms</div>
                            <div class="modal-stat-value" id="modal_total_rooms">0</div>
                        </div>
                    </div>
                    <div class="col-md-3">
                        <div class="modal-stat">
                            <div class="modal-stat-label">Occupied</div>
                            <div class="modal-stat-value text-danger" id="modal_occupied_rooms">0</div>
                        </div>
                    </div>
                    <div class="col-md-3">
                        <div class="modal-stat">
                            <div class="modal-stat-label">Available</div>
                            <div class="modal-stat-value text-success" id="modal_available_rooms">0</div>
                        </div>
                    </div>
                    <div class="col-md-3">
                        <div class="modal-stat">
                            <div class="modal-stat-label">Bookings</div>
                            <div class="modal-stat-value text-primary" id="modal_booking_count">0</div>
                        </div>
                    </div>
                </div>

                <div class="table-responsive">
                    <table class="table table-modern align-middle mb-0">
                        <thead>
                            <tr>
                                <th>Booking Ref</th>
                                <th>Guest</th>
                                <th>Room</th>
                                <th>Slot</th>
                                <th>Stay</th>
                                <th>Pax</th>
                                <th>Type</th>
                                <th>Status</th>
                                <th class="text-end">Actions</th>
                            </tr>
                        </thead>
                        <tbody id="availability_modal_tbody">
                            <tr>
                                <td colspan="9" class="text-center text-muted py-4">No bookings occupying this room type on the selected day.</td>
                            </tr>
                        </tbody>
                    </table>
                </div>
            </div>

            <div class="modal-footer no-print justify-content-between">
                <div class="d-flex gap-2">
                    <a href="#" class="btn btn-outline-danger d-none" id="modal_waitlist_btn">
                        <i class="bi bi-hourglass-split me-1"></i>Add to Waitlist
                    </a>
                    <a href="#" class="btn btn-primary d-none" id="modal_book_btn">
                        <i class="bi bi-plus-circle me-1"></i>Book This Type
                    </a>
                </div>
                <button type="button" class="btn btn-light" data-bs-dismiss="modal">Close</button>
            </div>
        </div>
    </div>
</div>


<?php if ($notifiedWaitlists): ?>
<div class="modal fade" id="waitlistNotifyModal" tabindex="-1" aria-labelledby="waitlistNotifyModalLabel" aria-hidden="true">
    <div class="modal-dialog modal-lg modal-dialog-scrollable">
        <div class="modal-content">
            <div class="modal-header">
                <div>
                    <h5 class="modal-title mb-1" id="waitlistNotifyModalLabel">Waitlist rooms are now available</h5>
                    <div class="small text-muted">These requests can now be confirmed because rooms became available.</div>
                </div>
                <button type="button" class="btn-close" data-bs-dismiss="modal" aria-label="Close"></button>
            </div>
            <div class="modal-body">
                <div class="list-group list-group-flush">
                    <?php foreach ($notifiedWaitlists as $wl): ?>
                        <div class="list-group-item px-0">
                            <div class="d-flex justify-content-between align-items-start gap-3">
                                <div>
                                    <div class="fw-bold"><?php echo cal_e($wl['guest_name'] ?: $wl['waitlist_no']); ?></div>
                                    <div class="small text-muted">
                                        <?php echo cal_e($wl['property_name'] ?? ''); ?> •
                                        <?php echo cal_e($wl['room_type_name'] ?? ''); ?> •
                                        <?php echo cal_e($wl['check_in']); ?> to <?php echo cal_e($wl['check_out']); ?>
                                    </div>
                                    <div class="small text-muted">
                                        Requested: <?php echo (int)$wl['totalrooms']; ?> room(s) •
                                        Available now: <?php echo (int)$wl['available_rooms_last']; ?>
                                    </div>
                                </div>
                                <div class="d-flex gap-2">
                                    <a class="btn btn-sm btn-primary" href="/rooms/modules/reservations/reservation_form.php?waitlist_id=<?php echo (int)$wl['id']; ?>">
                                        <i class="bi bi-check2-circle me-1"></i>Confirm
                                    </a>
                                    <a class="btn btn-sm btn-outline-secondary" href="/rooms/modules/reservations/waitlist.php">
                                        Open Waitlist
                                    </a>
                                </div>
                            </div>
                        </div>
                    <?php endforeach; ?>
                </div>
            </div>
            <div class="modal-footer no-print">
                <button type="button" class="btn btn-light" data-bs-dismiss="modal">Close</button>
            </div>
        </div>
    </div>
</div>
<?php endif; ?>

<style>

/* Compact default view: keeps the calendar visible without scrolling past large panels */
.calendar-hero-compact .card-body{padding-top:.85rem!important;padding-bottom:.85rem!important;}
.calendar-hero-compact h4{font-size:1.18rem;}
.calendar-hero-compact .text-muted{line-height:1.25;}
.calendar-stats-compact .inventory-stat{padding:9px 12px;border-radius:14px;gap:9px;}
.calendar-stats-compact .inventory-stat-icon{width:34px;height:34px;border-radius:10px;font-size:14px;}
.calendar-stats-compact .inventory-stat-value{font-size:1rem;}
.calendar-stats-compact .inventory-stat-label{font-size:.72rem;}
.calendar-filter-compact .form-label{font-size:.78rem;margin-bottom:.2rem;}
.calendar-filter-compact .form-control,.calendar-filter-compact .form-select{min-height:34px;padding:.35rem .65rem;font-size:.86rem;}
.calendar-filter-compact .btn{padding:.35rem .65rem;}
.calendar-filter-compact .month-pill{padding:6px 10px;font-size:.82rem;}
.calendar-filter-compact .compact-secondary-actions{display:none!important;}
.compact-waitlist-panel .card-header{padding:.7rem 1rem!important;}
.compact-waitlist-panel .card-header h5{font-size:.95rem;margin-bottom:0!important;}
.compact-waitlist-panel .card-header .text-muted{display:none;}
.compact-waitlist-panel .card-body{display:none;}
.compact-waitlist-panel .btn{padding:.3rem .6rem;font-size:.8rem;}
.calendar-main-card .calendar-property-header h5{font-size:1rem;}
.calendar-main-card .calendar-property-header .text-muted{font-size:.78rem;}
.property-totals-compact .property-total-box{padding:8px 10px;border-radius:12px;}
.property-totals-compact .property-total-label{font-size:.7rem;margin-bottom:1px;}
.property-totals-compact .property-total-value{font-size:.95rem;}
.availability-label-head{padding:9px 12px!important;}
.availability-day-head{padding:5px 4px!important;}
.availability-row{min-height:58px!important;}
.availability-label-cell{padding:9px 12px!important;}
.availability-cell{min-height:58px!important;}
.type-title{font-size:.86rem!important;}
.type-subtitle{font-size:.72rem!important;margin-top:2px!important;}
.cell-available{font-size:.95rem!important;}
.cell-meta{font-size:.6rem!important;margin-top:2px!important;}
.inventory-stat{
    display:flex;
    align-items:center;
    gap:14px;
    padding:16px 18px;
    border:1px solid #eef2f7;
    border-radius:18px;
    background:#fff;
    height:100%;
}
.inventory-stat-icon{
    width:46px;
    height:46px;
    border-radius:14px;
    display:inline-flex;
    align-items:center;
    justify-content:center;
    font-size:18px;
}
.inventory-stat-value{
    font-size:1.35rem;
    font-weight:800;
    line-height:1.1;
}
.inventory-stat-label{
    color:#6c757d;
    font-size:.9rem;
}
.month-nav .btn{
    border-radius:12px;
}
.month-pill{
    display:inline-flex;
    align-items:center;
    padding:10px 14px;
    border-radius:999px;
    background:#f8fbff;
    border:1px solid #dbe5f0;
    font-weight:700;
    color:#334155;
}
.property-total-box{
    border:1px solid #e6edf5;
    border-radius:16px;
    padding:14px 16px;
    background:#fff;
    height:100%;
}
.property-total-label{
    color:#6c757d;
    font-size:.82rem;
    margin-bottom:4px;
}
.property-total-value{
    font-size:1.2rem;
    font-weight:800;
    line-height:1.1;
}
.waitlist-quick-card{
    border:1px solid #e6edf5;
    border-radius:18px;
    padding:16px;
    background:#fff;
}
.waitlist-quick-card.has-availability{
    background:linear-gradient(135deg,#effdf5 0%,#ffffff 100%);
}
.waitlist-quick-card.is-full{
    background:linear-gradient(135deg,#fff5f5 0%,#ffffff 100%);
}
.waitlist-quick-stats{
    display:grid;
    grid-template-columns:repeat(3,1fr);
    gap:10px;
}
.waitlist-quick-stats div{
    border:1px solid #eef2f7;
    border-radius:12px;
    padding:10px 12px;
    background:#fff;
}
.waitlist-quick-stats span{
    display:block;
    color:#6c757d;
    font-size:.75rem;
    margin-bottom:2px;
}
.waitlist-quick-stats strong{
    font-size:1rem;
}

.availability-wrap{
    overflow:auto;
    border-radius:0 0 24px 24px;
}
.availability-table{
    background:#fff;
}
.availability-head,
.availability-row{
    display:flex;
}
.availability-head{
    position:sticky;
    top:0;
    z-index:5;
    background:#fff;
}
.availability-label-head{
    width:<?php echo (int)$labelWidth; ?>px;
    min-width:<?php echo (int)$labelWidth; ?>px;
    padding:14px 16px;
    font-weight:800;
    border-right:1px solid #e9eef5;
    border-bottom:1px solid #e9eef5;
    background:#f8fbff;
}
.availability-days-head{
    display:flex;
    border-bottom:1px solid #e9eef5;
}
.availability-day-head{
    flex:0 0 auto;
    border-right:1px solid #edf2f7;
    padding:8px 6px;
    text-align:center;
    background:#f8fbff;
}
.availability-day-head.is-today{
    background:#eef5ff;
}
.availability-day-head.compact-head{
    padding:6px 4px;
}
.day-name{
    font-size:.68rem;
    color:#6b7280;
    text-transform:uppercase;
    letter-spacing:.06em;
    font-weight:700;
}
.day-num{
    font-size:.95rem;
    font-weight:800;
    color:#111827;
    line-height:1.1;
}
.day-mon{
    font-size:.68rem;
    color:#6b7280;
}

.availability-row{
    min-height:76px;
    border-bottom:1px solid #edf2f7;
}
.availability-label-cell{
    width:<?php echo (int)$labelWidth; ?>px;
    min-width:<?php echo (int)$labelWidth; ?>px;
    padding:14px 16px;
    border-right:1px solid #edf2f7;
    background:#fff;
    display:flex;
    flex-direction:column;
    justify-content:center;
}
.summary-row{
    border-bottom:2px solid #dbe5f0;
}
.summary-label-cell{
    background:#f8fbff;
}
.type-title{
    font-weight:800;
    font-size:.95rem;
    color:#111827;
}
.type-subtitle{
    font-size:.82rem;
    color:#6b7280;
    margin-top:4px;
}
.availability-days-row{
    display:flex;
}
.availability-cell{
    flex:0 0 auto;
    border-right:1px solid #f1f5f9;
    display:flex;
    flex-direction:column;
    justify-content:center;
    align-items:center;
    padding:6px 4px;
    text-align:center;
    border:none;
    min-height:76px;
}
.summary-cell{
    border-bottom:1px solid #e5edf7;
}
.compact-cell{
    min-height:54px;
    padding:4px 2px;
}
.availability-cell.is-today{
    box-shadow: inset 0 0 0 2px rgba(37,99,235,.12);
}
.availability-cell.is-clickable{
    cursor:pointer;
}
.availability-cell.is-clickable:hover{
    filter:brightness(.98);
    box-shadow: inset 0 0 0 2px rgba(15,23,42,.08);
}
.cell-available{
    font-size:1.05rem;
    font-weight:800;
    line-height:1.1;
}
.compact-cell .cell-available{
    font-size:.95rem;
}
.cell-meta{
    margin-top:4px;
    font-size:.68rem;
    color:#475569;
    display:flex;
    flex-direction:column;
    line-height:1.15;
}
.cell-mini{
    margin-top:3px;
    font-size:.62rem;
    color:#475569;
    line-height:1.1;
    font-weight:700;
}

.cell-zero-booked{
    background:#f0fdf4;
}
.cell-zero-booked .cell-available{
    color:#15803d;
}

.cell-teal{
    background:#ccfbf1;
}
.cell-teal .cell-available{
    color:#0f766e;
}

.cell-light-red{
    background:#fee2e2;
}
.cell-light-red .cell-available{
    color:#b91c1c;
}

.cell-deep-red{
    background:#fecaca;
}
.cell-deep-red .cell-available{
    color:#991b1b;
}

.cell-100-full{
    background:#dc2626;
    color:#fff;
}
.cell-100-full .cell-available,
.cell-100-full .cell-meta,
.cell-100-full .cell-mini{
    color:#fff;
}

.cell-no-stock{
    background:#f8fafc;
    color:#94a3b8;
}

.modal-stat{
    border:1px solid #eef2f7;
    border-radius:16px;
    padding:14px 16px;
    background:#fff;
    height:100%;
}
.modal-stat-label{
    color:#6c757d;
    font-size:.82rem;
    margin-bottom:4px;
}
.modal-stat-value{
    font-size:1.25rem;
    font-weight:800;
    line-height:1.1;
}

.occupancy-badge{
    display:inline-flex;
    align-items:center;
    gap:4px;
    border-radius:999px;
    font-weight:800;
    letter-spacing:.01em;
}
.occupancy-badge.triple-room{
    background:#fff7ed;
    color:#9a3412;
    border:1px solid #fed7aa;
}
.occupancy-badge.family-room{
    background:#eef2ff;
    color:#3730a3;
    border:1px solid #c7d2fe;
}
.occupancy-badge.double-room{
    background:#ecfdf5;
    color:#047857;
    border:1px solid #a7f3d0;
}
.occupancy-badge.single-room{
    background:#f8fafc;
    color:#475569;
    border:1px solid #e2e8f0;
}

@media (max-width: 991.98px) {
    .availability-label-head,
    .availability-label-cell{
        width:220px;
        min-width:220px;
    }
}

@media print {
    .no-print,
    .btn,
    .modal,
    .navbar,
    .sidebar,
    footer {
        display:none !important;
    }

    body {
        background:#fff !important;
    }

    .card {
        box-shadow:none !important;
        border:1px solid #ddd !important;
    }

    .availability-wrap {
        overflow:visible !important;
    }

    .availability-table {
        min-width:100% !important;
    }
}
</style>

<script>
document.addEventListener('DOMContentLoaded', function () {
    var modalEl = document.getElementById('availabilityDetailsModal');
    if (!modalEl) return;

    var modalTitleSub = document.getElementById('availabilityDetailsSubTitle');
    var totalRoomsEl = document.getElementById('modal_total_rooms');
    var occupiedRoomsEl = document.getElementById('modal_occupied_rooms');
    var availableRoomsEl = document.getElementById('modal_available_rooms');
    var bookingCountEl = document.getElementById('modal_booking_count');
    var tbody = document.getElementById('availability_modal_tbody');
    var modalWaitlistBtn = document.getElementById('modal_waitlist_btn');
    var modalBookBtn = document.getElementById('modal_book_btn');

    function escapeHtml(str) {
        var div = document.createElement('div');
        div.textContent = String(str || '');
        return div.innerHTML;
    }

    function badgeClassFromStatus(statusText) {
        var s = String(statusText || '').toLowerCase();
        if (s.indexOf('confirm') !== -1) return 'success';
        if (s.indexOf('pending') !== -1) return 'warning';
        if (s.indexOf('house') !== -1) return 'primary';
        if (s.indexOf('checked out') !== -1) return 'secondary';
        if (s.indexOf('cancel') !== -1) return 'danger';
        return 'dark';
    }

    document.querySelectorAll('.availability-cell[data-cell-payload]').forEach(function (cell) {
        cell.addEventListener('click', function () {
            var payloadRaw = this.getAttribute('data-cell-payload') || '{}';
            var payload = {};

            try {
                payload = JSON.parse(payloadRaw);
            } catch (e) {
                payload = {};
            }

            totalRoomsEl.textContent = payload.total || 0;
            occupiedRoomsEl.textContent = payload.occupied || 0;
            availableRoomsEl.textContent = payload.available || 0;
            bookingCountEl.textContent = (payload.bookings || []).length;

            var propLabel = payload.property_name || '';
            if (payload.property_code) {
                propLabel += ' (' + payload.property_code + ')';
            }

            modalTitleSub.textContent =
                propLabel + ' • ' +
                (payload.room_type || 'Room Type') + ' • ' +
                (payload.date || '');

            var bookings = payload.bookings || [];

            if (modalWaitlistBtn) {
                if ((payload.available || 0) <= 0 && payload.waitlist_url) {
                    modalWaitlistBtn.href = payload.waitlist_url;
                    modalWaitlistBtn.classList.remove('d-none');
                } else {
                    modalWaitlistBtn.href = '#';
                    modalWaitlistBtn.classList.add('d-none');
                }
            }

            if (modalBookBtn) {
                if ((payload.available || 0) > 0 && payload.book_url) {
                    modalBookBtn.href = payload.book_url;
                    modalBookBtn.classList.remove('d-none');
                } else {
                    modalBookBtn.href = '#';
                    modalBookBtn.classList.add('d-none');
                }
            }

            if (!bookings.length) {
                tbody.innerHTML = '<tr><td colspan="9" class="text-center text-muted py-4">No bookings occupying this room type on the selected day.</td></tr>';
            } else {
                var rows = bookings.map(function (b) {
                    var guest = ((b.firstname || '') + ' ' + (b.lastname || '')).trim();
                    if (!guest) guest = 'Booking #' + (b.order_id || '');

                    var statusText = '';
                    var s = String(b.status || '').toLowerCase();
                    if (s === '1' || s === 'confirmed' || s === 'confirm' || s === 'reserved') statusText = 'Confirmed';
                    else if (s === '2' || s === 'pending' || s === 'provisional' || s === 'draft') statusText = 'Pending';
                    else if (s === '3' || s === 'checked_in' || s === 'checkin' || s === 'inhouse' || s === 'in-house') statusText = 'In House';
                    else if (s === '4' || s === 'checked_out' || s === 'checkout' || s === 'completed') statusText = 'Checked Out';
                    else if (s === '0' || s === 'cancelled' || s === 'canceled') statusText = 'Cancelled';
                    else statusText = s ? s : 'Open';

                    var pax = String((b.adults || 0)) + 'A';
                    if (parseInt(b.children || 0, 10) > 0) {
                        pax += ' / ' + String(b.children) + 'C';
                    }

                    var occupancyLabel = b.occupancy_label || '';
                    var occupancyClass = b.occupancy_class || '';
                    var occupancyBadge = occupancyLabel
                        ? '<span class="badge occupancy-badge ' + escapeHtml(occupancyClass) + '">' + escapeHtml(occupancyLabel) + '</span>'
                        : '';

                    return '<tr>' +
                        '<td>' + escapeHtml(b.order_no || ('#' + (b.order_id || ''))) + '</td>' +
                        '<td>' + escapeHtml(guest) + '</td>' +
                        '<td>' + escapeHtml(b.room_no || '-') + '</td>' +
                        '<td>' + escapeHtml(b.slot_no || '-') + '</td>' +
                        '<td>' + escapeHtml((b.check_in || '') + ' to ' + (b.check_out || '')) + '</td>' +
                        '<td>' + escapeHtml(pax) + '</td>' +
                        '<td>' + occupancyBadge + '</td>' +
                        '<td><span class="badge text-bg-' + badgeClassFromStatus(statusText) + '">' + escapeHtml(statusText) + '</span></td>' +
                        '<td class="text-end">' +
                            '<a href="/rooms/modules/reservations/reservation_form.php?id=' + encodeURIComponent(b.order_id || '') + '" class="btn btn-sm btn-outline-primary">' +
                                '<i class="bi bi-box-arrow-up-right me-1"></i>Open' +
                            '</a>' +
                        '</td>' +
                    '</tr>';
                });

                tbody.innerHTML = rows.join('');
            }

            var modal = bootstrap.Modal.getOrCreateInstance(modalEl);
            modal.show();
        });
    });

    <?php if ($notifiedWaitlists): ?>
    var waitlistNotifyModalEl = document.getElementById('waitlistNotifyModal');
    if (waitlistNotifyModalEl) {
        var waitlistNotifyModal = bootstrap.Modal.getOrCreateInstance(waitlistNotifyModalEl);
        setTimeout(function () {
            waitlistNotifyModal.show();
        }, 500);
    }
    <?php endif; ?>
});
</script>

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