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

$pageTitle = 'Timeline Planner';

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

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

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


if (!function_exists('planner_table_exists')) {
    function planner_table_exists(PDO $pdo, string $table): bool
    {
        static $cache = [];
        $key = strtolower($table);
        if (array_key_exists($key, $cache)) return $cache[$key];
        try {
            $stmt = $pdo->prepare("SELECT COUNT(*) FROM INFORMATION_SCHEMA.TABLES WHERE TABLE_SCHEMA = DATABASE() AND TABLE_NAME = :table_name");
            $stmt->execute([':table_name' => $table]);
            $cache[$key] = ((int)$stmt->fetchColumn() > 0);
        } catch (Throwable $e) { $cache[$key] = false; }
        return $cache[$key];
    }
}

if (!function_exists('planner_column_exists')) {
    function planner_column_exists(PDO $pdo, string $table, string $column): bool
    {
        static $cache = [];
        $key = strtolower($table . '.' . $column);
        if (array_key_exists($key, $cache)) return $cache[$key];
        try {
            $stmt = $pdo->prepare("SELECT COUNT(*) FROM INFORMATION_SCHEMA.COLUMNS WHERE TABLE_SCHEMA = DATABASE() AND TABLE_NAME = :table_name AND COLUMN_NAME = :column_name");
            $stmt->execute([':table_name' => $table, ':column_name' => $column]);
            $cache[$key] = ((int)$stmt->fetchColumn() > 0);
        } catch (Throwable $e) { $cache[$key] = false; }
        return $cache[$key];
    }
}

if (!function_exists('planner_normalize_code')) {
    function planner_normalize_code($value): string
    {
        $value = trim((string)$value);
        if ($value === '') return '';
        $value = strtoupper($value);
        $value = str_replace(['-', ' '], '_', $value);
        $value = preg_replace('/_+/', '_', $value);
        return trim($value, '_');
    }
}

if (!function_exists('planner_normalize_booking_status')) {
    function planner_normalize_booking_status($status): string
    {
        $s = planner_normalize_code($status);
        switch ($s) {
            case '1': case 'CONFIRM': case 'CONFIRMED': case 'RESERVED': return 'CONFIRMED';
            case '2': case 'PENDING': case 'PROVISIONAL': case 'DRAFT': return 'PROVISIONAL';
            case '3': case 'CHECKIN': case 'CHECKED_IN': case 'INHOUSE': case 'IN_HOUSE': return 'CHECKED_IN';
            case '4': case 'CHECKOUT': case 'CHECKED_OUT': case 'COMPLETED': return 'CHECKED_OUT';
            case '0': case 'CANCELLED': case 'CANCELED': return 'CANCELLED';
            case 'NOSHOW': case 'NO_SHOW': return 'NO_SHOW';
            default: return $s;
        }
    }
}

if (!function_exists('planner_normalize_payment_status')) {
    function planner_normalize_payment_status($status): string
    {
        $s = planner_normalize_code($status);
        switch ($s) {
            case '0': case 'UNPAID': case 'NOT_PAID': return 'UNPAID';
            case '1': case 'PART_PAID': case 'PARTLY_PAID': case 'PARTIAL': return 'PART_PAID';
            case '2': case 'PAID': case 'FULLY_PAID': case 'SETTLED': return 'PAID';
            case 'INVOICED': return 'INVOICED';
            default: return $s;
        }
    }
}

if (!function_exists('planner_humanize_code')) {
    function planner_humanize_code($value): string
    {
        $code = planner_normalize_code($value);
        return $code === '' ? 'Not set' : ucwords(strtolower(str_replace('_', ' ', $code)));
    }
}

if (!function_exists('planner_payment_due_label')) {
    function planner_payment_due_label($value): string
    {
        $code = planner_normalize_code($value);
        switch ($code) {
            case 'PAY_ON_ARRIVAL': return 'Pay On Arrival';
            case 'CHASE_PAYMENT': return 'Chase Payment';
            case 'ONLINE_PAYMENT': return 'Online Payment';
            case 'ACCOUNT': return 'Account';
            case '': return 'Not set';
            default: return planner_humanize_code($code);
        }
    }
}

if (!function_exists('planner_payment_status_label')) {
    function planner_payment_status_label($value): string
    {
        $code = planner_normalize_payment_status($value);
        switch ($code) {
            case 'UNPAID': return 'Unpaid';
            case 'PART_PAID': return 'Part Paid';
            case 'PAID': return 'Fully Paid';
            case 'INVOICED': return 'Invoiced';
            case '': return 'Not set';
            default: return planner_humanize_code($code);
        }
    }
}

if (!function_exists('planner_time_label')) {
    function planner_time_label($value): string
    {
        $value = trim((string)$value);
        if ($value === '') return '14:00 hrs';
        $ts = strtotime($value);
        return $ts ? date('H:i', $ts) . ' hrs' : $value;
    }
}

if (!function_exists('planner_room_requirement_hint')) {
    function planner_room_requirement_hint(array $booking): string
    {
        $parts = [];
        $extraBeds = (int)($booking['extra_beds_required'] ?? 0);
        $cots = (int)($booking['cots_required'] ?? 0);
        if ($extraBeds > 0) $parts[] = 'Extra Bed(s): ' . $extraBeds;
        if ($cots > 0) $parts[] = 'Cot(s): ' . $cots;
        if (!empty($booking['wheelchair_room_required'])) $parts[] = 'Wheelchair Room';
        if (!empty($booking['interleading_required'])) $parts[] = 'Interleading Required';
        foreach (['room_setup_notes' => 'Setup', 'housekeeping_notes' => 'Housekeeping', 'special_occasion' => 'Occasion'] as $key => $label) {
            $value = trim((string)($booking[$key] ?? ''));
            if ($value !== '') $parts[] = $label . ': ' . $value;
        }
        return $parts ? implode(' | ', $parts) : 'No special room setup';
    }
}

if (!function_exists('planner_status_meta')) {
    function planner_status_meta($status): array
    {
        $s = strtolower(trim((string)$status));

        switch ($s) {
            case '1':
            case 'confirmed':
            case 'confirm':
            case 'reserved':
                return ['Confirmed', 'confirmed', 'success'];

            case '2':
            case 'pending':
            case 'provisional':
            case 'draft':
                return ['Provisional', 'provisional', 'warning'];

            case '3':
            case 'checked_in':
            case 'checkin':
            case 'inhouse':
            case 'in-house':
                return ['In House', 'inhouse', 'primary'];

            case '4':
            case 'checked_out':
            case 'checkout':
            case 'completed':
                return ['Checked Out', 'checkedout', 'secondary'];

            case '0':
            case 'cancelled':
            case 'canceled':
                return ['Cancelled', 'cancelled', 'danger'];

            default:
                return [ucwords($s !== '' ? str_replace('_', ' ', $s) : 'Open'), 'default', 'dark'];
        }
    }
}

if (!function_exists('planner_booking_color')) {
    function planner_booking_color(PDO $pdo, array $booking): string
    {
        static $rules = null;

        if ($rules === null) {
            try {
                if (planner_table_exists($pdo, 'booking_color_codes')) {
                    $stmt = $pdo->query("SELECT * FROM booking_color_codes WHERE is_active = 1 ORDER BY priority_no ASC, id ASC");
                    $rules = $stmt->fetchAll(PDO::FETCH_ASSOC);
                } else {
                    $rules = [];
                }
            } catch (Throwable $e) { $rules = []; }
        }

        $status        = planner_normalize_booking_status($booking['status_code'] ?? $booking['status'] ?? '');
        $paymentDue    = planner_normalize_code($booking['payment_due'] ?? '');
        $paymentStatus = planner_normalize_payment_status($booking['payment_status'] ?? '');
        $source        = planner_normalize_code($booking['booking_source'] ?? '');
        $invoiced      = !empty($booking['invoice_number']) || ((int)($booking['invoiced'] ?? 0) === 1);
        $balance       = round((float)($booking['balance'] ?? 0), 2);

        foreach ($rules as $r) {
            $ruleStatus        = planner_normalize_booking_status($r['booking_status_code'] ?? '');
            $rulePaymentDue    = planner_normalize_code($r['payment_due_code'] ?? '');
            $rulePaymentStatus = planner_normalize_payment_status($r['payment_status_code'] ?? '');
            $ruleSource        = planner_normalize_code($r['booking_source_code'] ?? '');

            if ($ruleStatus !== '' && $ruleStatus !== $status) continue;
            if ($rulePaymentDue !== '' && $rulePaymentDue !== $paymentDue) continue;
            if ($rulePaymentStatus !== '' && $rulePaymentStatus !== $paymentStatus) continue;
            if ($ruleSource !== '' && $ruleSource !== $source) continue;

            $invoicedCondition = strtolower(trim((string)($r['invoiced_condition'] ?? 'any')));
            $balanceCondition  = strtolower(trim((string)($r['balance_condition'] ?? 'any')));
            if ($invoicedCondition === 'yes' && !$invoiced) continue;
            if ($invoicedCondition === 'no' && $invoiced) continue;
            if ($balanceCondition === 'has_balance' && $balance <= 0) continue;
            if ($balanceCondition === 'no_balance' && $balance > 0) continue;

            $bg = trim((string)($r['bg_color'] ?? ''));
            return $bg !== '' ? $bg : '#3b82f6';
        }

        return '#3b82f6';
    }
}

if (!function_exists('planner_booking_finance_hint')) {
    function planner_booking_finance_hint(array $booking): string
    {
        $parts = [
            'Payment Due: ' . planner_payment_due_label($booking['payment_due'] ?? ''),
            'Payment Status: ' . planner_payment_status_label($booking['payment_status'] ?? ''),
            'Balance: ' . number_format((float)($booking['balance'] ?? 0), 2),
        ];
        $invoiceNumber = trim((string)($booking['invoice_number'] ?? ''));
        if ($invoiceNumber !== '' || ((int)($booking['invoiced'] ?? 0) === 1)) {
            $parts[] = 'Invoiced' . ($invoiceNumber !== '' ? ': ' . $invoiceNumber : ': Yes');
        }
        return implode(' | ', $parts);
    }
}

if (!function_exists('planner_room_slot_meta')) {
    function planner_room_slot_meta($roomTypeTitle, int $adults, int $children, int $higherOccupancy = 0): array
    {
        $roomTypeTitle = trim((string)$roomTypeTitle);
        $titleLower = strtolower($roomTypeTitle);
        $totalPax = max(0, $adults) + max(0, $children);
        $isFamily = strpos($titleLower, 'family') !== false;

        if ($isFamily) {
            return [
                'label' => 'Family Room',
                'class' => 'family',
                'badge' => 'info',
                'icon'  => 'bi-people-fill',
                'is_triple' => false,
                'is_family' => true,
            ];
        }

        if ($totalPax >= 3 && ($higherOccupancy >= 3 || $higherOccupancy <= 0)) {
            return [
                'label' => 'Triple / Extra Bed',
                'class' => 'triple',
                'badge' => 'warning',
                'icon'  => 'bi-person-plus-fill',
                'is_triple' => true,
                'is_family' => false,
            ];
        }

        if ($totalPax === 2) {
            return [
                'label' => 'Double',
                'class' => 'double',
                'badge' => 'secondary',
                'icon'  => 'bi-person-fill',
                'is_triple' => false,
                'is_family' => false,
            ];
        }

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

        return [
            'label' => 'Empty',
            'class' => 'empty',
            'badge' => 'secondary',
            'icon'  => 'bi-door-open',
            'is_triple' => false,
            'is_family' => false,
        ];
    }
}

if (!function_exists('planner_bar_geometry')) {
    function planner_bar_geometry(array $booking, array $days, int $dayWidth): ?array
    {
        $rangeStart = strtotime($days[0]['date']);
        $rangeEnd   = strtotime(end($days)['date']);

        $checkIn  = strtotime((string)$booking['check_in']);
        $checkOut = strtotime((string)$booking['check_out']);

        if (!$checkIn || !$checkOut) {
            return null;
        }

        $bookingStart = max($checkIn, $rangeStart);
        $bookingEnd   = min(strtotime('-1 day', $checkOut), $rangeEnd);

        if ($bookingEnd < $rangeStart || $bookingStart > $rangeEnd || $bookingEnd < $bookingStart) {
            return null;
        }

        $offsetDays = (int) floor(($bookingStart - $rangeStart) / 86400);
        $spanDays   = (int) floor(($bookingEnd - $bookingStart) / 86400) + 1;

        return [
            'left'  => $offsetDays * $dayWidth,
            'width' => max($dayWidth, ($spanDays * $dayWidth)),
            'span'  => $spanDays,
            'start' => $bookingStart,
            'end'   => $bookingEnd,
        ];
    }
}

if (!function_exists('planner_assign_lanes')) {
    function planner_assign_lanes(array $bookings, array $days, int $dayWidth): array
    {
        $prepared = [];

        foreach ($bookings as $idx => $booking) {
            $geo = planner_bar_geometry($booking, $days, $dayWidth);
            if (!$geo) {
                continue;
            }

            $prepared[] = [
                'booking' => $booking,
                'geo'     => $geo,
                'index'   => $idx,
            ];
        }

        usort($prepared, function ($a, $b) {
            if ($a['geo']['start'] === $b['geo']['start']) {
                if ($a['geo']['end'] === $b['geo']['end']) {
                    return $a['index'] <=> $b['index'];
                }
                return $a['geo']['end'] <=> $b['geo']['end'];
            }
            return $a['geo']['start'] <=> $b['geo']['start'];
        });

        $laneEndTimes = [];
        $output = [];

        foreach ($prepared as $item) {
            $assignedLane = null;

            foreach ($laneEndTimes as $lane => $laneEnd) {
                if ($item['geo']['start'] > $laneEnd) {
                    $assignedLane = $lane;
                    break;
                }
            }

            if ($assignedLane === null) {
                $assignedLane = count($laneEndTimes);
            }

            $laneEndTimes[$assignedLane] = $item['geo']['end'];

            $output[] = [
                'booking' => $item['booking'],
                'geo'     => $item['geo'],
                'lane'    => $assignedLane,
            ];
        }

        return [
            'items'      => $output,
            'lane_count' => max(1, count($laneEndTimes)),
        ];
    }
}

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,
            ];
        }

        $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();

        $sql = "
            SELECT COALESCE(SUM(o.totalrooms), 0)
            FROM orders o
            WHERE o.property_id = :property_id
              AND o.room_type_id = :room_type_id
              AND COALESCE(o.status, 1) <> 0
              AND o.check_in < :check_out
              AND o.check_out > :check_in
        ";

        $params = [
            ':property_id'  => $propertyId,
            ':room_type_id' => $roomTypeId,
            ':check_in'     => $checkIn,
            ':check_out'    => $checkOut,
        ];

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

        $stmtOcc = $pdo->prepare($sql);
        $stmtOcc->execute($params);
        $occupiedRooms = (int)$stmtOcc->fetchColumn();

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

if (!function_exists('build_waitlist_url')) {
    function build_waitlist_url(array $params = []): string
    {
        $base = '/rooms/modules/reservations/waitlist.php';
        $query = http_build_query(array_filter($params, static function ($v) {
            return $v !== null && $v !== '';
        }));

        return $base . ($query !== '' ? ('?' . $query) : '');
    }
}

if (!function_exists('fetch_waitlist_alert_summary')) {
    function fetch_waitlist_alert_summary(PDO $pdo): array
    {
        if (!function_exists('waitlist_table_exists') || !waitlist_table_exists($pdo)) {
            return [
                'waiting_count'  => 0,
                'notified_count' => 0,
            ];
        }

        $sql = "
            SELECT
                SUM(CASE WHEN status = 'waiting' THEN 1 ELSE 0 END)  AS waiting_count,
                SUM(CASE WHEN status = 'notified' THEN 1 ELSE 0 END) AS notified_count
            FROM reservation_waitlist
            WHERE status IN ('waiting', 'notified')
        ";
        $row = $pdo->query($sql)->fetch(PDO::FETCH_ASSOC) ?: [];

        return [
            'waiting_count'  => (int)($row['waiting_count'] ?? 0),
            'notified_count' => (int)($row['notified_count'] ?? 0),
        ];
    }
}

$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);
if ($selectedPropertyId <= 0 && !empty($properties)) {
    $selectedPropertyId = (int)$properties[0]['id'];
}

$dateFrom  = trim((string)($_GET['from'] ?? date('Y-m-d')));
$dateTo    = trim((string)($_GET['to'] ?? date('Y-m-d', strtotime('+13 days'))));
$focusRoom = (int)($_GET['room_id'] ?? 0);

$fromTs = strtotime($dateFrom);
$toTs   = strtotime($dateTo);

if (!$fromTs) {
    $fromTs = strtotime(date('Y-m-d'));
    $dateFrom = date('Y-m-d', $fromTs);
}
if (!$toTs || $toTs < $fromTs) {
    $toTs = strtotime('+13 days', $fromTs);
    $dateTo = date('Y-m-d', $toTs);
}

$days = [];
$cursor = $fromTs;
while ($cursor <= $toTs) {
    $days[] = [
        'date' => date('Y-m-d', $cursor),
        'day' => date('D', $cursor),
        'num' => date('d', $cursor),
        'mon' => date('M', $cursor),
        'is_today' => date('Y-m-d') === date('Y-m-d', $cursor),
    ];
    $cursor = strtotime('+1 day', $cursor);
}

$totalDays = count($days);
$defaultDayWidth = 70;
$dayWidth = $defaultDayWidth;
$roomLabelWidth = 160;
$fitToScreenRange = ($totalDays > 0 && $totalDays <= 31);
$rowMinWidth = $roomLabelWidth + ($totalDays * $dayWidth);
$plannerFitMode = $fitToScreenRange ? 'fit' : 'scroll';

$rooms = [];
if ($selectedPropertyId > 0) {
    $stmtRooms = $pdo->prepare("
        SELECT
            r.id,
            r.property_id,
            r.room_no,
            r.status,
            r.room_type_id,
            " . (planner_column_exists($pdo, 'rooms', 'max_occupancy') ? "r.max_occupancy" : "NULL") . " AS max_occupancy,
            " . (planner_column_exists($pdo, 'rooms', 'allows_extra_bed') ? "r.allows_extra_bed" : "0") . " AS allows_extra_bed,
            " . (planner_column_exists($pdo, 'rooms', 'max_extra_beds') ? "r.max_extra_beds" : "0") . " AS max_extra_beds,
            " . (planner_column_exists($pdo, 'rooms', 'allows_baby_cot') ? "r.allows_baby_cot" : "0") . " AS allows_baby_cot,
            " . (planner_column_exists($pdo, 'rooms', 'max_cots') ? "r.max_cots" : "0") . " AS max_cots,
            " . (planner_column_exists($pdo, 'rooms', 'wheelchair_accessible') ? "r.wheelchair_accessible" : "0") . " AS wheelchair_accessible,
            " . (planner_column_exists($pdo, 'rooms', 'interleading_group') ? "r.interleading_group" : "NULL") . " AS interleading_group,
            rt.title AS room_type,
            rt.higher_occupancy AS room_higher_occupancy,
            p.name AS property_name,
            p.code AS property_code
        FROM rooms r
        LEFT JOIN room_types rt ON rt.id = r.room_type_id
        LEFT JOIN properties p ON p.id = r.property_id
        WHERE r.property_id = :property_id
        ORDER BY r.floor_id ASC, r.room_no ASC
    ");
    $stmtRooms->execute([':property_id' => $selectedPropertyId]);
    $rooms = $stmtRooms->fetchAll(PDO::FETCH_ASSOC);
}

$roomTypeSummaries = [];
if ($selectedPropertyId > 0) {
    $stmtRoomTypes = $pdo->prepare("
        SELECT
            rt.id,
            rt.title,
            rt.higher_occupancy,
            COUNT(r.id) AS total_rooms
        FROM room_types rt
        LEFT JOIN rooms r
          ON r.room_type_id = rt.id
         AND r.property_id = rt.property_id
        WHERE rt.property_id = :property_id
        GROUP BY rt.id, rt.title, rt.higher_occupancy
        ORDER BY rt.title ASC
    ");
    $stmtRoomTypes->execute([':property_id' => $selectedPropertyId]);
    $roomTypeRows = $stmtRoomTypes->fetchAll(PDO::FETCH_ASSOC);

    foreach ($roomTypeRows as $typeRow) {
        $availability = count_available_rooms_by_type(
            $pdo,
            $selectedPropertyId,
            (int)$typeRow['id'],
            $dateFrom,
            $dateTo
        );

        $roomTypeSummaries[] = [
            'id'              => (int)$typeRow['id'],
            'title'           => (string)$typeRow['title'],
            'higher_occupancy'=> (int)($typeRow['higher_occupancy'] ?? 0),
            'total_rooms'     => (int)($availability['total_rooms'] ?? 0),
            'occupied_rooms'  => (int)($availability['occupied_rooms'] ?? 0),
            'available_rooms' => (int)($availability['available_rooms'] ?? 0),
            'book_url'        => '/rooms/modules/reservations/reservation_form.php?' . http_build_query([
                'property_id'  => $selectedPropertyId,
                'room_type_id' => (int)$typeRow['id'],
                'check_in'     => $dateFrom,
                'check_out'    => $dateTo,
            ]),
            'waitlist_url'    => build_waitlist_url([
                'property_id'  => $selectedPropertyId,
                'room_type_id' => (int)$typeRow['id'],
                'check_in'     => $dateFrom,
                'check_out'    => $dateTo,
                'totalrooms'   => 1,
                'adults'       => 2,
                'kids'         => 0,
                'source'       => 'availability_planner',
            ]),
        ];
    }
}


$bookingSourceSql  = planner_column_exists($pdo, 'orders', 'booking_source') ? "o.booking_source" : "NULL";
$paymentDueSql     = planner_column_exists($pdo, 'orders', 'payment_due') ? "o.payment_due" : "NULL";
$paymentStatusSql  = planner_column_exists($pdo, 'orders', 'payment_status') ? "o.payment_status" : "NULL";
$invoiceNumberSql  = planner_column_exists($pdo, 'orders', 'invoice_number') ? "o.invoice_number" : "NULL";
$invoicedSql       = planner_column_exists($pdo, 'orders', 'invoiced') ? "o.invoiced" : "0";
$expectedArrivalSql = planner_column_exists($pdo, 'orders', 'expected_arrival_time') ? "o.expected_arrival_time" : "'14:00:00'";

$folioBalanceSql = "0";
if (planner_table_exists($pdo, 'folios') && planner_column_exists($pdo, 'folios', 'order_id') && planner_column_exists($pdo, 'folios', 'balance')) {
    $folioBalanceSql = "(SELECT COALESCE(SUM(f.balance), 0) FROM folios f WHERE f.order_id = o.id)";
}

$statusCodeSql = "
    CASE
        WHEN LOWER(TRIM(CAST(o.status AS CHAR))) IN ('1','confirmed','confirm','reserved') THEN 'CONFIRMED'
        WHEN LOWER(TRIM(CAST(o.status AS CHAR))) IN ('2','pending','provisional','draft') THEN 'PROVISIONAL'
        WHEN LOWER(TRIM(CAST(o.status AS CHAR))) IN ('3','checked_in','checkin','inhouse','in-house') THEN 'CHECKED_IN'
        WHEN LOWER(TRIM(CAST(o.status AS CHAR))) IN ('4','checked_out','checkout','completed') THEN 'CHECKED_OUT'
        WHEN LOWER(TRIM(CAST(o.status AS CHAR))) IN ('0','cancelled','canceled') THEN 'CANCELLED'
        WHEN LOWER(TRIM(CAST(o.status AS CHAR))) IN ('noshow','no_show') THEN 'NO_SHOW'
        ELSE UPPER(TRIM(CAST(o.status AS CHAR)))
    END
";

$roomingExtraBedsSql = planner_column_exists($pdo, 'order_rooming', 'extra_beds_required') ? "rmg.extra_beds_required" : "0";
$roomingCotsSql = planner_column_exists($pdo, 'order_rooming', 'cots_required') ? "rmg.cots_required" : "0";
$roomingWheelchairSql = planner_column_exists($pdo, 'order_rooming', 'wheelchair_room_required') ? "rmg.wheelchair_room_required" : "0";
$roomingInterleadingSql = planner_column_exists($pdo, 'order_rooming', 'interleading_required') ? "rmg.interleading_required" : "0";
$roomingSetupNotesSql = planner_column_exists($pdo, 'order_rooming', 'room_setup_notes') ? "rmg.room_setup_notes" : "NULL";
$roomingHousekeepingNotesSql = planner_column_exists($pdo, 'order_rooming', 'housekeeping_notes') ? "rmg.housekeeping_notes" : "NULL";
$roomingSpecialOccasionSql = planner_column_exists($pdo, 'order_rooming', 'special_occasion') ? "rmg.special_occasion" : "NULL";

$bookings = [];
if ($selectedPropertyId > 0) {
    $stmt = $pdo->prepare("
        SELECT
            rmg.id AS rooming_id,
            rmg.order_id,
            rmg.property_id,
            rmg.room_no,
            rmg.room_id,
            rmg.room_type_id,
            rmg.adults,
            rmg.children,
            rmg.check_in,
            rmg.check_out,
            o.order_no,
            o.status,
            {$statusCodeSql} AS status_code,
            {$bookingSourceSql} AS booking_source,
            {$paymentDueSql} AS payment_due,
            {$paymentStatusSql} AS payment_status,
            {$invoiceNumberSql} AS invoice_number,
            {$invoicedSql} AS invoiced,
            {$expectedArrivalSql} AS expected_arrival_time,
            {$folioBalanceSql} AS balance,
            {$roomingExtraBedsSql} AS extra_beds_required,
            {$roomingCotsSql} AS cots_required,
            {$roomingWheelchairSql} AS wheelchair_room_required,
            {$roomingInterleadingSql} AS interleading_required,
            {$roomingSetupNotesSql} AS room_setup_notes,
            {$roomingHousekeepingNotesSql} AS housekeeping_notes,
            {$roomingSpecialOccasionSql} AS special_occasion,
            o.totalamount,
            g.firstname,
            g.lastname,
            rt.title AS room_type,
            rt.higher_occupancy AS room_higher_occupancy,
            p.name AS property_name,
            p.code AS property_code
        FROM order_rooming rmg
        INNER JOIN orders o ON o.id = rmg.order_id
        LEFT JOIN guests g ON g.id = o.guest_id
        LEFT JOIN room_types rt ON rt.id = rmg.room_type_id
        LEFT JOIN properties p ON p.id = o.property_id
        WHERE rmg.property_id = :property_id
          AND COALESCE(o.status, 1) <> 0
          AND rmg.check_in < DATE_ADD(:toDate, INTERVAL 1 DAY)
          AND rmg.check_out > :fromDate
        ORDER BY rmg.check_in, rmg.order_id, rmg.room_no
    ");
    $stmt->execute([
        ':property_id' => $selectedPropertyId,
        ':fromDate'    => $dateFrom,
        ':toDate'      => $dateTo
    ]);
    $bookings = $stmt->fetchAll(PDO::FETCH_ASSOC);
}

$byRoom = [];
$unassigned = [];

foreach ($bookings as $booking) {
    $roomId = (int)($booking['room_id'] ?? 0);
    if ($roomId > 0) {
        $byRoom[$roomId][] = $booking;
    } else {
        $unassigned[] = $booking;
    }
}

if (function_exists('refresh_waitlist_matches') && $selectedPropertyId > 0) {
    refresh_waitlist_matches($pdo, $selectedPropertyId, null);
}

$waitlistSummary = fetch_waitlist_alert_summary($pdo);
$notifiedWaitlists = function_exists('fetch_notified_waitlists') ? fetch_notified_waitlists($pdo, 8) : [];

$totalBookings = count($bookings);
$totalUnassigned = count($unassigned);
$occupiedRooms = 0;
foreach ($rooms as $room) {
    if (!empty($byRoom[(int)$room['id']])) {
        $occupiedRooms++;
    }
}

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

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

<div class="timeline-hero card border-0 shadow-sm mb-3 overflow-hidden compact-top-card">
    <div class="card-body p-3 p-lg-3">
        <div class="row g-3 align-items-center">
            <div class="col-lg-8">
                <div class="page-eyebrow mb-2">
                    <i class="bi bi-calendar-range"></i> Occupancy Timeline
                </div>
                <h4 class="mb-1 fw-bold">Professional room timeline planner</h4>
                <div class="text-muted small">
                    Occupancy by property, room and date with draggable booking slots.
                </div>
                <div class="mt-1 small text-muted">
                    Current property: <strong><?php echo planner_e($currentPropertyLabel); ?></strong>
                </div>
            </div>
            <div class="col-lg-4">
                <div class="d-flex flex-wrap justify-content-lg-end gap-2">
                    <a class="btn btn-primary" href="/rooms/modules/reservations/reservation_form.php?property_id=<?php echo (int)$selectedPropertyId; ?>">
                        <i class="bi bi-plus-circle me-2"></i>New Reservation
                    </a>
                    <a class="btn btn-outline-secondary position-relative" href="/rooms/modules/reservations/waitlist.php?property_id=<?php echo (int)$selectedPropertyId; ?>&check_in=<?php echo urlencode($dateFrom); ?>&check_out=<?php echo urlencode($dateTo); ?>&source=availability_planner">
                        <i class="bi bi-clock-history me-2"></i>Waitlist
                        <?php if ((int)$waitlistSummary['notified_count'] > 0): ?>
                            <span class="position-absolute top-0 start-100 translate-middle badge rounded-pill text-bg-danger">
                                <?php echo (int)$waitlistSummary['notified_count']; ?>
                            </span>
                        <?php endif; ?>
                    </a>
                    <a class="btn btn-outline-secondary" href="/rooms/modules/reservations/reservation_list.php?property_id=<?php echo (int)$selectedPropertyId; ?>">
                        <i class="bi bi-journal-text me-2"></i>Reservations
                    </a>
                </div>
            </div>
        </div>

        <div class="row g-2 mt-3">
            <div class="col-md-3 col-sm-6">
                <div class="timeline-stat">
                    <div class="timeline-stat-icon bg-primary-subtle text-primary"><i class="bi bi-door-open"></i></div>
                    <div>
                        <div class="timeline-stat-value"><?php echo (int)count($rooms); ?></div>
                        <div class="timeline-stat-label">Rooms</div>
                    </div>
                </div>
            </div>
            <div class="col-md-3 col-sm-6">
                <div class="timeline-stat">
                    <div class="timeline-stat-icon bg-success-subtle text-success"><i class="bi bi-journal-check"></i></div>
                    <div>
                        <div class="timeline-stat-value"><?php echo (int)$totalBookings; ?></div>
                        <div class="timeline-stat-label">Room Slots In Range</div>
                    </div>
                </div>
            </div>
            <div class="col-md-3 col-sm-6">
                <div class="timeline-stat">
                    <div class="timeline-stat-icon bg-warning-subtle text-warning"><i class="bi bi-grid-3x3-gap"></i></div>
                    <div>
                        <div class="timeline-stat-value"><?php echo (int)$occupiedRooms; ?></div>
                        <div class="timeline-stat-label">Occupied Rooms</div>
                    </div>
                </div>
            </div>
            <div class="col-md-3 col-sm-6">
                <div class="timeline-stat">
                    <div class="timeline-stat-icon bg-danger-subtle text-danger"><i class="bi bi-exclamation-circle"></i></div>
                    <div>
                        <div class="timeline-stat-value"><?php echo (int)$totalUnassigned; ?></div>
                        <div class="timeline-stat-label">Unassigned Slots</div>
                    </div>
                </div>
            </div>
        </div>
    </div>
</div>

<div class="card border-0 shadow-sm mb-3 compact-filter-card">
    <div class="card-body p-3">
        <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" id="property_id">
                    <option value="0">Select property</option>
                    <?php foreach ($properties as $property): ?>
                        <option value="<?php echo (int)$property['id']; ?>" <?php echo $selectedPropertyId === (int)$property['id'] ? 'selected' : ''; ?>>
                            <?php echo planner_e($property['name']); ?><?php echo !empty($property['code']) ? ' - ' . planner_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 planner_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 planner_e($dateTo); ?>">
            </div>

            <div class="col-xl-3 col-md-6">
                <label class="form-label fw-semibold">Focus Room</label>
                <select class="form-select" name="room_id">
                    <option value="0">All rooms</option>
                    <?php foreach ($rooms as $room): ?>
                        <option value="<?php echo (int)$room['id']; ?>" <?php echo $focusRoom === (int)$room['id'] ? 'selected' : ''; ?>>
                            Room <?php echo planner_e($room['room_no']); ?><?php echo !empty($room['room_type']) ? ' - ' . planner_e($room['room_type']) : ''; ?>
                        </option>
                    <?php endforeach; ?>
                </select>
            </div>

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

        <?php if ($selectedPropertyId > 0): ?>
            <div class="d-flex flex-wrap gap-2 mt-2">
                <a class="btn btn-warning" href="/rooms/modules/reservations/waitlist.php?property_id=<?php echo (int)$selectedPropertyId; ?>&check_in=<?php echo urlencode($dateFrom); ?>&check_out=<?php echo urlencode($dateTo); ?>&source=availability_planner_filters">
                    <i class="bi bi-clock-history me-2"></i>Add Selected Stay to Waitlist
                </a>
                <a class="btn btn-outline-primary" href="/rooms/modules/reservations/reservation_form.php?property_id=<?php echo (int)$selectedPropertyId; ?>&check_in=<?php echo urlencode($dateFrom); ?>&check_out=<?php echo urlencode($dateTo); ?>">
                    <i class="bi bi-journal-plus me-2"></i>New Reservation For Selected Stay
                </a>
            </div>
        <?php endif; ?>
    </div>
</div>

<?php if ($selectedPropertyId > 0 && $roomTypeSummaries): ?>
<div class="card border-0 shadow-sm mb-3 compact-roomtype-card">
    <div class="card-header bg-white border-0 p-3 pb-0">
        <h5 class="mb-1">Room type availability for selected stay</h5>
        <div class="text-muted">If a room type is full for the selected date range, staff can move directly to the waitlist with the stay prefilled.</div>
    </div>
    <div class="card-body p-3">
        <div class="row g-2">
            <?php foreach ($roomTypeSummaries as $summary): ?>
                <div class="col-xl-3 col-lg-4 col-md-6">
                    <div class="availability-card h-100">
                        <div class="d-flex justify-content-between align-items-start gap-3">
                            <div>
                                <div class="fw-bold"><?php echo planner_e($summary['title']); ?></div>
                                <div class="small text-muted">
                                    <?php echo (int)$summary['occupied_rooms']; ?> occupied / <?php echo (int)$summary['total_rooms']; ?> total
                                </div>
                                <?php if ((int)($summary['higher_occupancy'] ?? 0) >= 3 && stripos((string)$summary['title'], 'family') === false): ?>
                                    <div class="small text-warning fw-semibold mt-1"><i class="bi bi-person-plus me-1"></i>Triple / extra bed possible</div>
                                <?php endif; ?>
                            </div>
                            <?php if ((int)$summary['available_rooms'] > 0): ?>
                                <span class="badge text-bg-success"><?php echo (int)$summary['available_rooms']; ?> available</span>
                            <?php else: ?>
                                <span class="badge text-bg-danger">No availability</span>
                            <?php endif; ?>
                        </div>

                        <div class="mt-3 d-grid gap-2">
                            <?php if ((int)$summary['available_rooms'] > 0): ?>
                                <a href="<?php echo planner_e($summary['book_url']); ?>" class="btn btn-outline-primary btn-sm">
                                    <i class="bi bi-box-arrow-up-right me-2"></i>Book This Type
                                </a>
                            <?php else: ?>
                                <a href="<?php echo planner_e($summary['waitlist_url']); ?>" class="btn btn-warning btn-sm">
                                    <i class="bi bi-clock-history me-2"></i>Add to Waitlist
                                </a>
                            <?php endif; ?>

                            <a href="/rooms/modules/reservations/waitlist.php?property_id=<?php echo (int)$selectedPropertyId; ?>&room_type_id=<?php echo (int)$summary['id']; ?>&check_in=<?php echo urlencode($dateFrom); ?>&check_out=<?php echo urlencode($dateTo); ?>&source=availability_planner_card"
                               class="btn btn-light btn-sm border">
                                Open Waitlist
                            </a>
                        </div>
                    </div>
                </div>
            <?php endforeach; ?>
        </div>
    </div>
</div>
<?php endif; ?>

<?php if ($selectedPropertyId <= 0): ?>
    <div class="alert alert-warning">Please select a property to view the planner.</div>
<?php endif; ?>

<?php if ($selectedPropertyId > 0): ?>
<div class="card border-0 shadow-sm mb-3 holding-drop-card compact-holding-card" data-holding-dropzone data-room-id="0">
    <div class="card-header bg-white border-0 p-3 pb-0 d-flex flex-wrap justify-content-between align-items-center gap-2">
        <div>
            <h5 class="mb-1"><i class="bi bi-inboxes me-2 text-warning"></i>Temporary Holding Area</h5>
            <div class="text-muted">Drag a booking here to temporarily move it out of a room while you rearrange nearby rooms for groups.</div>
        </div>
        <span class="badge text-bg-warning px-3 py-2"><?php echo (int)$totalUnassigned; ?> held / unassigned</span>
    </div>
    <div class="card-body p-3">
        <div class="holding-drop-zone">
            <div class="holding-drop-help"><i class="bi bi-arrows-move me-2"></i>Drop a booking here to hold it temporarily. Then drag it back into any suitable available room.</div>
            <?php if ($unassigned): ?>
                <div class="timeline-unassigned mt-3">
                    <?php foreach ($unassigned as $booking): ?>
                        <?php
                        [$statusLabel, $statusClass, $badgeClass] = planner_status_meta($booking['status']);
                        $guestName = trim(($booking['firstname'] ?? '') . ' ' . ($booking['lastname'] ?? ''));
                        if ($guestName === '') {
                            $guestName = 'Booking #' . (int)$booking['order_id'];
                        }
                        $slotMeta = planner_room_slot_meta(
                            $booking['room_type'] ?? '',
                            (int)($booking['adults'] ?? 0),
                            (int)($booking['children'] ?? 0),
                            (int)($booking['room_higher_occupancy'] ?? 0)
                        );
                        ?>
                        <div class="timeline-unassigned-card booking-bar-static unassigned-card occupancy-<?php echo planner_e($slotMeta['class']); ?>"
                             draggable="true"
                             data-rooming-id="<?php echo (int)$booking['rooming_id']; ?>"
                             data-order-id="<?php echo (int)$booking['order_id']; ?>"
                             data-check-in="<?php echo planner_e($booking['check_in']); ?>"
                             data-check-out="<?php echo planner_e($booking['check_out']); ?>">
                            <div class="fw-bold"><?php echo planner_e($guestName); ?></div>
                            <div class="small text-muted">
                                <?php echo planner_e($booking['order_no'] ?: ('#' . $booking['order_id'])); ?> •
                                Slot <?php echo (int)$booking['room_no']; ?> •
                                <?php echo planner_e(planner_display_date($booking['check_in'])); ?> →
                                <?php echo planner_e(planner_display_date($booking['check_out'])); ?>
                            </div>
                            <div class="small text-muted">
                                <?php echo (int)$booking['adults']; ?>A<?php echo (int)$booking['children'] > 0 ? ' / ' . (int)$booking['children'] . 'C' : ''; ?>
                                <?php if (!empty($booking['room_type'])): ?> • <?php echo planner_e($booking['room_type']); ?><?php endif; ?>
                                • ETA <?php echo planner_e(planner_time_label($booking['expected_arrival_time'] ?? '14:00')); ?>
                            </div>
                            <?php if (planner_room_requirement_hint($booking) !== 'No special room setup'): ?>
                                <div class="small text-muted"><?php echo planner_e(planner_room_requirement_hint($booking)); ?></div>
                            <?php endif; ?>
                            <div class="mt-2 d-flex flex-wrap gap-1">
                                <?php if ($slotMeta['is_triple'] || $slotMeta['is_family']): ?>
                                    <span class="badge text-bg-<?php echo planner_e($slotMeta['badge']); ?>">
                                        <i class="bi <?php echo planner_e($slotMeta['icon']); ?> me-1"></i><?php echo planner_e($slotMeta['label']); ?>
                                    </span>
                                <?php endif; ?>
                                <span class="badge text-bg-<?php echo planner_e($badgeClass); ?>"><?php echo planner_e($statusLabel); ?></span>
                            </div>
                        </div>
                    <?php endforeach; ?>
                </div>
            <?php else: ?>
                <div class="holding-empty mt-3">No bookings are currently in holding.</div>
            <?php endif; ?>
        </div>
    </div>
</div>
<?php endif; ?>

<?php if ($selectedPropertyId > 0): ?>
<div class="card border-0 shadow-sm">
    <div class="card-body p-0">
        <div class="timeline-wrap" id="plannerTimelineWrap" data-fit-mode="<?php echo planner_e($plannerFitMode); ?>" data-total-days="<?php echo (int)$totalDays; ?>" data-room-label-width="<?php echo (int)$roomLabelWidth; ?>" data-default-day-width="<?php echo (int)$defaultDayWidth; ?>" data-range-from="<?php echo planner_e($dateFrom); ?>" data-range-to="<?php echo planner_e($dateTo); ?>">
            <div class="timeline-table" style="min-width: <?php echo (int)$rowMinWidth; ?>px;">
                <div class="timeline-head">
                    <div class="timeline-room-head">Room</div>
                    <div class="timeline-days-head" style="width: <?php echo (int)($totalDays * $dayWidth); ?>px;">
                        <?php foreach ($days as $day): ?>
                            <div class="timeline-day-head <?php echo $day['is_today'] ? 'is-today' : ''; ?>" data-planner-day-cell style="width: <?php echo (int)$dayWidth; ?>px;">
                                <div class="day-name"><?php echo planner_e($day['day']); ?></div>
                                <div class="day-num"><?php echo planner_e($day['num']); ?></div>
                                <div class="day-mon"><?php echo planner_e($day['mon']); ?></div>
                            </div>
                        <?php endforeach; ?>
                    </div>
                </div>

                <?php foreach ($rooms as $room): ?>
                    <?php
                    $roomId = (int)$room['id'];
                    if ($focusRoom > 0 && $focusRoom !== $roomId) {
                        continue;
                    }

                    $roomBookings = $byRoom[$roomId] ?? [];
                    $laneData = planner_assign_lanes($roomBookings, $days, $dayWidth);
                    $roomItems = $laneData['items'];
                    $laneCount = $laneData['lane_count'];

                    $barHeight = 30;
                    $barGap = 4;
                    $topPadding = 6;
                    $bottomPadding = 6;
                    $computedRowHeight = ($laneCount > 0)
                        ? $topPadding + ($laneCount * $barHeight) + (($laneCount - 1) * $barGap) + $bottomPadding
                        : 48;
                    ?>
                    <div class="timeline-row"
                         data-room-dropzone
                         data-room-id="<?php echo $roomId; ?>"
                         data-room-no="<?php echo planner_e($room['room_no']); ?>"
                         style="min-height: <?php echo (int)$computedRowHeight; ?>px;">
                        <div class="timeline-room-meta" style="min-height: <?php echo (int)$computedRowHeight; ?>px;">
                            <div class="room-title">Room <?php echo planner_e($room['room_no']); ?></div>
                            <div class="room-subtitle"><?php echo planner_e($room['room_type'] ?: 'No type'); ?></div>
                            <?php if ((int)($room['room_higher_occupancy'] ?? 0) >= 3 && stripos((string)($room['room_type'] ?? ''), 'family') === false): ?>
                                <div class="room-capacity-badge"><i class="bi bi-person-plus me-1"></i>Triple possible</div>
                            <?php endif; ?>
                            <div class="room-status"><?php echo planner_e((string)$room['status']); ?></div>
                            <?php if ((int)($room['allows_extra_bed'] ?? 0) === 1 || (int)($room['allows_baby_cot'] ?? 0) === 1 || (int)($room['wheelchair_accessible'] ?? 0) === 1 || trim((string)($room['interleading_group'] ?? '')) !== ''): ?>
                                <div class="room-feature-line">
                                    <?php if ((int)($room['allows_extra_bed'] ?? 0) === 1): ?>EB<?php endif; ?>
                                    <?php if ((int)($room['allows_baby_cot'] ?? 0) === 1): ?> Cot<?php endif; ?>
                                    <?php if ((int)($room['wheelchair_accessible'] ?? 0) === 1): ?> Access<?php endif; ?>
                                    <?php if (trim((string)($room['interleading_group'] ?? '')) !== ''): ?> Interlead<?php endif; ?>
                                </div>
                            <?php endif; ?>
                        </div>

                        <div class="timeline-grid-area"
                             style="width: <?php echo (int)($totalDays * $dayWidth); ?>px; min-height: <?php echo (int)$computedRowHeight; ?>px;">
                            <div class="timeline-grid-lines">
                                <?php foreach ($days as $day): ?>
                                    <div class="timeline-cell <?php echo $day['is_today'] ? 'is-today' : ''; ?>" data-planner-day-cell style="width: <?php echo (int)$dayWidth; ?>px;"></div>
                                <?php endforeach; ?>
                            </div>

                            <div class="timeline-bars" style="min-height: <?php echo (int)$computedRowHeight; ?>px;">
                                <?php if (!$roomItems): ?>
                                    <div class="timeline-empty">Drop room slot here</div>
                                <?php endif; ?>

                                <?php foreach ($roomItems as $item): ?>
                                    <?php
                                    $booking = $item['booking'];
                                    $geo = $item['geo'];

                                    [$statusLabel, $statusClass, $badgeClass] = planner_status_meta($booking['status']);
                                    $guestName = trim(($booking['firstname'] ?? '') . ' ' . ($booking['lastname'] ?? ''));
                                    if ($guestName === '') {
                                        $guestName = 'Booking #' . (int)$booking['order_id'];
                                    }

                                    $slotMeta = planner_room_slot_meta(
                                        $booking['room_type'] ?? '',
                                        (int)($booking['adults'] ?? 0),
                                        (int)($booking['children'] ?? 0),
                                        (int)($booking['room_higher_occupancy'] ?? 0)
                                    );

                                    $tooltip = $guestName
                                        . ' | Ref: ' . ($booking['order_no'] ?: ('#' . $booking['order_id']))
                                        . ' | Slot ' . (int)$booking['room_no']
                                        . ' | ' . planner_display_date($booking['check_in']) . ' → ' . planner_display_date($booking['check_out'])
                                        . ' | ETA: ' . planner_time_label($booking['expected_arrival_time'] ?? '14:00')
                                        . ' | ' . (int)$booking['adults'] . 'A' . ((int)$booking['children'] > 0 ? ' / ' . (int)$booking['children'] . 'C' : '')
                                        . ' | ' . ($booking['room_type'] ?? '')
                                        . ' | ' . $slotMeta['label']
                                        . ' | Booking Status: ' . $statusLabel
                                        . ' | ' . planner_booking_finance_hint($booking)
                                        . ' | Room Setup: ' . planner_room_requirement_hint($booking);

                                    $top = $topPadding + ($item['lane'] * ($barHeight + $barGap));
                                    ?>
                                    <div class="booking-bar occupancy-<?php echo planner_e($slotMeta['class']); ?>"
                                         style="left: <?php echo (int)$geo['left']; ?>px; width: <?php echo (int)$geo['width']; ?>px; top: <?php echo (int)$top; ?>px; background: <?php echo planner_e(planner_booking_color($pdo, $booking)); ?>;"
                                         draggable="true"
                                         data-rooming-id="<?php echo (int)$booking['rooming_id']; ?>"
                                         data-order-id="<?php echo (int)$booking['order_id']; ?>"
                                         data-check-in="<?php echo planner_e($booking['check_in']); ?>"
                                         data-check-out="<?php echo planner_e($booking['check_out']); ?>"
                                         title="<?php echo planner_e($tooltip); ?>">

                                        <div class="bar-main">
                                            <span class="bar-guest"><?php echo planner_e($guestName); ?></span>
                                            <?php if ($slotMeta['is_triple'] || $slotMeta['is_family']): ?>
                                                <span class="bar-occupancy-badge">
                                                    <i class="bi <?php echo planner_e($slotMeta['icon']); ?>"></i>
                                                    <?php echo $slotMeta['is_triple'] ? 'Triple' : 'Family'; ?>
                                                </span>
                                            <?php endif; ?>
                                            <?php if ((int)($booking['extra_beds_required'] ?? 0) > 0): ?>
                                                <span class="bar-occupancy-badge"><i class="bi bi-person-plus"></i>Extra Bed</span>
                                            <?php endif; ?>
                                            <?php if ((int)($booking['cots_required'] ?? 0) > 0): ?>
                                                <span class="bar-occupancy-badge"><i class="bi bi-baby"></i>Cot</span>
                                            <?php endif; ?>
                                            <?php if (!empty($booking['wheelchair_room_required'])): ?>
                                                <span class="bar-occupancy-badge"><i class="bi bi-universal-access"></i>Access</span>
                                            <?php endif; ?>
                                        </div>

                                        <a class="bar-open"
                                           href="/rooms/modules/reservations/reservation_form.php?id=<?php echo (int)$booking['order_id']; ?>"
                                           onclick="event.stopPropagation();"
                                           title="Open booking">
                                            <i class="bi bi-box-arrow-up-right"></i>
                                        </a>
                                    </div>
                                <?php endforeach; ?>
                            </div>
                        </div>
                    </div>
                <?php endforeach; ?>

                <?php if (!$rooms): ?>
                    <div class="p-4 text-muted">No rooms found for the selected property.</div>
                <?php endif; ?>
            </div>
        </div>
    </div>
</div>
<?php endif; ?>

<?php if ($notifiedWaitlists): ?>
<div class="modal fade" id="waitlistAvailabilityModal" tabindex="-1" aria-hidden="true">
    <div class="modal-dialog modal-lg modal-dialog-scrollable">
        <div class="modal-content border-0 shadow">
            <div class="modal-header">
                <h5 class="modal-title"><i class="bi bi-bell-fill text-warning me-2"></i>Waitlist availability alerts</h5>
                <button type="button" class="btn-close" data-bs-dismiss="modal" aria-label="Close"></button>
            </div>
            <div class="modal-body">
                <div class="alert alert-success">
                    One or more waitlisted requests can now be confirmed because rooms have become available.
                </div>

                <div class="list-group">
                    <?php foreach ($notifiedWaitlists as $wl): ?>
                        <div class="list-group-item py-3">
                            <div class="d-flex flex-wrap justify-content-between gap-3">
                                <div>
                                    <div class="fw-bold"><?php echo planner_e($wl['guest_name'] ?: ('Waitlist #' . (int)$wl['id'])); ?></div>
                                    <div class="small text-muted">
                                        <?php echo planner_e($wl['property_name'] ?? ''); ?>
                                        <?php if (!empty($wl['room_type_name'])): ?> • <?php echo planner_e($wl['room_type_name']); ?><?php endif; ?>
                                    </div>
                                    <div class="small text-muted">
                                        <?php echo planner_e(planner_display_date($wl['check_in'])); ?> →
                                        <?php echo planner_e(planner_display_date($wl['check_out'])); ?>
                                        • <?php echo (int)$wl['totalrooms']; ?> room(s)
                                        • <?php echo (int)$wl['adults']; ?> adult(s)
                                        <?php if ((int)$wl['kids'] > 0): ?> • <?php echo (int)$wl['kids']; ?> child(ren)<?php endif; ?>
                                    </div>
                                </div>
                                <div class="d-flex align-items-start gap-2">
                                    <a class="btn btn-primary btn-sm"
                                       href="/rooms/modules/reservations/reservation_form.php?waitlist_id=<?php echo (int)$wl['id']; ?>">
                                        Confirm Now
                                    </a>
                                    <a class="btn btn-outline-secondary btn-sm"
                                       href="/rooms/modules/reservations/waitlist.php">
                                        Open Waitlist
                                    </a>
                                </div>
                            </div>
                        </div>
                    <?php endforeach; ?>
                </div>
            </div>
        </div>
    </div>
</div>
<?php endif; ?>

<style>
.timeline-hero { background: linear-gradient(135deg, #ffffff 0%, #f7faff 100%); border-radius: 24px; }
.timeline-stat { display:flex; align-items:center; gap:10px; padding:10px 12px; border:1px solid #eef2f7; border-radius:14px; background:#fff; height:100%; }
.timeline-stat-icon { width:36px; height:36px; border-radius:12px; display:inline-flex; align-items:center; justify-content:center; font-size:15px; }
.timeline-stat-value { font-size:1.05rem; font-weight:800; line-height:1.1; }
.timeline-stat-label { color:#6c757d; font-size:.76rem; line-height:1.1; }
.availability-card { border:1px solid #e9eef5; border-radius:14px; background:#fff; padding:10px 12px; box-shadow:0 4px 14px rgba(15,23,42,.035); font-size:.86rem; }
.timeline-unassigned { display:flex; flex-wrap:wrap; gap:8px; }
.timeline-unassigned-card { width:280px; max-width:100%; padding:10px 12px; }
.booking-bar-static {
    border-radius: 18px;
    cursor: grab;
    border: 1px solid #e5e7eb;
    background: #ffffff;
    color: #111827;
    box-shadow: 0 8px 24px rgba(15, 23, 42, .08);
}
.unassigned-card {
    background: linear-gradient(135deg, #fff7ed 0%, #fffbeb 100%);
    border: 1px dashed #f59e0b;
    color: #111827;
}
.unassigned-card .text-muted,
.unassigned-card .small.text-muted {
    color: #6b7280 !important;
}
.unassigned-card .fw-bold {
    color: #111827 !important;
}
.holding-drop-card { border-radius:24px; }
.holding-drop-zone { min-height:70px; border:2px dashed #f59e0b; border-radius:16px; background:linear-gradient(135deg,#fffbeb 0%,#ffffff 100%); padding:10px 12px; transition:.15s ease; }
.holding-drop-card.drag-over .holding-drop-zone, .holding-drop-zone.drag-over { background:#fff7ed; box-shadow:inset 0 0 0 3px rgba(245,158,11,.18); }
.holding-drop-help { font-weight:700; color:#92400e; font-size:.84rem; }
.holding-empty { color:#94a3b8; font-weight:700; background:#fff; border:1px solid #fde68a; border-radius:12px; padding:8px 10px; font-size:.84rem; }
.timeline-wrap { overflow:auto; border-radius:0 0 18px 18px; max-height: calc(100vh - 210px); }
.timeline-table { background:#fff; }
.timeline-head, .timeline-row { display:flex; }
.timeline-head { position:sticky; top:0; z-index:5; background:#fff; }
.timeline-room-head {
    width:160px;
    min-width:160px;
    padding:8px 10px;
    font-weight:800;
    border-right:1px solid #e9eef5;
    border-bottom:1px solid #e9eef5;
    background:#f8fbff;
}
.timeline-days-head { display:flex; border-bottom:1px solid #e9eef5; }
.timeline-day-head { flex:0 0 auto; border-right:1px solid #edf2f7; padding:5px 4px; text-align:center; background:#f8fbff; }
.timeline-day-head.is-today { background:#eef5ff; }
.day-name { font-size:.60rem; color:#6b7280; text-transform:uppercase; letter-spacing:.05em; font-weight:700; }
.day-num { font-size:.80rem; font-weight:800; color:#111827; line-height:1.05; }
.day-mon { font-size:.58rem; color:#6b7280; }
.timeline-row { border-bottom:1px solid #edf2f7; }
.timeline-room-meta {
    width:160px;
    min-width:160px;
    padding:8px 10px;
    border-right:1px solid #edf2f7;
    background:#fff;
}
.room-title { font-weight:800; font-size:.84rem; color:#111827; line-height:1.1; }
.room-subtitle { font-size:.72rem; color:#6b7280; margin-top:2px; line-height:1.1; }
.room-status { margin-top:5px; display:inline-block; padding:3px 7px; background:#f8fafc; border:1px solid #e5e7eb; border-radius:999px; font-size:.62rem; color:#475569; font-weight:700; }
.room-feature-line { margin-top:4px; font-size:.58rem; color:#475569; font-weight:800; line-height:1.15; }
.timeline-grid-area { position:relative; background:#fff; }
.timeline-grid-lines { display:flex; position:absolute; inset:0; }
.timeline-cell { flex:0 0 auto; border-right:1px solid #f1f5f9; }
.timeline-cell.is-today { background:rgba(37,99,235,.05); }
.timeline-bars { position:relative; }
.timeline-empty { position:absolute; top:14px; left:10px; color:#94a3b8; font-size:.72rem; font-weight:600; }

.booking-bar {
    position:absolute;
    height:30px;
    border-radius:7px;
    color:#fff;
    display:flex;
    align-items:center;
    justify-content:space-between;
    padding:0 8px;
    gap:8px;
    cursor:grab;
    box-shadow:0 8px 24px rgba(15,23,42,.18);
    overflow:hidden;
    white-space:nowrap;
    z-index:2;
    box-sizing:border-box;
}
.booking-bar:hover { filter:brightness(1.03); }
.bar-main {
    display:flex;
    align-items:center;
    min-width:0;
    overflow:hidden;
    flex:1 1 auto;
}
.bar-guest {
    font-size:.72rem;
    font-weight:800;
    text-overflow:ellipsis;
    overflow:hidden;
}
.bar-open {
    color:#fff;
    margin-left:8px;
    font-size:.78rem;
    opacity:.95;
    flex:0 0 auto;
}
.bar-open:hover { color:#fff; opacity:1; }


.room-capacity-badge { margin-top:4px; display:inline-flex; align-items:center; padding:2px 6px; border-radius:999px; background:#fff7ed; border:1px solid #fed7aa; color:#9a3412; font-size:.58rem; font-weight:800; }
.booking-bar.occupancy-triple { box-shadow:0 10px 28px rgba(245,158,11,.33), 0 8px 24px rgba(15,23,42,.16); outline:2px solid rgba(253,186,116,.95); outline-offset:0; }
.booking-bar.occupancy-family { box-shadow:0 10px 28px rgba(14,165,233,.28), 0 8px 24px rgba(15,23,42,.16); outline:2px solid rgba(125,211,252,.85); outline-offset:0; }
.bar-occupancy-badge { margin-left:5px; display:inline-flex; align-items:center; gap:3px; padding:2px 5px; border-radius:999px; background:rgba(255,255,255,.9); color:#7c2d12; font-size:.55rem; font-weight:900; text-transform:uppercase; letter-spacing:.03em; flex:0 0 auto; }
.occupancy-family .bar-occupancy-badge { color:#075985; }
.booking-bar-static.occupancy-triple { border-color:#f59e0b; background:linear-gradient(135deg,#fff7ed 0%,#fffbeb 100%); }
.booking-bar-static.occupancy-family { border-color:#38bdf8; background:linear-gradient(135deg,#f0f9ff 0%,#ffffff 100%); }

.timeline-row.drag-over .timeline-grid-area { background: rgba(13, 110, 253, .05); box-shadow: inset 0 0 0 2px rgba(13, 110, 253, .18); }

@media (max-width: 991.98px) {
    .timeline-room-head, .timeline-room-meta {
        width:150px;
        min-width:150px;
    }
}

/* Compact planner UX adjustments */
.compact-top-card .page-eyebrow { font-size:.72rem; margin-bottom:.15rem !important; }
.compact-top-card .btn { padding:.38rem .68rem; border-radius:10px; font-size:.82rem; }
.compact-filter-card label { font-size:.76rem; margin-bottom:.25rem; }
.compact-filter-card .form-control,
.compact-filter-card .form-select { min-height:34px; padding:.32rem .6rem; font-size:.84rem; border-radius:10px; }
.compact-filter-card .btn { min-height:34px; padding:.32rem .55rem; font-size:.82rem; border-radius:10px; }
.compact-roomtype-card .card-header h5,
.compact-holding-card .card-header h5 { font-size:.98rem; }
.compact-roomtype-card .text-muted,
.compact-holding-card .text-muted { font-size:.78rem; }
.compact-roomtype-card .btn-sm,
.compact-holding-card .btn-sm { padding:.22rem .48rem; font-size:.74rem; }
.timeline-head { position:sticky; top:0; z-index:30; }
.timeline-room-head { position:sticky; left:0; z-index:32; }
.timeline-room-meta { position:sticky; left:0; z-index:20; }
.timeline-table { font-size:.86rem; }
.timeline-bars { overflow:hidden; }
@media (max-width: 991.98px) {
    .timeline-wrap { max-height: calc(100vh - 180px); }
}

</style>

<script>
document.addEventListener('DOMContentLoaded', function () {
    function attachDragSources() {
        document.querySelectorAll('.booking-bar, .booking-bar-static').forEach(function (bar) {
            bar.addEventListener('dragstart', function (e) {
                e.dataTransfer.setData('rooming_id', this.getAttribute('data-rooming-id') || '');
                e.dataTransfer.setData('order_id', this.getAttribute('data-order-id') || '');
                e.dataTransfer.setData('check_in', this.getAttribute('data-check-in') || '');
                e.dataTransfer.setData('check_out', this.getAttribute('data-check-out') || '');
            });
        });
    }

    function moveRooming(roomId, roomingId, orderId, checkIn, checkOut, holdingReason) {
        if (!roomingId || !orderId) return;

        const formData = new FormData();
        formData.append('room_id', roomId);
        formData.append('rooming_id', roomingId);
        formData.append('order_id', orderId);
        formData.append('check_in', checkIn || '');
        formData.append('check_out', checkOut || '');
        formData.append('holding_reason', holdingReason || '');

        fetch('move_booking.php', {
            method: 'POST',
            body: formData,
            credentials: 'same-origin'
        })
        .then(function (r) { return r.json(); })
        .then(function (json) {
            if (json && json.ok) window.location.reload();
            else alert((json && json.message) ? json.message : 'Could not move rooming.');
        })
        .catch(function () { alert('Could not move rooming right now.'); });
    }


    function parsePlannerDate(value) {
        if (!value) return null;
        const parts = String(value).substring(0, 10).split('-').map(function (n) { return parseInt(n, 10); });
        if (parts.length !== 3 || !parts[0] || !parts[1] || !parts[2]) return null;
        return new Date(parts[0], parts[1] - 1, parts[2]);
    }

    function plannerDaysBetween(a, b) {
        return Math.floor((b.getTime() - a.getTime()) / 86400000);
    }

    function fitPlannerRangeToScreen() {
        const wrap = document.getElementById('plannerTimelineWrap');
        if (!wrap) return;

        const mode = wrap.getAttribute('data-fit-mode') || 'scroll';
        const totalDays = parseInt(wrap.getAttribute('data-total-days') || '0', 10);
        const roomWidth = parseInt(wrap.getAttribute('data-room-label-width') || '160', 10);
        const defaultDayWidth = parseInt(wrap.getAttribute('data-default-day-width') || '70', 10);
        const table = wrap.querySelector('.timeline-table');
        const daysHead = wrap.querySelector('.timeline-days-head');
        const rangeStart = parsePlannerDate(wrap.getAttribute('data-range-from'));
        const rangeEnd = parsePlannerDate(wrap.getAttribute('data-range-to'));

        if (!table || !daysHead || !totalDays || !rangeStart || !rangeEnd) return;

        let dayWidth = defaultDayWidth;
        if (mode === 'fit') {
            const available = Math.max(0, wrap.clientWidth - roomWidth - 2);
            dayWidth = Math.max(defaultDayWidth, Math.floor(available / totalDays));
        }

        const gridWidth = dayWidth * totalDays;
        const fullWidth = roomWidth + gridWidth;

        wrap.style.setProperty('--planner-day-width', dayWidth + 'px');

        if (mode === 'fit') {
            table.style.minWidth = '100%';
            table.style.width = '100%';
            wrap.style.overflowX = 'hidden';
        } else {
            table.style.minWidth = fullWidth + 'px';
            table.style.width = fullWidth + 'px';
            wrap.style.overflowX = 'auto';
        }

        daysHead.style.setProperty('width', gridWidth + 'px', 'important');
        daysHead.style.setProperty('min-width', gridWidth + 'px', 'important');
        daysHead.style.setProperty('flex-basis', gridWidth + 'px', 'important');

        wrap.querySelectorAll('[data-planner-day-cell]').forEach(function (cell) {
            cell.style.setProperty('width', dayWidth + 'px', 'important');
            cell.style.setProperty('min-width', dayWidth + 'px', 'important');
            cell.style.setProperty('flex-basis', dayWidth + 'px', 'important');
        });

        wrap.querySelectorAll('.timeline-grid-area').forEach(function (area) {
            area.style.setProperty('width', gridWidth + 'px', 'important');
            area.style.setProperty('min-width', gridWidth + 'px', 'important');
            area.style.setProperty('flex-basis', gridWidth + 'px', 'important');
        });

        wrap.querySelectorAll('.booking-bar').forEach(function (bar) {
            const checkIn = parsePlannerDate(bar.getAttribute('data-check-in'));
            const checkOut = parsePlannerDate(bar.getAttribute('data-check-out'));
            if (!checkIn || !checkOut) return;

            const start = checkIn > rangeStart ? checkIn : rangeStart;
            const checkOutMinusOne = new Date(checkOut.getTime());
            checkOutMinusOne.setDate(checkOutMinusOne.getDate() - 1);
            const end = checkOutMinusOne < rangeEnd ? checkOutMinusOne : rangeEnd;

            if (end < rangeStart || start > rangeEnd || end < start) return;

            const offset = Math.max(0, plannerDaysBetween(rangeStart, start));
            const span = Math.max(1, plannerDaysBetween(start, end) + 1);

            bar.style.left = (offset * dayWidth) + 'px';
            bar.style.width = Math.max(dayWidth, span * dayWidth) + 'px';
        });
    }

    fitPlannerRangeToScreen();
    requestAnimationFrame(fitPlannerRangeToScreen);
    window.addEventListener('load', fitPlannerRangeToScreen);
    window.addEventListener('resize', fitPlannerRangeToScreen);
    setTimeout(fitPlannerRangeToScreen, 150);

    attachDragSources();

    document.querySelectorAll('[data-room-dropzone]').forEach(function (row) {
        row.addEventListener('dragover', function (e) { e.preventDefault(); this.classList.add('drag-over'); });
        row.addEventListener('dragleave', function () { this.classList.remove('drag-over'); });
        row.addEventListener('drop', function (e) {
            e.preventDefault();
            this.classList.remove('drag-over');
            moveRooming(
                this.getAttribute('data-room-id'),
                e.dataTransfer.getData('rooming_id'),
                e.dataTransfer.getData('order_id'),
                e.dataTransfer.getData('check_in'),
                e.dataTransfer.getData('check_out'),
                ''
            );
        });
    });

    document.querySelectorAll('[data-holding-dropzone]').forEach(function (zone) {
        zone.addEventListener('dragover', function (e) { e.preventDefault(); this.classList.add('drag-over'); });
        zone.addEventListener('dragleave', function () { this.classList.remove('drag-over'); });
        zone.addEventListener('drop', function (e) {
            e.preventDefault();
            this.classList.remove('drag-over');

            const reason = window.prompt('Reason for moving this booking to Holding Area?', 'Room rearrangement / group alignment');
            if (reason === null) return;

            moveRooming(
                0,
                e.dataTransfer.getData('rooming_id'),
                e.dataTransfer.getData('order_id'),
                e.dataTransfer.getData('check_in'),
                e.dataTransfer.getData('check_out'),
                reason
            );
        });
    });

    var waitlistModalEl = document.getElementById('waitlistAvailabilityModal');
    if (waitlistModalEl && window.bootstrap && typeof window.bootstrap.Modal === 'function') {
        var waitlistModal = new bootstrap.Modal(waitlistModalEl);
        waitlistModal.show();
    }
});
</script>

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