
function canonicalizeLegacyRoleUrl() {
  const params = new URLSearchParams(window.location.search);
  const role = params.get("role");
  if (!role || window.location.pathname !== "/index.html") return;
  const validRole = role === "superadmin" ? "admin" : role;
  if (!["guest", "staff", "admin"].includes(validRole)) return;
  const hotel = params.get("hotel") || "default";
  params.delete("role");
  params.delete("hotel");
  const query = params.toString();
  const nextUrl = `/hotel/${encodeURIComponent(hotel)}/${validRole}${query ? `?${query}` : ""}`;
  window.history.replaceState(null, "", nextUrl);
}

canonicalizeLegacyRoleUrl();

const services = [
  { id: "reception_services", department: "frontdesk", nameAr: "الاستقبال", nameEn: "Reception", descAr: "دخول، خروج، مفاتيح، معلومات وحجوزات", descEn: "Check-in, checkout, keys, info and bookings", icon: "message" },
  { id: "room_service", department: "food", nameAr: "خدمة الغرف", nameEn: "Room service", descAr: "وجبات ومشروبات ومستلزمات طعام", descEn: "Meals, drinks and dining items", icon: "cloche" },
  { id: "housekeeping", department: "housekeeping", nameAr: "التدبير المنزلي", nameEn: "Housekeeping", descAr: "تنظيف، شراشف، مناشف ومستلزمات", descEn: "Cleaning, linens, towels and amenities", icon: "sparkle" },
  { id: "maintenance", department: "maintenance", nameAr: "الصيانة", nameEn: "Maintenance", descAr: "تكييف، تلفاز، سباكة وإنترنت", descEn: "AC, TV, plumbing and internet", icon: "tool" },
  { id: "food_beverage", department: "food", nameAr: "المطاعم", nameEn: "Food & Beverage", descAr: "حجوزات وتجهيز مناسبات وطلبات خاصة", descEn: "Restaurant bookings, setups and special requests", icon: "table" },
  { id: "concierge", department: "concierge", nameAr: "الكونسيرج", nameEn: "Concierge", descAr: "تذاكر، رحلات، هدايا ومعلومات سياحية", descEn: "Tickets, tours, gifts and city help", icon: "calendar" },
  { id: "laundry", department: "laundry", nameAr: "الغسيل", nameEn: "Laundry", descAr: "غسيل، كي وتنظيف جاف", descEn: "Wash, ironing and dry clean", icon: "shirt" },
  { id: "spa_wellness", department: "wellness", nameAr: "السبا والنادي الصحي", nameEn: "Spa & Wellness", descAr: "مساج، ساونا، جاكوزي وعناية", descEn: "Massage, sauna, jacuzzi and treatments", icon: "sparkle" },
  { id: "gym", department: "gym", nameAr: "النادي الرياضي", nameEn: "Gym", descAr: "دخول، مدرب، معدات وحصص", descEn: "Access, trainer, equipment and classes", icon: "tool" },
  { id: "pool_chairs", department: "pool", nameAr: "المسبح", nameEn: "Pool", descAr: "مناشف، كابانا، كراسي وطعام بجانب المسبح", descEn: "Towels, cabana, chairs and poolside food", icon: "pool" },
  { id: "business_center", department: "business", nameAr: "مركز الأعمال", nameEn: "Business Center", descAr: "طباعة، مسح، فاكس وغرف اجتماعات", descEn: "Printing, scanning, fax and meeting rooms", icon: "calendar" },
  { id: "security", department: "security", nameAr: "الأمن", nameEn: "Security", descAr: "مفقودات، خزنة، إزعاج وطوارئ", descEn: "Lost items, safe, disturbance and emergencies", icon: "message" },
  { id: "transport", department: "transport", nameAr: "النقل", nameEn: "Transportation", descAr: "تاكسي، ليموزين، مطار وتأجير سيارة", descEn: "Taxi, limousine, airport and car rental", icon: "car" },
  { id: "kids_services", department: "kids", nameAr: "خدمات الأطفال", nameEn: "Kids services", descAr: "سرير، كرسي، نادي وأكل أطفال", descEn: "Crib, chair, kids club and kids meals", icon: "sparkle" },
  { id: "sports_activities", department: "sports", nameAr: "الملاعب والأنشطة الرياضية", nameEn: "Sports courts & activities", descAr: "ملاعب، معدات، مدربين وحصص", descEn: "Courts, equipment, trainers and classes", icon: "tool" },
  { id: "entertainment", department: "entertainment", nameAr: "الأنشطة الترفيهية", nameEn: "Entertainment activities", descAr: "فعاليات، عروض، رحلات وتأجير", descEn: "Events, shows, trips and rentals", icon: "calendar" },
  { id: "vip_services", department: "vip", nameAr: "خدمات كبار الشخصيات", nameEn: "VIP services", descAr: "يخت، سائق، استقبال خاص وخدمات شخصية", descEn: "Yacht, driver, private welcome and personal services", icon: "sparkle" },  { id: "events_services", department: "events", nameAr: "المناسبات", nameEn: "Occasions", descAr: "عيد ميلاد، شهر عسل، تزيين وهدايا", descEn: "Birthday, honeymoon, decorations and gifts", icon: "calendar" },
  { id: "medical_services", department: "medical", nameAr: "الخدمات الطبية", nameEn: "Medical services", descAr: "طبيب، ممرض، إسعاف وصيدلية", descEn: "Doctor, nurse, ambulance and pharmacy", icon: "message" },
  { id: "tech_services", department: "tech", nameAr: "الخدمات التقنية", nameEn: "Tech support", descAr: "واي فاي، تلفاز ذكي، شواحن ومحولات", descEn: "Wi-Fi, smart TV, chargers and adapters", icon: "tool" },
  { id: "extra_services", department: "extras", nameAr: "خدمات إضافية", nameEn: "Extra services", descAr: "أمتعة، بريد، VIP واحتياجات خاصة", descEn: "Luggage, courier, VIP and accessibility", icon: "message" }
];

const serviceOptions = {
  reception_services: [
    { titleAr: "إجراءات الإقامة", titleEn: "Stay procedures", items: [
      { id: "check_in", ar: "تسجيل الدخول", en: "Check-in", price: 0 },
      { id: "check_out", ar: "تسجيل المغادرة", en: "Check-out", price: 0 },
      { id: "extend_stay", ar: "تمديد الإقامة", en: "Extend stay", price: 0 },
      { id: "change_room_type", ar: "تغيير نوع الغرفة", en: "Change room type", price: 0 },
      { id: "change_room", ar: "تغيير الغرفة", en: "Change room", price: 0 },
      { id: "new_key", ar: "إصدار مفتاح جديد", en: "Issue new key", price: 0 },
      { id: "early_checkin", ar: "طلب تسجيل دخول مبكر", en: "Early check-in request", price: 120 },
      { id: "late_checkout", ar: "طلب مغادرة متأخرة", en: "Late checkout request", price: 150 },
      { id: "extra_room", ar: "حجز غرفة إضافية", en: "Book extra room", price: 0 }
    ]},
    { titleAr: "معلومات وخدمات", titleEn: "Information and services", items: [
      { id: "hotel_info", ar: "معلومات عن الفندق", en: "Hotel information", price: 0 },
      { id: "city_info", ar: "معلومات عن المدينة", en: "City information", price: 0 },
      { id: "taxi_booking", ar: "حجز سيارة أجرة", en: "Taxi booking", price: 0 },
      { id: "limousine_booking", ar: "حجز ليموزين", en: "Limousine booking", price: 180 },
      { id: "private_car_call", ar: "استدعاء سيارة خاصة", en: "Call private car", price: 120 },
      { id: "tour_booking", ar: "حجز جولات سياحية", en: "Book sightseeing tours", price: 0 },
      { id: "call_forwarding", ar: "تحويل المكالمات", en: "Call forwarding", price: 0 },
      { id: "wake_up", ar: "خدمة الإيقاظ", en: "Wake-up call", price: 0 },
      { id: "luggage_storage", ar: "حفظ الأمتعة", en: "Luggage storage", price: 0 },
      { id: "mail_parcels", ar: "استلام وتسليم البريد والطرود", en: "Mail and parcel handling", price: 0 },
      { id: "print_copy", ar: "طباعة أو تصوير المستندات", en: "Print or copy documents", price: 5 },
      { id: "currency_exchange", ar: "صرف العملات", en: "Currency exchange", price: 0 },
      { id: "flight_help", ar: "المساعدة في الرحلات الجوية", en: "Flight assistance", price: 0 }
    ]}
  ],
  room_service: [
    { titleAr: "وجبات", titleEn: "Meals", items: [
      { id: "breakfast_order", ar: "طلب الإفطار", en: "Order breakfast", price: 55 },
      { id: "lunch_order", ar: "طلب الغداء", en: "Order lunch", price: 75 },
      { id: "dinner_order", ar: "طلب العشاء", en: "Order dinner", price: 85 },
      { id: "kids_meal", ar: "طلب وجبات للأطفال", en: "Kids meals", price: 35 },
      { id: "special_meal", ar: "وجبات خاصة: دايت، نباتي، خال من الجلوتين", en: "Special meal: diet, vegan, gluten-free", price: 65 }
    ]},
    { titleAr: "مشروبات وحلويات", titleEn: "Drinks and extras", items: [
      { id: "drinks", ar: "طلب المشروبات", en: "Order drinks", price: 18 },
      { id: "coffee_tea", ar: "طلب القهوة والشاي", en: "Coffee and tea", price: 18 },
      { id: "desserts", ar: "طلب الحلويات", en: "Desserts", price: 32 },
      { id: "ice", ar: "طلب ثلج", en: "Ice bucket", price: 0 },
      { id: "extra_cutlery", ar: "أدوات مائدة إضافية", en: "Extra cutlery", price: 0 }
    ]}
  ],
  housekeeping: [
    { titleAr: "تنظيف وترتيب", titleEn: "Cleaning", items: [
      { id: "room_cleaning", ar: "تنظيف الغرفة", en: "Room cleaning", price: 0 },
      { id: "extra_cleaning", ar: "تنظيف إضافي", en: "Extra cleaning", price: 0 },
      { id: "urgent_cleaning", ar: "تنظيف عاجل", en: "Urgent cleaning", price: 0 },
      { id: "turndown", ar: "ترتيب السرير مساء", en: "Turndown service", price: 0 },
      { id: "trash_collection", ar: "جمع القمامة", en: "Trash collection", price: 0 },
      { id: "room_sanitizing", ar: "تعقيم الغرفة", en: "Room sanitizing", price: 0 }
    ]},
    { titleAr: "مستلزمات الغرفة", titleEn: "Room items", items: [
      { id: "change_sheets", ar: "تغيير الشراشف", en: "Change sheets", price: 0 },
      { id: "change_towels", ar: "تغيير المناشف", en: "Change towels", price: 0 },
      { id: "extra_towels", ar: "توفير مناشف إضافية", en: "Extra towels", price: 0 },
      { id: "extra_pillows", ar: "توفير وسائد إضافية", en: "Extra pillows", price: 0 },
      { id: "blankets", ar: "توفير بطانيات", en: "Blankets", price: 0 },
      { id: "baby_crib", ar: "توفير سرير أطفال", en: "Baby crib", price: 0 },
      { id: "extra_bed", ar: "توفير سرير إضافي", en: "Extra bed", price: 100 },
      { id: "bath_amenities", ar: "تعبئة مستلزمات الحمام", en: "Refill bathroom amenities", price: 0 },
      { id: "bathrobe", ar: "توفير روب استحمام", en: "Bathrobe", price: 0 },
      { id: "slippers", ar: "توفير شباشب", en: "Slippers", price: 0 },
      { id: "hangers", ar: "توفير شماعات", en: "Hangers", price: 0 },
      { id: "iron_board", ar: "توفير مكواة وطاولة كي", en: "Iron and ironing board", price: 0 },
      { id: "hair_dryer", ar: "مجفف شعر", en: "Hair dryer", price: 0 }
    ]}
  ],
  maintenance: [
    { titleAr: "أعطال الغرفة", titleEn: "Room issues", items: [
      { id: "fix_ac", ar: "إصلاح التكييف", en: "Fix AC", price: 0 },
      { id: "fix_tv", ar: "إصلاح التلفاز", en: "Fix TV", price: 0 },
      { id: "fix_fridge", ar: "إصلاح الثلاجة", en: "Fix fridge", price: 0 },
      { id: "fix_safe", ar: "إصلاح الخزنة", en: "Fix safe", price: 0 },
      { id: "fix_phone", ar: "إصلاح الهاتف", en: "Fix phone", price: 0 },
      { id: "fix_lighting", ar: "إصلاح الإضاءة", en: "Fix lighting", price: 0 },
      { id: "fix_plumbing", ar: "إصلاح السباكة", en: "Fix plumbing", price: 0 },
      { id: "fix_internet", ar: "إصلاح الإنترنت", en: "Fix internet", price: 0 },
      { id: "fix_locks", ar: "إصلاح الأقفال", en: "Fix locks", price: 0 },
      { id: "adjust_temperature", ar: "ضبط درجة حرارة الغرفة", en: "Adjust room temperature", price: 0 }
    ]}
  ],
  food_beverage: [
    { titleAr: "مطاعم ومناسبات", titleEn: "Restaurants and setups", items: [
      { id: "restaurant_booking", ar: "حجز مطعم", en: "Restaurant reservation", price: 0 },
      { id: "menu_request", ar: "طلب قائمة الطعام", en: "Request menu", price: 0 },
      { id: "event_booking", ar: "حجز مناسبة", en: "Event booking", price: 0 },
      { id: "birthday_setup", ar: "تجهيز عيد ميلاد", en: "Birthday setup", price: 250 },
      { id: "honeymoon_setup", ar: "تجهيز شهر عسل", en: "Honeymoon setup", price: 350 },
      { id: "romantic_dinner", ar: "تجهيز عشاء رومانسي", en: "Romantic dinner setup", price: 450 },
      { id: "cake_order", ar: "طلب كيك", en: "Cake order", price: 120 },
      { id: "buffet_order", ar: "طلب بوفيه", en: "Buffet request", price: 0 },
      { id: "allergy_food", ar: "مأكولات خاصة للحساسية", en: "Allergy-friendly food", price: 0 }
    ]}
  ],
  concierge: [
    { titleAr: "حجوزات ورحلات", titleEn: "Bookings and tours", items: [
      { id: "external_restaurants", ar: "حجز مطاعم خارج الفندق", en: "Book restaurants outside hotel", price: 0 },
      { id: "tickets", ar: "حجز تذاكر", en: "Book tickets", price: 0 },
      { id: "events", ar: "حجز فعاليات", en: "Book events", price: 0 },
      { id: "trips", ar: "تنظيم رحلات", en: "Organize trips", price: 0 },
      { id: "museum", ar: "حجز متحف", en: "Museum booking", price: 0 },
      { id: "safari", ar: "حجز سفاري", en: "Safari booking", price: 0 },
      { id: "rent_car", ar: "تأجير سيارة", en: "Rent a car", price: 0 },
      { id: "airport_drop", ar: "توصيل للمطار", en: "Airport drop-off", price: 180 },
      { id: "airport_pickup", ar: "استقبال من المطار", en: "Airport pickup", price: 180 },
      { id: "tourist_info", ar: "معلومات سياحية", en: "Tourist information", price: 0 },
      { id: "places", ar: "اقتراح أماكن للزيارة", en: "Places to visit", price: 0 }
    ]},
    { titleAr: "طلبات خاصة", titleEn: "Special requests", items: [
      { id: "flowers", ar: "إرسال زهور", en: "Send flowers", price: 150 },
      { id: "gifts", ar: "شراء هدايا نيابة عن النزيل", en: "Buy gifts for guest", price: 0 }
    ]}
  ],
  laundry: [
    { titleAr: "خدمات الملابس", titleEn: "Clothing services", items: [
      { id: "wash", ar: "غسيل الملابس", en: "Laundry wash", price: 20 },
      { id: "iron", ar: "كي الملابس", en: "Ironing", price: 15 },
      { id: "dry_clean", ar: "تنظيف جاف", en: "Dry cleaning", price: 35 },
      { id: "express", ar: "خدمة عاجلة", en: "Express service", price: 25 },
      { id: "minor_repair", ar: "إصلاح بسيط للملابس", en: "Minor clothing repair", price: 20 }
    ]},
    { titleAr: "عدد قطع الغسيل", titleEn: "Laundry pieces", items: [
      { id: "piece_tshirt", ar: "تيشيرت", en: "T-shirt", price: 12 },
      { id: "piece_shirt", ar: "قميص", en: "Shirt", price: 15 },
      { id: "piece_pants", ar: "بنطلون", en: "Pants", price: 18 },
      { id: "piece_jacket", ar: "جاكيت", en: "Jacket", price: 30 },
      { id: "piece_dress", ar: "فستان", en: "Dress", price: 35 },
      { id: "piece_suit", ar: "بدلة", en: "Suit", price: 45 },
      { id: "piece_socks", ar: "جوارب", en: "Socks", price: 8 },
      { id: "piece_underwear", ar: "ملابس داخلية", en: "Underwear", price: 8 }
    ]}
  ],
  spa_wellness: [
    { titleAr: "سبا وعناية", titleEn: "Spa and care", items: [
      { id: "massage", ar: "حجز مساج", en: "Massage booking", price: 250 },
      { id: "spa_treatment", ar: "حجز علاج سبا", en: "Spa treatment", price: 300 },
      { id: "sauna", ar: "حجز ساونا", en: "Sauna booking", price: 90 },
      { id: "steam_room", ar: "حجز غرفة بخار", en: "Steam room", price: 90 },
      { id: "jacuzzi", ar: "حجز جاكوزي", en: "Jacuzzi booking", price: 120 },
      { id: "beauty", ar: "جلسات تجميل", en: "Beauty sessions", price: 180 },
      { id: "skin_care", ar: "خدمات العناية بالبشرة", en: "Skin care", price: 220 },
      { id: "physio", ar: "جلسات علاج طبيعي", en: "Physiotherapy sessions", price: 250 }
    ]}
  ],
  gym: [
    { titleAr: "النادي الرياضي", titleEn: "Gym", items: [
      { id: "gym_access", ar: "دخول النادي", en: "Gym access", price: 0 },
      { id: "personal_trainer", ar: "حجز مدرب شخصي", en: "Personal trainer", price: 180 },
      { id: "equipment", ar: "طلب معدات", en: "Request equipment", price: 0 },
      { id: "fitness_class", ar: "حجز حصص رياضية", en: "Fitness class booking", price: 60 },
      { id: "gym_hours", ar: "استفسار عن أوقات العمل", en: "Opening hours inquiry", price: 0 }
    ]}
  ],
  pool_chairs: [
    { titleAr: "خدمات المسبح", titleEn: "Pool services", items: [
      { id: "pool_towels", ar: "مناشف مسبح", en: "Pool towels", price: 0 },
      { id: "cabana", ar: "حجز كابانا", en: "Cabana booking", price: 180 },
      { id: "pool_food", ar: "خدمة الطعام بجانب المسبح", en: "Poolside food service", price: 0 },
      { id: "kids_swim_gear", ar: "معدات سباحة للأطفال", en: "Kids swimming gear", price: 0 },
      { id: "life_jackets", ar: "سترات نجاة", en: "Life jackets", price: 0 }
    ]},
    { titleAr: "أكل ومشروبات المسبح", titleEn: "Pool food and drinks", items: [
      { id: "pool_club", ar: "كلوب ساندويتش", en: "Club sandwich", price: 42 },
      { id: "pool_fries", ar: "بطاطا مقلية", en: "French fries", price: 24 },
      { id: "fruit_platter", ar: "طبق فواكه", en: "Fruit platter", price: 38 },
      { id: "lemon_mint", ar: "ليمون نعناع", en: "Lemon mint", price: 24 },
      { id: "smoothie", ar: "سموذي", en: "Smoothie", price: 28 }
    ]}
  ],
  business_center: [
    { titleAr: "مركز الأعمال", titleEn: "Business Center", items: [
      { id: "computer_use", ar: "استخدام الكمبيوتر", en: "Computer use", price: 0 },
      { id: "internet", ar: "الإنترنت", en: "Internet", price: 0 },
      { id: "printing", ar: "الطباعة", en: "Printing", price: 5 },
      { id: "scanning", ar: "المسح الضوئي", en: "Scanning", price: 5 },
      { id: "fax", ar: "الفاكس", en: "Fax", price: 10 },
      { id: "photocopy", ar: "تصوير المستندات", en: "Photocopy", price: 5 },
      { id: "meeting_room", ar: "حجز غرفة اجتماعات", en: "Meeting room booking", price: 350 }
    ]}
  ],
  security: [
    { titleAr: "الأمن والطوارئ", titleEn: "Security and safety", items: [
      { id: "open_safe", ar: "فتح الخزنة", en: "Open safe", price: 0 },
      { id: "lost_report", ar: "الإبلاغ عن مفقودات", en: "Report lost items", price: 0 },
      { id: "found_items", ar: "العثور على أغراض", en: "Found items", price: 0 },
      { id: "security_escort", ar: "طلب مرافقة أمنية", en: "Security escort", price: 0 },
      { id: "noise_report", ar: "الإبلاغ عن إزعاج", en: "Report disturbance", price: 0 },
      { id: "medical_emergency", ar: "الإبلاغ عن حالة طبية طارئة", en: "Medical emergency report", price: 0 }
    ]}
  ],
  transport: [
    { titleAr: "النقل", titleEn: "Transportation", items: [
      { id: "taxi", ar: "تاكسي", en: "Taxi", price: 0 },
      { id: "careem_uber", ar: "أوبر أو كريم", en: "Uber or Careem", price: 0 },
      { id: "limousine", ar: "ليموزين", en: "Limousine", price: 180 },
      { id: "hotel_bus", ar: "حافلة الفندق", en: "Hotel shuttle", price: 0 },
      { id: "airport_transport", ar: "النقل من وإلى المطار", en: "Airport transfer", price: 180 },
      { id: "car_rental", ar: "تأجير سيارة", en: "Car rental", price: 0 },
      { id: "ev_charging", ar: "شحن سيارة كهربائية", en: "EV charging", price: 40 }
    ]}
  ],
  kids_services: [
    { titleAr: "خدمات الأطفال", titleEn: "Kids services", items: [
      { id: "kids_crib", ar: "سرير أطفال", en: "Baby crib", price: 0 },
      { id: "kids_chair", ar: "كرسي أطفال", en: "High chair", price: 0 },
      { id: "babysitter", ar: "جليسة أطفال", en: "Babysitter", price: 120 },
      { id: "kids_club", ar: "نادي الأطفال", en: "Kids club", price: 0 },
      { id: "kids_toys", ar: "ألعاب للأطفال", en: "Kids toys", price: 0 },
      { id: "kids_menu", ar: "قائمة طعام للأطفال", en: "Kids menu", price: 0 }
    ]}
  ],
  sports_activities: [
    { titleAr: "حجز الملاعب", titleEn: "Court bookings", items: [
      { id: "tennis_court", ar: "حجز ملعب تنس", en: "Book tennis court", price: 120 },
      { id: "padel_court", ar: "حجز ملعب بادل", en: "Book padel court", price: 160 },
      { id: "football_court", ar: "حجز ملعب كرة قدم", en: "Book football field", price: 250 },
      { id: "basketball_court", ar: "حجز ملعب كرة سلة", en: "Book basketball court", price: 120 },
      { id: "squash_court", ar: "حجز ملعب اسكواش", en: "Book squash court", price: 100 },
      { id: "golf_course", ar: "حجز ملعب جولف", en: "Book golf course", price: 350 },
      { id: "mini_golf", ar: "حجز ملعب ميني جولف", en: "Book mini golf", price: 70 },
      { id: "beach_volleyball", ar: "حجز ملعب كرة طائرة شاطئية", en: "Book beach volleyball court", price: 90 }
    ]},
    { titleAr: "مدربين وحصص", titleEn: "Trainers and classes", items: [
      { id: "sports_equipment", ar: "استئجار معدات رياضية", en: "Rent sports equipment", price: 40 },
      { id: "tennis_coach", ar: "حجز مدرب تنس", en: "Book tennis coach", price: 180 },
      { id: "swim_coach", ar: "حجز مدرب سباحة", en: "Book swimming coach", price: 160 },
      { id: "personal_fitness", ar: "حجز مدرب لياقة شخصية", en: "Book personal fitness trainer", price: 180 },
      { id: "yoga_class", ar: "حجز حصص يوغا", en: "Book yoga classes", price: 80 },
      { id: "pilates_class", ar: "حجز حصص بيلاتس", en: "Book pilates classes", price: 90 },
      { id: "aqua_aerobics", ar: "حجز حصص أكوا إيروبيك", en: "Book aqua aerobics", price: 70 }
    ]},
    { titleAr: "استفسارات وتنظيم", titleEn: "Info and events", items: [
      { id: "court_hours", ar: "معرفة أوقات عمل الملاعب", en: "Court opening hours", price: 0 },
      { id: "sports_fees", ar: "الاستفسار عن الرسوم", en: "Ask about fees", price: 0 },
      { id: "friendly_match", ar: "حجز بطولة أو مباراة ودية", en: "Book tournament or friendly match", price: 0 }
    ]}
  ],
  entertainment: [
    { titleAr: "فعاليات وعروض", titleEn: "Events and shows", items: [
      { id: "daily_events", ar: "معرفة الفعاليات اليومية", en: "Daily events schedule", price: 0 },
      { id: "show_tickets", ar: "حجز تذاكر العروض", en: "Book show tickets", price: 0 },
      { id: "live_music", ar: "العروض الموسيقية الحية", en: "Live music shows", price: 0 },
      { id: "kids_shows", ar: "عروض الأطفال", en: "Kids shows", price: 0 },
      { id: "outdoor_cinema", ar: "السينما الخارجية", en: "Outdoor cinema", price: 0 },
      { id: "bbq_nights", ar: "ليالي الشواء", en: "BBQ nights", price: 0 },
      { id: "international_food_nights", ar: "ليالي المأكولات العالمية", en: "International food nights", price: 0 },
      { id: "cultural_shows", ar: "عروض ثقافية", en: "Cultural shows", price: 0 }
    ]},
    { titleAr: "مغامرات وتأجير", titleEn: "Adventures and rentals", items: [
      { id: "water_games", ar: "ألعاب مائية", en: "Water games", price: 0 },
      { id: "boat_trips", ar: "رحلات بحرية", en: "Boat trips", price: 0 },
      { id: "fishing", ar: "صيد الأسماك", en: "Fishing", price: 0 },
      { id: "diving", ar: "الغوص", en: "Diving", price: 0 },
      { id: "snorkeling", ar: "السنوركلينج", en: "Snorkeling", price: 0 },
      { id: "bike_rental", ar: "تأجير دراجات", en: "Bike rental", price: 40 },
      { id: "e_scooter", ar: "تأجير سكوتر كهربائي", en: "Electric scooter rental", price: 60 },
      { id: "safari_trips", ar: "رحلات سفاري", en: "Safari trips", price: 0 },
      { id: "mountain_trips", ar: "رحلات جبلية", en: "Mountain trips", price: 0 },
      { id: "city_tours", ar: "جولات سياحية", en: "Sightseeing tours", price: 0 }
    ]}
  ],
  vip_services: [
    { titleAr: "تجارب VIP", titleEn: "VIP experiences", items: [
      { id: "proposal_setup", ar: "تنظيم عرض زواج", en: "Marriage proposal setup", price: 1200 },
      { id: "vip_honeymoon", ar: "تجهيز شهر العسل", en: "Honeymoon setup", price: 350 },
      { id: "private_airport_welcome", ar: "استقبال خاص في المطار", en: "Private airport welcome", price: 350 },
      { id: "car_with_driver", ar: "سيارة مع سائق", en: "Car with driver", price: 450 },
      { id: "helicopter", ar: "طائرة هليكوبتر", en: "Helicopter", price: 0 },
      { id: "private_yacht", ar: "يخت خاص", en: "Private yacht", price: 0 },
      { id: "private_jet", ar: "حجز طائرة خاصة", en: "Private jet booking", price: 0 },
      { id: "bodyguard", ar: "حارس شخصي", en: "Bodyguard", price: 0 },
      { id: "personal_assistant", ar: "مساعد شخصي", en: "Personal assistant", price: 0 },
      { id: "personal_shopping", ar: "خدمة تسوق شخصية", en: "Personal shopping", price: 0 }
    ]}
  ],  events_services: [
    { titleAr: "حجز قاعات وحفلات", titleEn: "Halls and parties", items: [
      { id: "wedding_hall", ar: "حجز قاعة زفاف", en: "Wedding hall booking", price: 0 },
      { id: "engagement_hall", ar: "حجز قاعة خطوبة", en: "Engagement hall booking", price: 0 },
      { id: "birthday_party", ar: "حجز حفلة عيد ميلاد", en: "Birthday party booking", price: 250 },
      { id: "graduation_party", ar: "حجز حفلة تخرج", en: "Graduation party booking", price: 0 },
      { id: "kids_party", ar: "حجز حفلة أطفال", en: "Kids party booking", price: 0 },
      { id: "corporate_party", ar: "حجز حفلة شركة", en: "Corporate party booking", price: 0 },
      { id: "conference", ar: "حجز مؤتمر", en: "Conference booking", price: 0 },
      { id: "meeting", ar: "حجز اجتماع", en: "Meeting booking", price: 350 },
      { id: "seminar", ar: "حجز ندوة", en: "Seminar booking", price: 0 },
      { id: "workshop", ar: "حجز ورشة عمل", en: "Workshop booking", price: 0 },
      { id: "exhibition", ar: "حجز معرض", en: "Exhibition booking", price: 0 },
      { id: "group_breakfast", ar: "حجز إفطار جماعي", en: "Group breakfast", price: 0 },
      { id: "business_lunch", ar: "حجز غداء عمل", en: "Business lunch", price: 0 },
      { id: "private_dinner", ar: "حجز عشاء خاص", en: "Private dinner", price: 0 }
    ]},
    { titleAr: "تجهيزات القاعة", titleEn: "Hall setup", items: [
      { id: "hall_layout", ar: "طلب تنسيق القاعة", en: "Hall layout setup", price: 0 },
      { id: "sound_lighting", ar: "طلب نظام صوت وإضاءة", en: "Sound and lighting system", price: 250 },
      { id: "screen_projector", ar: "طلب شاشة عرض وبروجكتور", en: "Screen and projector", price: 150 },
      { id: "stage_podium", ar: "طلب منصة وخطابة", en: "Stage and podium", price: 300 },
      { id: "dj_band", ar: "طلب دي جي أو فرقة موسيقية", en: "DJ or live band", price: 0 },
      { id: "event_coordinator", ar: "طلب منسق فعاليات", en: "Event coordinator", price: 0 }
    ]},
    { titleAr: "تصوير وديكور", titleEn: "Media and decor", items: [
      { id: "photographer", ar: "طلب مصور فوتوغرافي", en: "Photographer", price: 0 },
      { id: "videographer", ar: "طلب مصور فيديو", en: "Videographer", price: 0 },
      { id: "decor", ar: "طلب ديكور", en: "Decor", price: 0 },
      { id: "flowers", ar: "طلب زهور", en: "Flowers", price: 150 },
      { id: "balloons", ar: "طلب بالونات", en: "Balloons", price: 90 },
      { id: "custom_cake", ar: "طلب كيك مخصص", en: "Custom cake", price: 150 }
    ]},
    { titleAr: "ضيافة وهدايا", titleEn: "Catering and gifts", items: [
      { id: "buffet", ar: "طلب بوفيه", en: "Buffet", price: 0 },
      { id: "hospitality_coffee", ar: "طلب ضيافة وقهوة", en: "Hospitality and coffee", price: 0 },
      { id: "guest_gifts", ar: "طلب هدايا للضيوف", en: "Guest gifts", price: 0 },
      { id: "honeymoon", ar: "تجهيز شهر العسل", en: "Honeymoon setup", price: 350 },
      { id: "anniversary", ar: "ذكرى زواج", en: "Anniversary", price: 300 },
      { id: "room_decoration", ar: "تزيين الغرفة", en: "Room decoration", price: 180 },
      { id: "chocolate", ar: "شوكولاتة", en: "Chocolate", price: 80 }
    ]}
  ],  medical_services: [
    { titleAr: "الخدمات الطبية", titleEn: "Medical services", items: [
      { id: "doctor", ar: "طبيب عند الطلب", en: "Doctor on call", price: 0 },
      { id: "nurse", ar: "ممرض", en: "Nurse", price: 0 },
      { id: "ambulance", ar: "سيارة إسعاف", en: "Ambulance", price: 0 },
      { id: "first_aid", ar: "إسعافات أولية", en: "First aid", price: 0 },
      { id: "pharmacy", ar: "صيدلية", en: "Pharmacy", price: 0 },
      { id: "pressure_sugar", ar: "قياس ضغط وسكر", en: "Blood pressure and sugar check", price: 0 }
    ]}
  ],
  tech_services: [
    { titleAr: "الخدمات التقنية", titleEn: "Tech services", items: [
      { id: "wifi", ar: "واي فاي", en: "Wi-Fi", price: 0 },
      { id: "wifi_password", ar: "كلمة مرور الإنترنت", en: "Internet password", price: 0 },
      { id: "smart_tv", ar: "دعم التلفاز الذكي", en: "Smart TV support", price: 0 },
      { id: "hdmi", ar: "توصيل HDMI", en: "HDMI connection", price: 0 },
      { id: "phone_charger", ar: "شاحن هاتف", en: "Phone charger", price: 0 },
      { id: "adapters", ar: "محولات كهربائية", en: "Adapters", price: 0 },
      { id: "headphones", ar: "سماعات", en: "Headphones", price: 0 },
      { id: "batteries", ar: "بطاريات", en: "Batteries", price: 0 }
    ]}
  ],
  extra_services: [
    { titleAr: "خدمات إضافية", titleEn: "Extra services", items: [
      { id: "store_luggage", ar: "تخزين الأمتعة", en: "Luggage storage", price: 0 },
      { id: "ship_luggage", ar: "شحن الأمتعة", en: "Luggage shipping", price: 0 },
      { id: "courier", ar: "البريد السريع", en: "Courier", price: 0 },
      { id: "buy_supplies", ar: "شراء مستلزمات", en: "Buy supplies", price: 0 },
      { id: "money_transfer", ar: "تحويل أموال", en: "Money transfer", price: 0 },
      { id: "atm", ar: "ماكينة صراف", en: "ATM", price: 0 },
      { id: "vip", ar: "خدمات كبار الشخصيات", en: "VIP services", price: 0 },
      { id: "accessibility", ar: "خدمات ذوي الإعاقة", en: "Accessibility services", price: 0 },
      { id: "connected_rooms", ar: "غرف متصلة", en: "Connected rooms", price: 0 },
      { id: "non_smoking", ar: "غرف لغير المدخنين", en: "Non-smoking rooms", price: 0 },
      { id: "medical_pillow", ar: "طلب وسادة طبية", en: "Medical pillow", price: 0 },
      { id: "fan_heater", ar: "طلب مروحة أو مدفأة", en: "Fan or heater", price: 0 }
    ]}
  ]
};

const defaultDepartments = [
  { id: "all", ar: "الكل", en: "All" },
  { id: "frontdesk", ar: "الاستقبال", en: "Front desk" },
  { id: "food", ar: "خدمة الغرف / المطاعم", en: "Room service / Food" },
  { id: "housekeeping", ar: "التدبير", en: "Housekeeping" },
  { id: "maintenance", ar: "الصيانة", en: "Maintenance" },
  { id: "concierge", ar: "الكونسيرج", en: "Concierge" },
  { id: "laundry", ar: "الغسيل", en: "Laundry" },
  { id: "wellness", ar: "السبا", en: "Spa" },
  { id: "gym", ar: "النادي", en: "Gym" },
  { id: "pool", ar: "المسبح", en: "Pool" },
  { id: "business", ar: "الأعمال", en: "Business" },
  { id: "security", ar: "الأمن", en: "Security" },
  { id: "transport", ar: "النقل", en: "Transport" },
  { id: "kids", ar: "الأطفال", en: "Kids" },
  { id: "sports", ar: "الرياضة", en: "Sports" },
  { id: "entertainment", ar: "الترفيه", en: "Entertainment" },
  { id: "events", ar: "المناسبات", en: "Occasions" },
  { id: "vip", ar: "VIP", en: "VIP" },
  { id: "medical", ar: "الطبي", en: "Medical" },
  { id: "tech", ar: "التقني", en: "Tech" },
  { id: "extras", ar: "إضافي", en: "Extras" }
];


function ensureCoreDepartments() {
  const foodDepartment = departments.find((department) => department.id === "food");
  if (foodDepartment) {
    foodDepartment.ar = "خدمة الغرف / المطاعم";
    foodDepartment.en = "Room service / Food";
  }
}
function ensureLaundryPieces() {
  if (!Array.isArray(serviceOptions.laundry)) serviceOptions.laundry = [];
  let group = serviceOptions.laundry.find((item) => item.items?.some((piece) => piece.id === "piece_tshirt"));
  if (!group) {
    group = { titleAr: "عدد قطع الغسيل", titleEn: "Laundry pieces", items: [] };
    serviceOptions.laundry.push(group);
  }
  const pieces = [
    { id: "piece_tshirt", ar: "تيشيرت", en: "T-shirt", price: 12 },
    { id: "piece_shirt", ar: "قميص", en: "Shirt", price: 15 },
    { id: "piece_pants", ar: "بنطلون", en: "Pants", price: 18 },
    { id: "piece_jacket", ar: "جاكيت", en: "Jacket", price: 30 },
    { id: "piece_dress", ar: "فستان", en: "Dress", price: 35 },
    { id: "piece_suit", ar: "بدلة", en: "Suit", price: 45 },
    { id: "piece_socks", ar: "جوارب", en: "Socks", price: 8 },
    { id: "piece_underwear", ar: "ملابس داخلية", en: "Underwear", price: 8 }
  ];
  pieces.forEach((piece) => {
    if (!group.items.some((item) => item.id === piece.id)) group.items.push(piece);
  });
}
function ensureRoomServiceRestaurantMenu() {
  if (!Array.isArray(serviceOptions.room_service)) serviceOptions.room_service = [];
  const menuGroups = [
    { titleAr: "إفطار الفندق", titleEn: "Hotel breakfast", items: [
      { id: "arabic_breakfast", ar: "فطور عربي: لبنة، جبنة، زيتون، بيض، خبز", en: "Arabic breakfast: labneh, cheese, olives, eggs, bread", price: 65 },
      { id: "continental_breakfast", ar: "فطور كونتيننتال: كرواسون، مربى، عصير، قهوة", en: "Continental breakfast: croissant, jam, juice, coffee", price: 58 },
      { id: "english_breakfast", ar: "فطور إنجليزي كامل", en: "Full English breakfast", price: 72 },
      { id: "omelette", ar: "أومليت حسب الاختيار", en: "Omelette of your choice", price: 34 },
      { id: "pancakes", ar: "بان كيك مع عسل أو شوكولاتة", en: "Pancakes with honey or chocolate", price: 38 }
    ]},
    { titleAr: "المقبلات والشوربات", titleEn: "Starters and soups", items: [
      { id: "lentil_soup", ar: "شوربة عدس", en: "Lentil soup", price: 28 },
      { id: "mushroom_soup", ar: "شوربة فطر كريمية", en: "Creamy mushroom soup", price: 32 },
      { id: "hummus", ar: "حمص مع خبز عربي", en: "Hummus with Arabic bread", price: 24 },
      { id: "mutabbal", ar: "متبل باذنجان", en: "Eggplant mutabbal", price: 26 },
      { id: "crispy_calamari", ar: "كالاماري مقرمش", en: "Crispy calamari", price: 54 }
    ]},
    { titleAr: "السلطات", titleEn: "Salads", items: [
      { id: "caesar_salad", ar: "سلطة سيزر بالدجاج", en: "Chicken Caesar salad", price: 48 },
      { id: "fattoush", ar: "فتوش", en: "Fattoush", price: 30 },
      { id: "tabbouleh", ar: "تبولة", en: "Tabbouleh", price: 30 },
      { id: "greek_salad", ar: "سلطة يونانية", en: "Greek salad", price: 42 },
      { id: "quinoa_salad", ar: "سلطة كينوا صحية", en: "Healthy quinoa salad", price: 52 }
    ]},
    { titleAr: "الأطباق الرئيسية", titleEn: "Main courses", items: [
      { id: "grilled_chicken", ar: "دجاج مشوي مع أرز وخضار", en: "Grilled chicken with rice and vegetables", price: 78 },
      { id: "beef_steak", ar: "ستيك لحم مع بطاطا وصوص فلفل", en: "Beef steak with potatoes and pepper sauce", price: 145 },
      { id: "grilled_salmon", ar: "سلمون مشوي مع خضار", en: "Grilled salmon with vegetables", price: 132 },
      { id: "lamb_chops", ar: "ريش غنم مشوية", en: "Grilled lamb chops", price: 155 },
      { id: "biryani_chicken", ar: "برياني دجاج", en: "Chicken biryani", price: 68 },
      { id: "vegetable_curry", ar: "كاري خضار نباتي", en: "Vegetable curry", price: 58 }
    ]},
    { titleAr: "برغر وسندويش", titleEn: "Burgers and sandwiches", items: [
      { id: "classic_beef_burger", ar: "برغر لحم كلاسيكي مع بطاطا", en: "Classic beef burger with fries", price: 64 },
      { id: "chicken_burger", ar: "برغر دجاج مقرمش", en: "Crispy chicken burger", price: 58 },
      { id: "club_sandwich", ar: "كلوب ساندويتش مع بطاطا", en: "Club sandwich with fries", price: 52 },
      { id: "chicken_wrap", ar: "راب دجاج مشوي", en: "Grilled chicken wrap", price: 46 },
      { id: "halloumi_sandwich", ar: "ساندويتش حلوم مشوي", en: "Grilled halloumi sandwich", price: 44 }
    ]},
    { titleAr: "باستا وبيتزا", titleEn: "Pasta and pizza", items: [
      { id: "penne_arrabbiata", ar: "بيني أرابياتا", en: "Penne arrabbiata", price: 54 },
      { id: "fettuccine_alfredo", ar: "فيتوتشيني ألفريدو بالدجاج", en: "Chicken fettuccine Alfredo", price: 68 },
      { id: "spaghetti_bolognese", ar: "سباغيتي بولونيز", en: "Spaghetti bolognese", price: 62 },
      { id: "pizza_margherita", ar: "بيتزا مارغريتا", en: "Pizza Margherita", price: 55 },
      { id: "pizza_pepperoni", ar: "بيتزا بيبروني", en: "Pepperoni pizza", price: 68 }
    ]},
    { titleAr: "حلويات", titleEn: "Desserts", items: [
      { id: "cheesecake", ar: "تشيز كيك", en: "Cheesecake", price: 36 },
      { id: "chocolate_fondant", ar: "فوندو شوكولاتة", en: "Chocolate fondant", price: 42 },
      { id: "tiramisu", ar: "تيراميسو", en: "Tiramisu", price: 38 },
      { id: "fruit_platter_room", ar: "طبق فواكه موسمية", en: "Seasonal fruit platter", price: 45 },
      { id: "ice_cream_selection", ar: "تشكيلة آيس كريم", en: "Ice cream selection", price: 30 }
    ]},
    { titleAr: "مشروبات ساخنة وباردة", titleEn: "Hot and cold drinks", items: [
      { id: "arabic_coffee", ar: "قهوة عربية", en: "Arabic coffee", price: 24 },
      { id: "espresso", ar: "إسبريسو", en: "Espresso", price: 18 },
      { id: "cappuccino", ar: "كابتشينو", en: "Cappuccino", price: 24 },
      { id: "fresh_orange_juice", ar: "عصير برتقال طازج", en: "Fresh orange juice", price: 28 },
      { id: "lemon_mint_room", ar: "ليمون نعناع", en: "Lemon mint", price: 26 },
      { id: "soft_drink", ar: "مشروب غازي", en: "Soft drink", price: 16 },
      { id: "still_water", ar: "مياه معدنية", en: "Still water", price: 10 }
    ]}
  ];

  const existingIds = new Set(serviceOptions.room_service.flatMap((group) => (group.items || []).map((item) => item.id)));
  menuGroups.forEach((menuGroup) => {
    let group = serviceOptions.room_service.find((item) => item.titleAr === menuGroup.titleAr || item.titleEn === menuGroup.titleEn);
    if (!group) {
      group = { titleAr: menuGroup.titleAr, titleEn: menuGroup.titleEn, items: [] };
      serviceOptions.room_service.push(group);
    }
    menuGroup.items.forEach((menuItem) => {
      const existing = (group.items || []).find((item) => item.id === menuItem.id);
      if (existing) {
        existing.ar = menuItem.ar;
        existing.en = menuItem.en;
        existing.price = menuItem.price;
      } else if (!existingIds.has(menuItem.id)) {
        group.items.push(menuItem);
        existingIds.add(menuItem.id);
      }
    });
  });
}

ensureLaundryPieces();
ensureRoomServiceRestaurantMenu();
const defaultTenantServices = JSON.parse(JSON.stringify(services));
const defaultTenantServiceOptions = JSON.parse(JSON.stringify(serviceOptions));
const defaultTenantDepartments = JSON.parse(JSON.stringify(defaultDepartments));

let departments = JSON.parse(localStorage.getItem("hotelDepartments") || "null") || defaultDepartments;
function normalizeDepartment(department) {
  return { ...department };
}
departments = departments.map(normalizeDepartment);
let rooms = JSON.parse(localStorage.getItem("hotelRooms") || "null") || ["101"];
let currentRoom = localStorage.getItem("hotelCurrentRoom") || rooms[0];
let guestAccounts = JSON.parse(localStorage.getItem("hotelGuestAccounts") || "null") || {};
let hotelLogo = localStorage.getItem("hotelLogo") || "";
let hotelName = JSON.parse(localStorage.getItem("hotelName") || "null") || { ar: "فندق لافينا", en: "Lavina Hotel" };
const defaultTheme = {
  brand: "#0f766e",
  brandDark: "#115e59",
  accent: "#b88a44",
  page: "#eef2f1",
  panel: "#ffffff",
  soft: "#f5f7f6",
  ink: "#17211f",
  muted: "#66716d",
  line: "#d9dfdc",
  danger: "#b42318",
  font: "Tahoma, Arial, sans-serif"
};
let hotelTheme = { ...defaultTheme, ...(JSON.parse(localStorage.getItem("hotelTheme") || "null") || {}) };
const defaultHeroImages = ["assets/hotel-tablet-banner.png"];
let heroImages = JSON.parse(localStorage.getItem("heroImages") || "null") || [...defaultHeroImages];
let heroSlideSeconds = Number(localStorage.getItem("heroSlideSeconds") || 5);
let heroSlideIndex = 0;
let heroSlideTimer = null;
const defaultHotelOffers = [
  { id: "spa_offer", ar: "خصم 20% على السبا اليوم", en: "20% off spa today", serviceId: "spa_wellness" },
  { id: "dinner_offer", ar: "عشاء رومانسي مع كيك مجاني", en: "Romantic dinner with free cake", serviceId: "food_beverage" },
  { id: "cabana_offer", ar: "كابانا المسبح بسعر خاص", en: "Special pool cabana rate", serviceId: "pool_chairs" },
  { id: "trip_offer", ar: "جولة سياحية مسائية", en: "Evening city tour", serviceId: "concierge" }
];
let savedHotelOffers = JSON.parse(localStorage.getItem("hotelOffers") || "null");
let hotelOffers = Array.isArray(savedHotelOffers) && savedHotelOffers.length ? savedHotelOffers : defaultHotelOffers.map((offer) => ({ ...offer }));
let pmsConnection = JSON.parse(localStorage.getItem("hotelPmsConnection") || "null") || { provider: "mock", mode: "test", propertyId: "", hotelCode: hotelPathSlug(), enabled: false };
const savedConfig = JSON.parse(localStorage.getItem("hotelConfig") || "null");
if (savedConfig?.services && savedConfig?.serviceOptions) {
  services.splice(0, services.length, ...savedConfig.services);
  Object.keys(serviceOptions).forEach((key) => delete serviceOptions[key]);
  Object.assign(serviceOptions, savedConfig.serviceOptions);
  ensureLaundryPieces();
  ensureRoomServiceRestaurantMenu();
}
function generateStrongPassword(length = 14) {
  const chars = "ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijkmnopqrstuvwxyz23456789!@#$%";
  const required = ["ABCDEFGHJKLMNPQRSTUVWXYZ", "abcdefghijkmnopqrstuvwxyz", "23456789", "!@#$%"];
  const randomValue = () => {
    if (window.crypto?.getRandomValues) {
      const array = new Uint32Array(1);
      window.crypto.getRandomValues(array);
      return array[0];
    }
    return Math.floor(Math.random() * 4294967296);
  };
  const pick = (source) => source[randomValue() % source.length];
  const password = required.map(pick);
  while (password.length < length) password.push(pick(chars));
  for (let index = password.length - 1; index > 0; index -= 1) {
    const swapIndex = randomValue() % (index + 1);
    [password[index], password[swapIndex]] = [password[swapIndex], password[index]];
  }
  return password.join("");
}

function makeGuestPassword(room) {
  return generateStrongPassword(14);
}

function ensureStrongGuestPassword(room) {
  const account = guestAccounts[room];
  if (!account) return;
  const oldPattern = new RegExp(`^${String(room).replace(/\D/g, "") || room}1$`);
  if (!account.password || account.password === "1111" || oldPattern.test(String(account.password))) {
    account.password = generateStrongPassword(14);
  }
}

function ensureGuestAccount(room) {
  if (!guestAccounts[room]) {
    guestAccounts[room] = {
      username: `room${room}`,
      password: makeGuestPassword(room),
      room
    };
  }
  return guestAccounts[room];
}

rooms.forEach((room) => {
  ensureGuestAccount(room);
  ensureStrongGuestPassword(room);
});
localStorage.setItem("hotelGuestAccounts", JSON.stringify(guestAccounts));

function hotelPathSlug() {
  return hotelFromUrl() || "default";
}

function guestLink(room) {
  const hotel = hotelPathSlug();
  return `${window.location.origin}/hotel/${encodeURIComponent(hotel)}/guest?room=${encodeURIComponent(room)}`;
}

function roomFromUrl() {
  return new URLSearchParams(window.location.search).get("room");
}

function hotelFromUrl() {
  const pathMatch = window.location.pathname.match(/^\/hotel\/([^/]+)(?:\/|$)/);
  if (pathMatch) return decodeURIComponent(pathMatch[1]).trim().toLowerCase();
  return (new URLSearchParams(window.location.search).get("hotel") || "").trim().toLowerCase();
}

function staffUserFromUrl() {
  return new URLSearchParams(window.location.search).get("user");
}

function staffLink(account) {
  const hotel = hotelPathSlug();
  return `${window.location.origin}/hotel/${encodeURIComponent(hotel)}/staff?user=${encodeURIComponent(account.username)}`;
}

function staffAccountFromUrl() {
  const username = staffUserFromUrl();
  if (!username) return null;
  const account = getStaffAccounts().find((item) => item.username.toLowerCase() === username.toLowerCase()) || null;
  return account ? normalizeStaffAccount(account) : null;
}

function applyStaffLinkPreset() {
  const account = staffAccountFromUrl();
  if (!account) return;
  if (staffUsernameInput && !staffUsernameInput.value) staffUsernameInput.value = account.username;
  sessionStorage.setItem("hotelStaffUsername", account.username);
  sessionStorage.setItem("hotelStaffDepartment", account.department);
  sessionStorage.setItem("hotelStaffRole", account.role || "staff");
  localStorage.setItem("hotelStaffUsername", account.username);
  localStorage.setItem("hotelStaffDepartment", account.department);
  localStorage.setItem("hotelStaffRole", account.role || "staff");
}

function applyGuestLinkPreset() {
  const room = roomFromUrl();
  if (!room) return;
  const account = ensureGuestAccount(room);
  if (!rooms.includes(room)) rooms.push(room);
  currentRoom = room;
  localStorage.setItem("hotelGuestRoom", room);
  localStorage.setItem("hotelCurrentRoom", room);
  if (guestRoomSelect) guestRoomSelect.value = room;
  if (guestUsernameInput) guestUsernameInput.value = account.username;
}

function addAudit(action, details = "") {
  const actor = getRole() === "admin" ? "admin" : (activeStaffAccount()?.username || getRole());
  auditLog.unshift({ id: crypto.randomUUID(), action, details, actor, createdAt: new Date().toISOString() });
  auditLog = auditLog.slice(0, 300);
  localStorage.setItem("hotelAuditLog", JSON.stringify(auditLog));
  renderAuditLog();
}

function saveConfig() {
  const config = { services, serviceOptions };
  localStorage.setItem("hotelConfig", JSON.stringify(config));
  localStorage.setItem("hotelRooms", JSON.stringify(rooms));
  localStorage.setItem("hotelDepartments", JSON.stringify(departments));
  localStorage.setItem("hotelCurrentRoom", currentRoom);
  localStorage.setItem("hotelStaffAccounts", JSON.stringify(staffAccounts));
  localStorage.setItem("hotelGuestAccounts", JSON.stringify(guestAccounts));
  localStorage.setItem("hotelLogo", hotelLogo);
  localStorage.setItem("hotelName", JSON.stringify(hotelName));
  localStorage.setItem("hotelTheme", JSON.stringify(hotelTheme));
  localStorage.setItem("heroImages", JSON.stringify(heroImages));
  localStorage.setItem("heroSlideSeconds", String(heroSlideSeconds));
  localStorage.setItem("hotelOffers", JSON.stringify(hotelOffers));
  localStorage.setItem("hotelSuperHotels", JSON.stringify(superHotels));
  apiSave("/api/config", { config, rooms, departments, currentRoom, staffAccounts, guestAccounts, hotelLogo, hotelName, hotelTheme, heroImages, heroSlideSeconds, hotelOffers, superHotels });
}
const copy = {
  ar: {
    hotelName: "فندق لافينا",
    title: "خدمات الغرفة",
    guestTab: "النزيل",
    staffTab: "الموظفين",
    adminTab: "الإدارة",
    superAdminTab: "مالك النظام",
    superKicker: "لوحة مالك النظام",
    superTitle: "إدارة الفنادق والاشتراكات",
    superHint: "هذه الصفحة لا تظهر للفنادق، فقط لصاحب النظام",
    addHotelTitle: "إضافة فندق جديد",
    hotelsListTitle: "الفنادق المشتركة",
    hotelNameArLabel: "اسم الفندق عربي",
    hotelNameEnLabel: "اسم الفندق إنجليزي",
    hotelSlugLabel: "كود الفندق / الرابط",
    planLabel: "الباقة",
    allowedRoomsLabel: "عدد الغرف المسموح",
    subscriptionStatusLabel: "حالة الاشتراك",
    subscriptionActive: "فعال",
    subscriptionPaused: "موقوف",
    subscriptionExpired: "منتهي",
    subscriptionStartLabel: "بداية الاشتراك",
    subscriptionEndLabel: "نهاية الاشتراك",
    hotelAdminUserLabel: "يوزر أدمن الفندق",
    hotelAdminPassLabel: "باسورد أدمن الفندق",
    addHotelButton: "إضافة الفندق",
    hotelSearchPlaceholder: "بحث عن فندق",
    superLockTitle: "لوحة مالك النظام مقفلة",
    usernameLabel: "اسم المستخدم",
    passwordLabel: "كلمة المرور",
    openSuperDashboard: "فتح لوحة المالك",
    welcome: "أهلاً بك",
    heroTitle: "اطلب أي خدمة من غرفتك مباشرة",
    selectedService: "الخدمة المختارة",
    chooseItems: "اختر من القائمة",
    optionalItems: "يمكن اختيار أكثر من خيار",
    roomNumberLabel: "رقم الغرفة",
    chargeLabel: "تحميل الطلب على",
    chargeRoom: "رقم الغرفة",
    chargeAccount: "حساب النزيل",
    chargeInfo: "الحساب",
    detailsLabel: "ملاحظات إضافية",
    detailsPlaceholder: "مثلاً: بدون بصل، أو أحتاجها بعد نصف ساعة",
    sendRequest: "إرسال الطلب",
    myRequests: "طلباتي",
    filters: "فلترة",
    staffSearchPlaceholder: "بحث برقم الغرفة أو الخدمة",
    roomSearchPlaceholder: "رقم الغرفة",
    activeWork: "طلبات تحتاج متابعة",
    activeRequests: "طلبات تحتاج متابعة",
    closedArchive: "الأرشيف المكتمل والملغى",
    archiveHint: "الطلبات المكتملة والملغاة محفوظة هنا ولا تظهر مع الطلبات النشطة",
    roomBoardTitle: "غرف عليها طلبات",
    roomBoardHint: "اضغط على كرت الغرفة لعرض طلباتها فقط",
    activeCount: "طلبات نشطة",
    lateCount: "متأخر",
    viewRoom: "عرض الغرفة",
    clearRoom: "إظهار كل الغرف",
    selectedRoomOrders: "طلبات الغرفة",
    allStatuses: "كل الحالات",
    all: "الكل",
    food: "المطعم",
    housekeeping: "تنظيف",
    maintenance: "صيانة",
    frontdesk: "الاستقبال",
    pool: "المسبح",
    sports: "الرياضة",
    entertainment: "الترفيه",
    vip: "VIP",
    events: "المناسبات",
    concierge: "الكونسيرج",
    laundry: "الغسيل",
    wellness: "السبا",
    gym: "النادي الرياضي",
    business: "مركز الأعمال",
    security: "الأمن",
    transport: "النقل",
    kids: "الأطفال",
    medical: "الخدمات الطبية",
    tech: "الخدمات التقنية",
    extras: "خدمات إضافية",
    incomingRequests: "الطلبات الواردة",
    serviceCatalog: "إدارة الخدمات",
    catalogHint: "إدارة الخدمات والأسعار مرتبطة ببيانات الفندق",
    empty: "لا توجد طلبات حالياً",
    sent: "تم إرسال الطلب",
    new: "جديد",
    progress: "قيد التنفيذ",
    done: "مكتمل",
    late: "متأخر",
    cancelled: "ملغى",
    rejected: "مرفوض",
    cancel: "إلغاء الطلب",
    reject: "رفض",
    rateService: "قيّم الخدمة",
    ratingSaved: "تم حفظ التقييم",
    cancelReason: "تم الإلغاء من النزيل",
    rejectReason: "سبب الرفض",
    roomModeTitle: "وضع الغرفة",
    dndMode: "عدم الإزعاج",
    cleaningMode: "تنظيف الغرفة",
    todayOffers: "عروض الفندق اليوم",
    currentMode: "الوضع الحالي",
    modeNormal: "عادي",
    offerSpa: "خصم 20% على السبا اليوم",
    offerDinner: "عشاء رومانسي مع كيك مجاني",
    offerCabana: "كابانا المسبح بسعر خاص",
    offerTrip: "جولة سياحية مسائية",
    start: "بدء",
    complete: "إنهاء",
    selectedItems: "الاختيارات",
    notes: "ملاحظات",
    chatTitle: "دردشة الطلب",
    noMessages: "لا توجد رسائل بعد",
    sendMessage: "إرسال رسالة",
    messagePlaceholder: "اكتب رسالة للنزيل أو الموظف",
    guestSender: "النزيل",
    staffSender: "الموظف",
    adminSender: "الإدارة",
    messageSent: "تم إرسال الرسالة",
    internalReport: "بلاغ داخلي",
    reportLocation: "المكان",
    reportPriority: "الأهمية",
    reporterName: "المبلّغ",
    total: "إجمالي الطلبات",
    orderTotal: "المجموع",
    currency: "درهم",
    free: "مجاني",
    open: "طلبات مفتوحة",
    completed: "طلبات مكتملة",
    avg: "متوسط تجريبي",
    minutes: "دقيقة",
    staffPresenceTitle: "حالة الموظف",
    presenceOnline: "متواجد",
    presenceAway: "استراحة",
    presenceOffline: "غير متواجد",
    lastSeen: "آخر ظهور",
    nowOnline: "متصل الآن",
    departmentCoverage: "تغطية الأقسام",
    noOnlineStaff: "لا يوجد موظف متواجد"
  },
  en: {
    hotelName: "Lavina Hotel",
    title: "In-room services",
    guestTab: "Guest",
    staffTab: "Staff",
    adminTab: "Admin",
    superAdminTab: "System owner",
    superKicker: "System owner dashboard",
    superTitle: "Hotels and subscriptions",
    superHint: "Hotels cannot see this page. It is only for the system owner",
    addHotelTitle: "Add new hotel",
    hotelsListTitle: "Subscribed hotels",
    hotelNameArLabel: "Hotel name Arabic",
    hotelNameEnLabel: "Hotel name English",
    hotelSlugLabel: "Hotel code / link",
    planLabel: "Plan",
    allowedRoomsLabel: "Allowed rooms",
    subscriptionStatusLabel: "Subscription status",
    subscriptionActive: "Active",
    subscriptionPaused: "Paused",
    subscriptionExpired: "Expired",
    subscriptionStartLabel: "Subscription start",
    subscriptionEndLabel: "Subscription end",
    hotelAdminUserLabel: "Hotel admin user",
    hotelAdminPassLabel: "Hotel admin password",
    addHotelButton: "Add hotel",
    hotelSearchPlaceholder: "Search hotel",
    superLockTitle: "System owner dashboard locked",
    usernameLabel: "Username",
    passwordLabel: "Password",
    openSuperDashboard: "Open owner dashboard",
    generateStrongPassword: "Generate strong password",
    welcome: "Welcome",
    heroTitle: "Request any service directly from your room",
    selectedService: "Selected service",
    chooseItems: "Choose from menu",
    optionalItems: "You can select more than one item",
    roomNumberLabel: "Room number",
    chargeLabel: "Charge request to",
    chargeRoom: "Room number",
    chargeAccount: "Guest account",
    chargeInfo: "Billing",
    detailsLabel: "Extra notes",
    detailsPlaceholder: "Example: no onion, or deliver after 30 minutes",
    sendRequest: "Send request",
    myRequests: "My requests",
    filters: "Filters",
    staffSearchPlaceholder: "Search by room number or service",
    roomSearchPlaceholder: "Room number",
    activeWork: "Needs follow-up",
    activeRequests: "Needs follow-up",
    closedArchive: "Completed and closed archive",
    archiveHint: "Completed and cancelled requests are saved here and kept separate from active work",
    roomBoardTitle: "Rooms with requests",
    roomBoardHint: "Tap a room card to show only that room requests",
    activeCount: "Active requests",
    lateCount: "Delayed",
    viewRoom: "View room",
    clearRoom: "Show all rooms",
    selectedRoomOrders: "Room requests",
    allStatuses: "All statuses",
    all: "All",
    food: "Restaurant",
    housekeeping: "Housekeeping",
    maintenance: "Maintenance",
    frontdesk: "Front desk",
    pool: "Pool",
    sports: "Sports",
    entertainment: "Entertainment",
    vip: "VIP",
    events: "Occasions",
    concierge: "Concierge",
    laundry: "Laundry",
    wellness: "Spa",
    gym: "Gym",
    business: "Business Center",
    security: "Security",
    transport: "Transport",
    kids: "Kids",
    medical: "Medical",
    tech: "Tech support",
    extras: "Extras",
    incomingRequests: "Incoming requests",
    serviceCatalog: "Service catalog",
    catalogHint: "Services and prices are connected to the hotel data",
    empty: "No requests yet",
    sent: "Request sent",
    new: "New",
    progress: "In progress",
    done: "Done",
    late: "Delayed",
    cancelled: "Cancelled",
    rejected: "Rejected",
    cancel: "Cancel request",
    reject: "Reject",
    rateService: "Rate service",
    ratingSaved: "Rating saved",
    cancelReason: "Cancelled by guest",
    rejectReason: "Reject reason",
    roomModeTitle: "Room mode",
    dndMode: "Do not disturb",
    cleaningMode: "Cleaning please",
    todayOffers: "Today hotel offers",
    currentMode: "Current mode",
    modeNormal: "Normal",
    offerSpa: "20% off spa today",
    offerDinner: "Romantic dinner with free cake",
    offerCabana: "Special pool cabana rate",
    offerTrip: "Evening city tour",
    start: "Start",
    complete: "Complete",
    selectedItems: "Items",
    notes: "Notes",
    chatTitle: "Request chat",
    noMessages: "No messages yet",
    sendMessage: "Send message",
    messagePlaceholder: "Write a message to the guest or staff",
    guestSender: "Guest",
    staffSender: "Staff",
    adminSender: "Admin",
    messageSent: "Message sent",
    internalReport: "Internal report",
    reportLocation: "Location",
    reportPriority: "Priority",
    reporterName: "Reporter",
    total: "Total requests",
    orderTotal: "Total",
    currency: "AED",
    free: "Free",
    open: "Open requests",
    completed: "Completed",
    avg: "Average",
    minutes: "min",
    logoutButton: "Exit",
    staffPresenceTitle: "Staff status",
    presenceOnline: "Online",
    presenceAway: "Away",
    presenceOffline: "Offline",
    lastSeen: "Last seen",
    nowOnline: "Online now",
    departmentCoverage: "Department coverage",
    noOnlineStaff: "No online staff"
  }
};

const icons = {
  calendar: '<svg viewBox="0 0 24 24"><path d="M7 3v4"/><path d="M17 3v4"/><path d="M4 8h16"/><path d="M5 5h14v15H5z"/><path d="M8 12h3"/><path d="M13 12h3"/></svg>',
  table: '<svg viewBox="0 0 24 24"><path d="M4 9h16"/><path d="M6 9v10"/><path d="M18 9v10"/><path d="M8 5h8l2 4H6z"/><path d="M9 19h6"/></svg>',
  pool: '<svg viewBox="0 0 24 24"><path d="M4 17c2 0 2-1 4-1s2 1 4 1 2-1 4-1 2 1 4 1"/><path d="M4 21c2 0 2-1 4-1s2 1 4 1 2-1 4-1 2 1 4 1"/><path d="M8 13V5a3 3 0 0 1 6 0"/><path d="M8 9h6"/></svg>',  cloche: '<svg viewBox="0 0 24 24"><path d="M5 17h14"/><path d="M12 7v-2"/><path d="M6 17a6 6 0 0 1 12 0"/><path d="M4 20h16"/></svg>',
  sparkle: '<svg viewBox="0 0 24 24"><path d="M12 3l1.8 5.2L19 10l-5.2 1.8L12 17l-1.8-5.2L5 10l5.2-1.8z"/><path d="M19 15l.8 2.2L22 18l-2.2.8L19 21l-.8-2.2L16 18l2.2-.8z"/></svg>',
  droplet: '<svg viewBox="0 0 24 24"><path d="M12 3s6 6.2 6 11a6 6 0 0 1-12 0c0-4.8 6-11 6-11z"/></svg>',
  tool: '<svg viewBox="0 0 24 24"><path d="M14.7 6.3a4 4 0 0 0 5 5L11 20l-5-5 8.7-8.7z"/><path d="M7 17l-3 3"/></svg>',
  clock: '<svg viewBox="0 0 24 24"><circle cx="12" cy="12" r="8"/><path d="M12 8v5l3 2"/></svg>',
  shirt: '<svg viewBox="0 0 24 24"><path d="M8 4l4 2 4-2 4 4-3 3v9H7v-9L4 8z"/><path d="M10 5a2 2 0 0 0 4 0"/></svg>',
  car: '<svg viewBox="0 0 24 24"><path d="M5 13l2-5h10l2 5"/><path d="M4 13h16v5H4z"/><circle cx="7" cy="18" r="1.5"/><circle cx="17" cy="18" r="1.5"/></svg>',
  message: '<svg viewBox="0 0 24 24"><path d="M5 5h14v10H8l-3 4z"/><path d="M8 9h8"/><path d="M8 12h5"/></svg>'
};


function initialLanguage() {
  localStorage.removeItem("hotelLang");
  localStorage.removeItem(`hotelLang:${hotelPathSlug()}`);
  const queryLang = new URLSearchParams(window.location.search).get("lang");
  return queryLang === "ar" ? "ar" : "en";
}

let state = {
  lang: initialLanguage(),
  selectedService: services[0].id,
  filter: "all",
  staffSearch: "",
  staffStatus: "active",
  staffRoom: "",
  staffDate: "",
  orders: JSON.parse(localStorage.getItem("hotelOrders") || "[]")
};

let knownOrderIds = new Set(state.orders.map((order) => order.id).filter(Boolean));
const chatDrafts = {};
const delayedAlertIds = new Set(JSON.parse(localStorage.getItem("hotelDelayedAlertIds") || "[]"));

function isChatInputActive() {
  return Boolean(document.activeElement?.matches?.("[data-chat-input]"));
}

const defaultStaffAccounts = [
  { username: "frontdesk", password: generateStrongPassword(14), department: "frontdesk", role: "reception" },
  { username: "food", password: generateStrongPassword(14), department: "food", role: "staff" },
  { username: "pool", password: generateStrongPassword(14), department: "pool", role: "staff" },
  { username: "housekeeping", password: generateStrongPassword(14), department: "housekeeping", role: "staff" },
  { username: "maintenance", password: generateStrongPassword(14), department: "maintenance", role: "staff" },
  { username: "concierge", password: generateStrongPassword(14), department: "concierge", role: "staff" },
  { username: "laundry", password: generateStrongPassword(14), department: "laundry", role: "staff" },
  { username: "wellness", password: generateStrongPassword(14), department: "wellness", role: "staff" },
  { username: "gym", password: generateStrongPassword(14), department: "gym", role: "staff" },
  { username: "security", password: generateStrongPassword(14), department: "security", role: "staff" },
  { username: "transport", password: generateStrongPassword(14), department: "transport", role: "staff" },
  { username: "events", password: generateStrongPassword(14), department: "events", role: "manager" },
  { username: "vip", password: generateStrongPassword(14), department: "vip", role: "manager" }
];

let staffAccounts = JSON.parse(localStorage.getItem("hotelStaffAccounts") || "null") || defaultStaffAccounts.map((account) => ({ ...account }));

const staffRoleOptions = [
  { id: "staff", ar: "موظف قسم", en: "Department staff" },
  { id: "manager", ar: "مدير قسم", en: "Department manager" },
  { id: "accountant", ar: "محاسب", en: "Accountant" },
  { id: "reception", ar: "استقبال", en: "Reception" }
];

function normalizeStaffAccount(account) {
  const role = account.role || (account.department === "frontdesk" ? "reception" : "staff");
  return { ...account, role, presence: account.presence || "offline", lastSeen: account.lastSeen || "" };
}

staffAccounts = staffAccounts.map((account) => {
  const normalized = normalizeStaffAccount(account);
  if (!normalized.password || normalized.password === "1111") normalized.password = generateStrongPassword(14);
  return normalized;
});
localStorage.setItem("hotelStaffAccounts", JSON.stringify(staffAccounts));

function staffRoleLabel(role) {
  const option = staffRoleOptions.find((item) => item.id === role) || staffRoleOptions[0];
  return state.lang === "ar" ? option.ar : option.en;
}

function getStaffAccounts() {
  staffAccounts = staffAccounts.map(normalizeStaffAccount);
  return staffAccounts;
}

function activeStaffAccount() {
  const linked = staffAccountFromUrl();
  if (linked) return normalizeStaffAccount(linked);
  const username = sessionStorage.getItem("hotelStaffUsername") || localStorage.getItem("hotelStaffUsername") || "";
  const account = getStaffAccounts().find((item) => item.username.toLowerCase() === username.toLowerCase());
  return account ? normalizeStaffAccount(account) : null;
}

function getStaffPermission() {
  return activeStaffAccount()?.role || sessionStorage.getItem("hotelStaffRole") || "staff";
}

function staffCanViewAllDepartments() {
  return getStaffPermission() === "accountant";
}

function staffCanChangeOrderStatus() {
  return getRole() !== "staff" || getStaffPermission() !== "accountant";
}

function getStaffDepartmentId() {
  const account = activeStaffAccount();
  const requested = account?.department || sessionStorage.getItem("hotelStaffDepartment") || localStorage.getItem("hotelStaffDepartment") || "frontdesk";
  const valid = departments.find((department) => department.id === requested && department.id !== "all");
  return valid ? valid.id : (departments.find((department) => department.id !== "all")?.id || "frontdesk");
}

function getStaffDepartment() {
  const id = getStaffDepartmentId();
  return departments.find((department) => department.id === id) || departments.find((department) => department.id !== "all");
}


function presenceLabel(status) {
  if (status === "online") return t("presenceOnline");
  if (status === "away") return t("presenceAway");
  return t("presenceOffline");
}

function staffPresenceStatus(account) {
  const normalized = normalizeStaffAccount(account || {});
  if (normalized.presence === "offline") return "offline";
  const lastSeen = normalized.lastSeen ? new Date(normalized.lastSeen).getTime() : 0;
  if (!lastSeen) return normalized.presence || "offline";
  const minutesAgo = (Date.now() - lastSeen) / 60000;
  if (normalized.presence === "online" && minutesAgo > 10) return "away";
  if (minutesAgo > 45) return "offline";
  return normalized.presence || "offline";
}

function updateStaffPresence(username, presence = "online") {
  if (!username) return;
  staffAccounts = getStaffAccounts().map((account) => account.username.toLowerCase() === username.toLowerCase()
    ? { ...account, presence, lastSeen: new Date().toISOString() }
    : account);
  localStorage.setItem("hotelStaffAccounts", JSON.stringify(staffAccounts));
  saveConfig();
  if (getRole() === "admin") renderAdminControls();
}

function formatLastSeen(account) {
  if (!account?.lastSeen) return "-";
  return new Date(account.lastSeen).toLocaleString(state.lang === "ar" ? "ar-AE" : "en-US", { hour: "2-digit", minute: "2-digit", month: "short", day: "numeric" });
}

function renderStaffPresencePanel() {
  if (!staffPresencePanel) return;
  const account = activeStaffAccount();
  const isStaffPage = getRole() === "staff" && account;
  staffPresencePanel.hidden = !isStaffPage;
  if (!isStaffPage) return;
  const status = staffPresenceStatus(account);
  staffPresenceTitle.textContent = `${t("staffPresenceTitle")}: ${presenceLabel(status)}`;
  staffPresenceMeta.textContent = `${t("lastSeen")}: ${formatLastSeen(account)}`;
  staffPresencePanel.querySelectorAll("[data-presence-set]").forEach((button) => {
    const value = button.dataset.presenceSet;
    button.textContent = presenceLabel(value);
    button.classList.toggle("active", value === status);
  });
}


let lastPresenceHeartbeat = 0;
function heartbeatStaffPresence(force = false, presence = "online") {
  if (getRole() !== "staff" || !isStaffUnlocked()) return;
  const account = activeStaffAccount();
  if (!account) return;
  const now = Date.now();
  if (!force && now - lastPresenceHeartbeat < 55000) return;
  lastPresenceHeartbeat = now;
  updateStaffPresence(account.username, presence);
  if (getRole() === "staff") renderStaffPresencePanel();
}

function orderBelongsToDepartment(order, departmentId) {
  const service = services.find((item) => item.id === order.serviceId);
  return service?.department === departmentId;
}

const hotelLogoEl = document.querySelector("#hotelLogo");
const logoAdminForm = document.querySelector("#logoAdminForm");
const adminHotelNameAr = document.querySelector("#adminHotelNameAr");
const adminHotelNameEn = document.querySelector("#adminHotelNameEn");
const adminLogoInput = document.querySelector("#adminLogoInput");
const adminLogoPreview = document.querySelector("#adminLogoPreview");
const adminLogoEmpty = document.querySelector("#adminLogoEmpty");
const removeLogoButton = document.querySelector("#removeLogo");
const themeAdminForm = document.querySelector("#themeAdminForm");
const resetThemeButton = document.querySelector("#resetTheme");
const themeInputs = {
  brand: document.querySelector("#themeBrand"),
  brandDark: document.querySelector("#themeBrandDark"),
  accent: document.querySelector("#themeAccent"),
  page: document.querySelector("#themePage"),
  panel: document.querySelector("#themePanel"),
  soft: document.querySelector("#themeSoft"),
  ink: document.querySelector("#themeInk"),
  muted: document.querySelector("#themeMuted"),
  line: document.querySelector("#themeLine"),
  danger: document.querySelector("#themeDanger"),
  font: document.querySelector("#themeFont")
};
const staffFilters = document.querySelector("#staffFilters");
const staffSearch = document.querySelector("#staffSearch");
const staffStatusFilter = document.querySelector("#staffStatusFilter");
const staffRoomFilter = document.querySelector("#staffRoomFilter");
const staffDateFilter = document.querySelector("#staffDateFilter");
const staffPresencePanel = document.querySelector("#staffPresencePanel");
const staffPresenceTitle = document.querySelector("#staffPresenceTitle");
const staffPresenceMeta = document.querySelector("#staffPresenceMeta");
const serviceGrid = document.querySelector("#serviceGrid");
const serviceOptionsEl = document.querySelector("#serviceOptions");
const requestForm = document.querySelector("#requestForm");
const detailsInput = document.querySelector("#requestDetails");
const topContext = document.querySelector("#topContext");
const logoutButton = document.querySelector("#logoutButton");
const topContextLabel = document.querySelector("#topContextLabel");
const currentRoomDisplay = document.querySelector("#currentRoomDisplay");
const guestRoomSelect = document.querySelector("#guestRoomSelect");
const requestRoomDisplay = document.querySelector("#requestRoomDisplay");
const chargeSelect = document.querySelector("#chargeSelect");
const selectedServiceName = document.querySelector("#selectedServiceName");
const selectedEstimate = document.querySelector("#selectedEstimate");
const guestOrders = document.querySelector("#guestOrders");
const todayOffersList = document.querySelector("#todayOffersList");
const roomModeStatus = document.querySelector("#roomModeStatus");
const staffOrders = document.querySelector("#staffOrders");
const catalogList = document.querySelector("#catalogList");
const metrics = document.querySelector("#metrics");
const adminInsights = document.querySelector("#adminInsights");
const toast = document.querySelector("#toast");
const appShell = document.querySelector(".app-shell");
const guestLock = document.querySelector("#guestLock");
const guestLockForm = document.querySelector("#guestLockForm");
const guestUsernameInput = document.querySelector("#guestUsernameInput");
const guestPasswordInput = document.querySelector("#guestPasswordInput");
const staffLock = document.querySelector("#staffLock");
const staffLockForm = document.querySelector("#staffLockForm");
const staffUsernameInput = document.querySelector("#staffUsernameInput");
const staffPasswordInput = document.querySelector("#staffPasswordInput");
const adminLock = document.querySelector("#adminLock");
const adminLockForm = document.querySelector("#adminLockForm");
const adminUsernameInput = document.querySelector("#adminUsernameInput");
const adminPasswordInput = document.querySelector("#adminPasswordInput");
const superAdminLock = document.querySelector("#superAdminLock");
const superAdminLockForm = document.querySelector("#superAdminLockForm");
const superUsernameInput = document.querySelector("#superUsernameInput");
const superPasswordInput = document.querySelector("#superPasswordInput");
const superHotelForm = document.querySelector("#superHotelForm");
const superHotelNameAr = document.querySelector("#superHotelNameAr");
const superHotelNameEn = document.querySelector("#superHotelNameEn");
const superHotelSlug = document.querySelector("#superHotelSlug");
const superHotelPlan = document.querySelector("#superHotelPlan");
const superHotelRooms = document.querySelector("#superHotelRooms");
const superHotelStatus = document.querySelector("#superHotelStatus");
const superHotelStart = document.querySelector("#superHotelStart");
const superHotelEnd = document.querySelector("#superHotelEnd");
const superHotelAdminUser = document.querySelector("#superHotelAdminUser");
const superHotelAdminPass = document.querySelector("#superHotelAdminPass");
const superHotelSearch = document.querySelector("#superHotelSearch");
const superHotelList = document.querySelector("#superHotelList");
const superMetrics = document.querySelector("#superMetrics");
const adminRoomNumber = document.querySelector("#adminRoomNumber");
const roomAdminList = document.querySelector("#roomAdminList");
const serviceAdminForm = document.querySelector("#serviceAdminForm");
const adminServiceAr = document.querySelector("#adminServiceAr");
const adminServiceEn = document.querySelector("#adminServiceEn");
const adminServiceDesc = document.querySelector("#adminServiceDesc");
const adminServiceDepartment = document.querySelector("#adminServiceDepartment");
const optionAdminForm = document.querySelector("#optionAdminForm");
const adminOptionService = document.querySelector("#adminOptionService");
const adminOptionAr = document.querySelector("#adminOptionAr");
const adminOptionEn = document.querySelector("#adminOptionEn");
const adminOptionPrice = document.querySelector("#adminOptionPrice");
const departmentAdminForm = document.querySelector("#departmentAdminForm");
const adminDepartmentAr = document.querySelector("#adminDepartmentAr");
const adminDepartmentEn = document.querySelector("#adminDepartmentEn");
const departmentAdminList = document.querySelector("#departmentAdminList");
const staffAccountForm = document.querySelector("#staffAccountForm");
const adminStaffUsername = document.querySelector("#adminStaffUsername");
const adminStaffPassword = document.querySelector("#adminStaffPassword");
const generateStaffPasswordButton = document.querySelector("#generateStaffPassword");
const adminStaffDepartment = document.querySelector("#adminStaffDepartment");
const adminStaffRole = document.querySelector("#adminStaffRole");
const staffAccountList = document.querySelector("#staffAccountList");
const invoiceRoomSelect = document.querySelector("#invoiceRoomSelect");
const showInvoiceButton = document.querySelector("#showInvoice");
const printInvoiceButton = document.querySelector("#printInvoice");
const downloadInvoiceButton = document.querySelector("#downloadInvoice");
const invoiceOutput = document.querySelector("#invoiceOutput");
const qrRoomSelect = document.querySelector("#qrRoomSelect");
const qrPreview = document.querySelector("#qrPreview");
const downloadQrButton = document.querySelector("#downloadQr");
const printQrButton = document.querySelector("#printQr");
const exportTodayReportButton = document.querySelector("#exportTodayReport");
const exportAllReportButton = document.querySelector("#exportAllReport");
const exportServicesReportButton = document.querySelector("#exportServicesReport");
const exportAuditLogButton = document.querySelector("#exportAuditLog");
const clearAuditLogButton = document.querySelector("#clearAuditLog");
const auditList = document.querySelector("#auditList");
const heroImageEl = document.querySelector("#heroImage");
const heroDots = document.querySelector("#heroDots");
const heroAdminForm = document.querySelector("#heroAdminForm");
const heroImageInput = document.querySelector("#heroImageInput");
const heroSlideSecondsInput = document.querySelector("#heroSlideSeconds");
const heroAdminPreview = document.querySelector("#heroAdminPreview");
const resetHeroImagesButton = document.querySelector("#resetHeroImages");
const offerAdminForm = document.querySelector("#offerAdminForm");
const adminOfferAr = document.querySelector("#adminOfferAr");
const adminOfferEn = document.querySelector("#adminOfferEn");
const adminOfferService = document.querySelector("#adminOfferService");
const offerAdminList = document.querySelector("#offerAdminList");
const pmsAdminForm = document.querySelector("#pmsAdminForm");
const pmsProvider = document.querySelector("#pmsProvider");
const pmsMode = document.querySelector("#pmsMode");
const pmsPropertyId = document.querySelector("#pmsPropertyId");
const pmsHotelCode = document.querySelector("#pmsHotelCode");
const pmsEnabled = document.querySelector("#pmsEnabled");
const checkPmsStatusButton = document.querySelector("#checkPmsStatus");
const pmsStatusOutput = document.querySelector("#pmsStatusOutput");
const adminSections = [
  { id: "all", ar: "الكل", en: "All" },
  { id: "brand", ar: "الهوية والمظهر", en: "Brand & theme" },
  { id: "rooms", ar: "الغرف", en: "Rooms" },
  { id: "services", ar: "الخدمات", en: "Services" },
  { id: "staff", ar: "الموظفون", en: "Staff" },
  { id: "billing", ar: "الفواتير", en: "Billing" },
  { id: "reports", ar: "التقارير والسجل", en: "Reports & log" },
  { id: "links", ar: "الروابط", en: "Links" },
  { id: "pms", ar: "PMS", en: "PMS" }
];
let activeAdminSection = localStorage.getItem("hotelAdminSection") || "all";
let auditLog = JSON.parse(localStorage.getItem("hotelAuditLog") || "[]");
let superHotels = JSON.parse(localStorage.getItem("hotelSuperHotels") || "[]");
let superHotelQuery = "";

function adminSectionName(section) {
  return state.lang === "ar" ? section.ar : section.en;
}

function assignAdminSections() {
  const mapping = {
    logoAdminForm: "brand",
    heroAdminForm: "brand",
    themeAdminForm: "brand",
    roomAdminForm: "rooms",
    serviceAdminForm: "services",
    optionAdminForm: "services",
    departmentAdminForm: "staff",
    staffAccountForm: "staff",
    pmsAdminForm: "pms"
  };
  document.querySelector("#securityTool")?.setAttribute("data-admin-section", "staff");
  Object.entries(mapping).forEach(([id, section]) => {
    const element = document.querySelector(`#${id}`);
    if (element) element.dataset.adminSection = section;
  });
  document.querySelector(".login-links")?.setAttribute("data-admin-section", "links");
  document.querySelector(".invoice-tool")?.setAttribute("data-admin-section", "billing");
  document.querySelector(".reports-tool")?.setAttribute("data-admin-section", "reports");
  document.querySelector(".audit-tool")?.setAttribute("data-admin-section", "reports");
  document.querySelector(".qr-tool")?.setAttribute("data-admin-section", "rooms");
}

function renderAdminSectionTabs() {
  const dashboard = document.querySelector("#adminDashboard");
  if (!dashboard) return;
  let nav = document.querySelector("#adminSectionTabs");
  if (!nav) {
    nav = document.createElement("div");
    nav.id = "adminSectionTabs";
    nav.className = "admin-section-tabs";
    dashboard.before(nav);
  }
  nav.innerHTML = adminSections.map((section) => `<button class="admin-section-tab ${activeAdminSection === section.id ? "active" : ""}" type="button" data-admin-tab="${section.id}">${adminSectionName(section)}</button>`).join("");
  dashboard.querySelectorAll("[data-admin-section]").forEach((tool) => {
    tool.hidden = activeAdminSection !== "all" && tool.dataset.adminSection !== activeAdminSection;
  });
}

function currentHotelName() {
  if (getRole() === "superadmin") return uiText("منصة النظام", "System platform");
  return state.lang === "ar" ? (hotelName.ar || "\u0641\u0646\u062f\u0642 \u0644\u0627\u0641\u064a\u0646\u0627") : (hotelName.en || "Lavina Hotel");
}

function t(key) {
  if (key === "title" && getRole() === "superadmin") return uiText("لوحة مالك النظام", "System owner dashboard");
  if (key === "hotelName") return currentHotelName();
  return copy[state.lang][key] || key;
}

function escapeHtml(value) {
  return String(value || "").replace(/[&<>"]/g, (char) => ({ "&": "&amp;", "<": "&lt;", ">": "&gt;", '"': "&quot;" }[char]));
}


const staticEnglishText = {
  "#logoAdminForm h3": "Hotel logo and name",
  "#logoAdminForm label:nth-of-type(1) span": "Hotel name Arabic",
  "#logoAdminForm label:nth-of-type(2) span": "Hotel name English",
  "#logoAdminForm label:nth-of-type(3) span": "Choose logo image",
  "#adminLogoEmpty": "No logo selected yet",
  "#logoAdminForm button[type=submit]": "Save name and logo",
  "#removeLogo": "Remove logo",
  "#heroAdminForm h3": "Main slider images",
  "#heroAdminForm label:nth-of-type(1) span": "Add slider images",
  "#heroAdminForm label:nth-of-type(2) span": "Change image every seconds",
  "#heroAdminForm button[type=submit]": "Save slider images",
  "#resetHeroImages": "Restore default image",
  "#offerAdminForm h3": "Today hotel offers",
  "#offerAdminForm label:nth-of-type(1) span": "Offer title Arabic",
  "#offerAdminForm label:nth-of-type(2) span": "Offer title English",
  "#offerAdminForm label:nth-of-type(3) span": "Open which service?",
  "#offerAdminForm button[type=submit]": "Add offer",
  "#themeAdminForm h3": "System colors and font",
  "#themeAdminForm label:nth-of-type(1) span": "Primary color",
  "#themeAdminForm label:nth-of-type(2) span": "Dark primary color",
  "#themeAdminForm label:nth-of-type(3) span": "Accent color",
  "#themeAdminForm label:nth-of-type(4) span": "Page background",
  "#themeAdminForm label:nth-of-type(5) span": "Card background",
  "#themeAdminForm label:nth-of-type(6) span": "Soft background",
  "#themeAdminForm label:nth-of-type(7) span": "Text color",
  "#themeAdminForm label:nth-of-type(8) span": "Muted text",
  "#themeAdminForm label:nth-of-type(9) span": "Border color",
  "#themeAdminForm label:nth-of-type(10) span": "Alert and danger color",
  "#themeAdminForm label:nth-of-type(11) span": "Font",
  "#themeAdminForm button[type=submit]": "Save theme",
  "#resetTheme": "Reset default",  "#roomAdminForm h3": "Rooms",
  "#roomAdminForm label span": "New room number",
  "#roomAdminForm button[type=submit]": "Add room",
  "#serviceAdminForm h3": "Add service card",
  "#serviceAdminForm label:nth-of-type(1) span": "Card name Arabic",
  "#serviceAdminForm label:nth-of-type(2) span": "Card name English",
  "#serviceAdminForm label:nth-of-type(3) span": "Short description",
  "#serviceAdminForm label:nth-of-type(4) span": "Staff department",
  "#serviceAdminForm button[type=submit]": "Add card",
  "#optionAdminForm h3": "Add service inside card",
  "#optionAdminForm label:nth-of-type(1) span": "Card",
  "#optionAdminForm label:nth-of-type(2) span": "Service name Arabic",
  "#optionAdminForm label:nth-of-type(3) span": "Service name English",
  "#optionAdminForm label:nth-of-type(4) span": "Price",
  "#optionAdminForm button[type=submit]": "Add service",
  "#departmentAdminForm h3": "Staff departments",
  "#departmentAdminForm label:nth-of-type(1) span": "Department name Arabic",
  "#departmentAdminForm label:nth-of-type(2) span": "Department name English",
  "#departmentAdminForm button[type=submit]": "Add department",
  "#staffAccountForm h3": "Staff accounts",
  "#staffAccountForm label:nth-of-type(1) span": "Username",
  "#staffAccountForm label:nth-of-type(2) span": "Password",
  "#staffAccountForm label:nth-of-type(3) span": "Department",
  "#staffAccountForm label:nth-of-type(4) span": "Permission",
  "#generateStaffPassword": "Generate strong password",
  "#staffAccountForm button[type=submit]": "Add staff member",
  "#securityTool h3": "Security settings",
  "#securityTool label:nth-of-type(1) span": "Admin username",
  "#securityTool label:nth-of-type(2) span": "Admin password",
  "#generateAdminPassword": "Generate strong password",
  "#saveAdminPassword": "Save admin password",
  "#securityTool .security-note": "Do not use simple passwords. Use a strong password for each hotel and change it when handing over the system.",
  ".login-links h3": "Login links",
  ".login-links a:nth-of-type(1)": "Guest login",
  ".login-links a:nth-of-type(2)": "Staff login",
  ".login-links a:nth-of-type(3)": "Admin login",
  "#internalReportLink": "Staff reports",
  ".invoice-tool h3": "Room invoice",
  ".invoice-tool label span": "Choose room number",
  "#showInvoice": "Show invoice",
  "#printInvoice": "Print invoice",
  "#downloadInvoice": "Download invoice",
  "#reportsTool h3": "Reports",
  "#exportTodayReport": "Export today's requests Excel",
  "#exportAllReport": "Export all requests Excel",
  "#exportServicesReport": "Most requested services report",
  "#auditTool h3": "Activity log",
  "#exportAuditLog": "Export log",
  "#clearAuditLog": "Clear log",
  "#qrAdminTool h3": "Room QR",
  "#qrAdminTool label span": "Choose room number",
  "#downloadQr": "Download QR",
  "#printQr": "Print QR",
  "#guestLock h2": "Guest login",
  "#guestLock label:nth-of-type(1) span": "Username",
  "#guestLock label:nth-of-type(2) span": "Password",
  "#guestLock button": "Login",
  "#guestLock p": "Use the room credentials from the admin dashboard",
  "#staffLock h2": "Staff login",
  "#staffLock label:nth-of-type(1) span": "Username",
  "#staffLock label:nth-of-type(2) span": "Password",
  "#staffLock button": "Login",
  "#staffLock p": "Use the staff credentials from the admin dashboard",
  "#adminLock h2": "Admin dashboard locked",
  "#adminLock label:nth-of-type(1) span": "Username",
  "#adminLock label:nth-of-type(2) span": "Password",
  "#adminLock button": "Open dashboard",
  "#adminLock p": "Use the saved admin password",
  "#pmsAdminForm h3": "PMS integration",
  "#pmsAdminForm label:nth-of-type(1) span": "PMS provider",
  "#pmsAdminForm label:nth-of-type(2) span": "Environment",
  "#pmsAdminForm label:nth-of-type(3) span": "Property ID",
  "#pmsAdminForm label:nth-of-type(4) span": "Hotel code",
  "#pmsAdminForm label:nth-of-type(5) span": "Enable PMS verification for room access",
  "#pmsAdminForm button[type=submit]": "Save PMS settings",
  "#checkPmsStatus": "Check PMS status"
};

const staticEnglishPlaceholders = {
  "#adminRoomNumber": "Example: 508",
  "#adminServiceAr": "Example: New service",
  "#adminServiceEn": "New service",
  "#adminServiceDesc": "Description shown under the card",
  "#adminOptionAr": "Example: Special request",
  "#adminOptionEn": "Special request",
  "#adminDepartmentAr": "Example: Beach",
  "#adminDepartmentEn": "Beach",
  "#adminStaffUsername": "Example: pool2",
  "#adminStaffPassword": "Auto-generated if left empty",
  "#adminOfferAr": "Example: Spa discount",
  "#adminOfferEn": "Example: Spa discount",
  "#securityAdminPassword": "Strong password",
  "#superHotelNameAr": "Example: Lavina Hotel in Arabic",
  "#superHotelAdminPass": "Auto-generated if empty",
  "#pmsPropertyId": "OPERA_PROPERTY_ID",
  "#pmsHotelCode": "Hotel code"
};

function uiText(ar, en) {
  return state.lang === "ar" ? ar : en;
}

function applyStaticLanguage() {
  document.title = getRole() === "superadmin" ? uiText("لوحة مالك النظام", "System owner dashboard") : uiText("نظام خدمات غرف الفندق", "Hotel room service system");
  Object.entries(staticEnglishText).forEach(([selector, english]) => {
    document.querySelectorAll(selector).forEach((el) => {
      if (!el.dataset.arText) el.dataset.arText = el.textContent;
      el.textContent = state.lang === "ar" ? el.dataset.arText : english;
    });
  });
  Object.entries(staticEnglishPlaceholders).forEach(([selector, english]) => {
    document.querySelectorAll(selector).forEach((el) => {
      if (!el.dataset.arPlaceholder) el.dataset.arPlaceholder = el.placeholder;
      el.placeholder = state.lang === "ar" ? el.dataset.arPlaceholder : english;
    });
  });
  document.querySelector("#langToggle")?.setAttribute("title", uiText("تبديل اللغة", "Switch language"));
  document.querySelector("#langToggle")?.setAttribute("aria-label", uiText("تبديل اللغة", "Switch language"));
}
function localized(item, arKey = "ar", enKey = "en") {
  return state.lang === "ar" ? item[arKey] : item[enKey];
}

function formatMoney(price) {
  const value = Number(price) || 0;
  return value > 0 ? `${value} ${t("currency")}` : t("free");
}

function itemLabel(item) {
  return `${localized(item)} - ${formatMoney(item.price)}`;
}

function calculateTotal(items) {
  return (Array.isArray(items) ? items : []).reduce((sum, item) => sum + ((Number(item.price) || 0) * (Number(item.quantity) || 1)), 0);
}

function serviceName(service) {
  return state.lang === "ar" ? service.nameAr : service.nameEn;
}

function serviceDesc(service) {
  return state.lang === "ar" ? service.descAr : service.descEn;
}

function orderTimeValue(order, key = "updatedAt") {
  return new Date(order?.[key] || order?.createdAt || 0).getTime() || 0;
}

function mergeOrderLists(localOrders, remoteOrders) {
  const merged = new Map();
  (Array.isArray(remoteOrders) ? remoteOrders : []).forEach((order) => {
    if (order?.id) merged.set(order.id, order);
  });
  (Array.isArray(localOrders) ? localOrders : []).forEach((order) => {
    if (!order?.id) return;
    const current = merged.get(order.id);
    if (!current || orderTimeValue(order) > orderTimeValue(current)) merged.set(order.id, order);
  });
  return Array.from(merged.values()).sort((a, b) => orderTimeValue(b, "createdAt") - orderTimeValue(a, "createdAt"));
}

function apiPathWithHotel(path) {
  const hotel = hotelFromUrl();
  if (!hotel || !path.startsWith("/api/")) return path;
  const separator = path.includes("?") ? "&" : "?";
  return `${path}${separator}hotel=${encodeURIComponent(hotel)}`;
}

function resetTenantDefaultsFromTemplate() {
  services.splice(0, services.length, ...JSON.parse(JSON.stringify(defaultTenantServices)));
  Object.keys(serviceOptions).forEach((key) => delete serviceOptions[key]);
  Object.assign(serviceOptions, JSON.parse(JSON.stringify(defaultTenantServiceOptions)));
  departments = JSON.parse(JSON.stringify(defaultTenantDepartments));
  rooms = ["101"];
  currentRoom = "101";
  guestAccounts = {};
  staffAccounts = defaultStaffAccounts.map((account) => normalizeStaffAccount({ ...account }));
  hotelLogo = "";
  hotelName = { ar: "فندق جديد", en: "New Hotel" };
  hotelTheme = { ...defaultTheme };
  heroImages = [...defaultHeroImages];
  heroSlideSeconds = 5;
  hotelOffers = defaultHotelOffers.map((offer) => ({ ...offer }));
  state.orders = [];
  knownOrderIds = new Set();
  rooms.forEach((room) => ensureGuestAccount(room));
}
function ordersEndpoint() {
  const role = getRole();
  const params = new URLSearchParams();
  if (role === "guest") params.set("room", guestRoomSelect?.value || roomFromUrl() || currentRoom);
  if (role === "staff" && !staffCanViewAllDepartments()) params.set("department", getStaffDepartmentId());
  const query = params.toString();
  return `/api/orders${query ? `?${query}` : ""}`;
}

async function fetchBackendOrders() {
  const data = await apiLoad(ordersEndpoint());
  return Array.isArray(data?.orders) ? data.orders : null;
}

function shouldNotifyOrder(order) {
  const role = getRole();
  if (role === "admin") return true;
  if (role === "staff") return staffCanViewAllDepartments() || orderBelongsToDepartment(order, getStaffDepartmentId());
  return false;
}

function playOrderAlert() {
  try {
    const AudioContextClass = window.AudioContext || window.webkitAudioContext;
    if (!AudioContextClass) return;
    const context = new AudioContextClass();
    const oscillator = context.createOscillator();
    const gain = context.createGain();
    oscillator.type = "sine";
    oscillator.frequency.value = 880;
    gain.gain.setValueAtTime(0.001, context.currentTime);
    gain.gain.exponentialRampToValueAtTime(0.16, context.currentTime + 0.02);
    gain.gain.exponentialRampToValueAtTime(0.001, context.currentTime + 0.35);
    oscillator.connect(gain);
    gain.connect(context.destination);
    oscillator.start();
    oscillator.stop(context.currentTime + 0.36);
    window.setTimeout(() => context.close(), 500);
  } catch (error) {
    // Browsers can block audio before user interaction; visual toast still appears.
  }
}

function markNewIncomingOrders(orders) {
  const incoming = orders.filter((order) => order?.id && !knownOrderIds.has(order.id) && shouldNotifyOrder(order));
  orders.forEach((order) => {
    if (order?.id) knownOrderIds.add(order.id);
  });
  if (!incoming.length) return;
  incoming.forEach((order) => {
    order.justArrived = true;
  });
  playOrderAlert();
  showToast(state.lang === "ar" ? `وصل ${incoming.length} طلب جديد` : `${incoming.length} new request(s)`);
  window.setTimeout(() => {
    incoming.forEach((order) => {
      delete order.justArrived;
    });
    renderOrders();
  }, 5000);
}

async function syncOrdersFromBackend({ renderAfter = true } = {}) {
  const remoteOrders = await fetchBackendOrders();
  if (!remoteOrders) return;
  const merged = hotelFromUrl() ? [...remoteOrders] : mergeOrderLists(state.orders, remoteOrders);
  const changed = JSON.stringify(merged) !== JSON.stringify(state.orders);
  if (changed) markNewIncomingOrders(merged);
  state.orders = merged;
  localStorage.setItem("hotelOrders", JSON.stringify(state.orders));
  if (changed && renderAfter) render();
}

async function saveOrder(order) {
  if (!order?.id) return;
  localStorage.setItem("hotelOrders", JSON.stringify(state.orders));
  await apiSave("/api/orders", [order]);
}

async function saveOrders() {
  localStorage.setItem("hotelOrders", JSON.stringify(state.orders));
  await apiSave("/api/orders", state.orders);
}

async function apiLoad(path) {
  try {
    const response = await fetch(apiPathWithHotel(path), { headers: { "Accept": "application/json" } });
    if (!response.ok) return null;
    return await response.json();
  } catch (error) {
    return null;
  }
}

async function apiSave(path, payload) {
  try {
    await fetch(apiPathWithHotel(path), {
      method: "PUT",
      headers: { "Content-Type": "application/json" },
      body: JSON.stringify(payload)
    });
  } catch (error) {
    // Offline/static mode: localStorage remains the fallback.
  }
}

async function apiSendJson(path, method, payload) {
  try {
    const response = await fetch(apiPathWithHotel(path), {
      method,
      headers: { "Content-Type": "application/json", "Accept": "application/json" },
      body: JSON.stringify(payload || {})
    });
    const data = await response.json().catch(() => ({}));
    return { ok: response.ok, data };
  } catch (error) {
    return { ok: false, data: { error: "network_error", message: error.message } };
  }
}
async function apiDelete(path) {
  try {
    await fetch(apiPathWithHotel(path), { method: "DELETE" });
  } catch (error) {
    // Offline/static mode: localStorage remains the fallback.
  }
}

async function deleteOrdersForRoom(room) {
  const removedOrders = state.orders.filter((order) => String(order.room) === String(room));
  state.orders = state.orders.filter((order) => String(order.room) !== String(room));
  removedOrders.forEach((order) => {
    delete chatDrafts[order.id];
    delayedAlertIds.delete(order.id);
  });
  knownOrderIds = new Set(state.orders.map((order) => order.id).filter(Boolean));
  localStorage.setItem("hotelOrders", JSON.stringify(state.orders));
  localStorage.setItem("hotelDelayedAlertIds", JSON.stringify([...delayedAlertIds]));
  await apiDelete(`/api/orders?room=${encodeURIComponent(room)}`);
  return removedOrders.length;
}
async function loadBackendState() {
  const data = await apiLoad("/api/bootstrap");
  if (!data) return;
  const isolatedHotel = !!hotelFromUrl();
  if (Array.isArray(data.orders)) {
    state.orders = data.orders;
    knownOrderIds = new Set(state.orders.map((order) => order.id).filter(Boolean));
    localStorage.setItem("hotelOrders", JSON.stringify(state.orders));
  }
  if (Array.isArray(data.superHotels)) {
    superHotels = data.superHotels;
    localStorage.setItem("hotelSuperHotels", JSON.stringify(superHotels));
  }
  if (isolatedHotel && !data.config) {
    resetTenantDefaultsFromTemplate();
    const hotelRecord = superHotels.find((hotel) => hotel.slug === hotelFromUrl());
    if (hotelRecord) hotelName = { ar: hotelRecord.nameAr || hotelRecord.nameEn || "فندق جديد", en: hotelRecord.nameEn || hotelRecord.nameAr || "New Hotel" };
  }
  if (Array.isArray(data.staffAccounts)) {
    let staffChanged = false;
    staffAccounts = data.staffAccounts.map((account) => {
      const normalized = normalizeStaffAccount(account);
      if (!normalized.password || normalized.password === "1111") {
        normalized.password = generateStrongPassword(14);
        staffChanged = true;
      }
      return normalized;
    });
    localStorage.setItem("hotelStaffAccounts", JSON.stringify(staffAccounts));
    if (staffChanged) apiSave("/api/staff-accounts", staffAccounts);
  }
  if (data.guestAccounts && typeof data.guestAccounts === "object") {
    guestAccounts = data.guestAccounts;
    let guestChanged = false;
    Object.keys(guestAccounts).forEach((room) => {
      const before = guestAccounts[room]?.password;
      ensureStrongGuestPassword(room);
      if (guestAccounts[room]?.password !== before) guestChanged = true;
    });
    localStorage.setItem("hotelGuestAccounts", JSON.stringify(guestAccounts));
    if (guestChanged) saveConfig();
  }
  if (typeof data.hotelLogo === "string") {
    hotelLogo = data.hotelLogo;
    localStorage.setItem("hotelLogo", hotelLogo);
  }
  if (data.hotelName && typeof data.hotelName === "object") {
    hotelName = { ar: data.hotelName.ar || "\u0641\u0646\u062f\u0642 \u0644\u0627\u0641\u064a\u0646\u0627", en: data.hotelName.en || "Lavina Hotel" };
    localStorage.setItem("hotelName", JSON.stringify(hotelName));
  }
  if (data.hotelTheme && typeof data.hotelTheme === "object") {
    hotelTheme = { ...defaultTheme, ...data.hotelTheme };
    localStorage.setItem("hotelTheme", JSON.stringify(hotelTheme));
  }
  if (Array.isArray(data.heroImages) && data.heroImages.length) {
    heroImages = data.heroImages;
    localStorage.setItem("heroImages", JSON.stringify(heroImages));
  }
  if (data.heroSlideSeconds) {
    heroSlideSeconds = Math.max(2, Number(data.heroSlideSeconds) || 5);
    localStorage.setItem("heroSlideSeconds", String(heroSlideSeconds));
  }
  if (data.config?.services && data.config?.serviceOptions) {
    services.splice(0, services.length, ...data.config.services);
    Object.keys(serviceOptions).forEach((key) => delete serviceOptions[key]);
    Object.assign(serviceOptions, data.config.serviceOptions);
    ensureLaundryPieces();
    ensureRoomServiceRestaurantMenu();
    localStorage.setItem("hotelConfig", JSON.stringify({ services, serviceOptions }));
  }
  if (Array.isArray(data.rooms)) {
    rooms = data.rooms;
    localStorage.setItem("hotelRooms", JSON.stringify(rooms));
  }
  if (Array.isArray(data.departments)) {
    departments = data.departments.map(normalizeDepartment);
    localStorage.setItem("hotelDepartments", JSON.stringify(departments));
  }
  ensureCoreDepartments();
  if (data.pmsConnection) {
    pmsConnection = normalizePmsConnection(data.pmsConnection);
    localStorage.setItem("hotelPmsConnection", JSON.stringify(pmsConnection));
  }
  if (data.currentRoom) {
    currentRoom = data.currentRoom;
    localStorage.setItem("hotelCurrentRoom", currentRoom);
  }
}




function normalizePmsConnection(connection = {}) {
  return {
    provider: connection.provider || "mock",
    mode: connection.mode || "test",
    propertyId: connection.propertyId || connection.property_id || "",
    hotelCode: connection.hotelCode || connection.hotel_code || hotelPathSlug(),
    enabled: Boolean(connection.enabled)
  };
}

function renderPmsAdmin() {
  if (!pmsAdminForm) return;
  const connection = normalizePmsConnection(pmsConnection);
  const pmsLabelCopy = [
    ["#pmsAdminForm h3", "تكامل PMS", "PMS integration"],
    ["#pmsAdminForm label:nth-of-type(1) span", "مزود PMS", "PMS provider"],
    ["#pmsAdminForm label:nth-of-type(2) span", "البيئة", "Environment"],
    ["#pmsAdminForm label:nth-of-type(3) span", "Property ID", "Property ID"],
    ["#pmsAdminForm label:nth-of-type(4) span", "كود الفندق", "Hotel code"],
    ["#pmsAdminForm label:nth-of-type(5) span", "تفعيل تحقق PMS لدخول الغرف", "Enable PMS verification for room access"],
    ["#pmsAdminForm button[type=submit]", "حفظ إعدادات PMS", "Save PMS settings"],
    ["#checkPmsStatus", "فحص حالة PMS", "Check PMS status"]
  ];
  pmsLabelCopy.forEach(([selector, ar, en]) => {
    document.querySelectorAll(selector).forEach((el) => { el.textContent = uiText(ar, en); });
  });
  if (pmsProvider) pmsProvider.value = connection.provider;
  if (pmsMode) pmsMode.value = connection.mode;
  if (pmsPropertyId) pmsPropertyId.value = connection.propertyId;
  if (pmsHotelCode) pmsHotelCode.value = connection.hotelCode;
  if (pmsEnabled) pmsEnabled.checked = connection.enabled;
  if (pmsStatusOutput && !pmsStatusOutput.dataset.touched) {
    pmsStatusOutput.textContent = connection.provider === "mock"
      ? uiText("وضع الاختبار جاهز بدون اتصال Oracle", "Mock PMS is ready for testing without Oracle")
      : uiText("يتطلب Oracle OPERA Cloud وثائق OHIP الرسمية والاعتمادات والصلاحيات", "Oracle OPERA Cloud requires official OHIP documentation, credentials, app key, property ID, and permissions");
  }
}

async function refreshPmsStatus() {
  const data = await apiLoad("/api/pms/connection-status");
  if (!data) {
    if (pmsStatusOutput) pmsStatusOutput.textContent = uiText("تعذر الاتصال بالسيرفر", "Could not reach the server");
    return null;
  }
  if (pmsStatusOutput) {
    pmsStatusOutput.dataset.touched = "true";
    const missing = Array.isArray(data.missingEnvironment) && data.missingEnvironment.length
      ? ` Missing env: ${data.missingEnvironment.join(", ")}`
      : "";
    pmsStatusOutput.textContent = `${data.provider || "mock"} / ${data.mode || "test"}: ${data.message || "Ready"}${missing}`;
  }
  return data;
}

async function savePmsAdminSettings() {
  pmsConnection = normalizePmsConnection({
    provider: pmsProvider?.value || "mock",
    mode: pmsMode?.value || "test",
    propertyId: pmsPropertyId?.value.trim() || "",
    hotelCode: pmsHotelCode?.value.trim() || hotelPathSlug(),
    enabled: Boolean(pmsEnabled?.checked)
  });
  localStorage.setItem("hotelPmsConnection", JSON.stringify(pmsConnection));
  const result = await apiSendJson("/api/pms/config", "PUT", pmsConnection);
  if (result.ok && result.data?.connection) {
    pmsConnection = normalizePmsConnection(result.data.connection);
    localStorage.setItem("hotelPmsConnection", JSON.stringify(pmsConnection));
    if (pmsStatusOutput) {
      pmsStatusOutput.dataset.touched = "true";
      pmsStatusOutput.textContent = uiText("تم حفظ إعدادات PMS", "PMS settings saved");
    }
  } else if (pmsStatusOutput) {
    pmsStatusOutput.dataset.touched = "true";
    pmsStatusOutput.textContent = result.data?.message || uiText("تعذر حفظ إعدادات PMS", "Could not save PMS settings");
  }
  renderPmsAdmin();
}
function startHeroSlider() {
  if (heroSlideTimer) window.clearInterval(heroSlideTimer);
  if (heroSlideSecondsInput) heroSlideSecondsInput.value = heroSlideSeconds;
  heroSlideTimer = window.setInterval(() => {
    if (heroImages.length > 1) {
      heroSlideIndex = (heroSlideIndex + 1) % heroImages.length;
      renderHeroSlider();
    }
  }, Math.max(2, Number(heroSlideSeconds) || 5) * 1000);
}
function renderHeroSlider() {
  if (!heroImages.length) heroImages = [...defaultHeroImages];
  heroSlideIndex = Math.min(heroSlideIndex, heroImages.length - 1);
  if (heroImageEl) heroImageEl.src = heroImages[heroSlideIndex] || defaultHeroImages[0];
  if (heroDots) {
    heroDots.innerHTML = heroImages.map((_, index) => `
      <button class="hero-dot ${index === heroSlideIndex ? "active" : ""}" type="button" data-hero-slide="${index}" aria-label="${uiText("صورة", "Slide")} ${index + 1}"></button>
    `).join("");
  }
}

function renderHeroAdmin() {
  if (!heroAdminPreview) return;
  heroAdminPreview.innerHTML = heroImages.map((src, index) => `
    <div class="hero-admin-item">
      <img src="${src}" alt="${uiText("صورة السلايدر", "Slider image")} ${index + 1}">
      <button type="button" data-hero-delete="${index}">${uiText("حذف الصورة", "Delete image")}</button>
    </div>
  `).join("");
}

async function readImageFiles(input) {
  const files = Array.from(input?.files || []);
  const images = [];
  for (const file of files) {
    images.push(await readLogoFile(file));
  }
  return images;
}
function applyTheme() {
  const root = document.documentElement;
  root.style.setProperty("--brand", hotelTheme.brand || defaultTheme.brand);
  root.style.setProperty("--brand-dark", hotelTheme.brandDark || defaultTheme.brandDark);
  root.style.setProperty("--accent", hotelTheme.accent || defaultTheme.accent);
  root.style.setProperty("--ink", hotelTheme.ink || defaultTheme.ink);
  root.style.setProperty("--muted", hotelTheme.muted || defaultTheme.muted);
  root.style.setProperty("--line", hotelTheme.line || defaultTheme.line);
  root.style.setProperty("--panel", hotelTheme.panel || defaultTheme.panel);
  root.style.setProperty("--soft", hotelTheme.soft || defaultTheme.soft);
  root.style.setProperty("--danger", hotelTheme.danger || defaultTheme.danger);
  document.body.style.background = hotelTheme.page || defaultTheme.page;
  document.body.style.fontFamily = hotelTheme.font || defaultTheme.font;
}

function renderThemeControls() {
  Object.entries(themeInputs).forEach(([key, input]) => {
    if (input) input.value = hotelTheme[key] || defaultTheme[key];
  });
}

function readThemeControls() {
  const next = { ...hotelTheme };
  Object.entries(themeInputs).forEach(([key, input]) => {
    if (input?.value) next[key] = input.value;
  });
  return { ...defaultTheme, ...next };
}
function renderLogo() {
  document.querySelectorAll("[data-i18n=\"hotelName\"]").forEach((el) => {
    el.textContent = currentHotelName();
  });
  if (adminHotelNameAr) adminHotelNameAr.value = hotelName.ar || "";
  if (adminHotelNameEn) adminHotelNameEn.value = hotelName.en || "";
  if (hotelLogoEl) {
    const ownerView = getRole() === "superadmin";
    hotelLogoEl.hidden = ownerView || !hotelLogo;
    if (!ownerView && hotelLogo) hotelLogoEl.src = hotelLogo;
  }
  if (adminLogoPreview) {
    adminLogoPreview.hidden = !hotelLogo;
    if (hotelLogo) adminLogoPreview.src = hotelLogo;
  }
  if (adminLogoEmpty) adminLogoEmpty.hidden = !!hotelLogo;
}

function readLogoFile(file) {
  return new Promise((resolve, reject) => {
    const reader = new FileReader();
    reader.onload = () => resolve(reader.result);
    reader.onerror = reject;
    reader.readAsDataURL(file);
  });
}
function setLanguage(lang) {
  state.lang = lang;
  localStorage.removeItem("hotelLang");
  localStorage.removeItem(`hotelLang:${hotelPathSlug()}`);
  document.documentElement.lang = lang;
  document.documentElement.dir = lang === "ar" ? "rtl" : "ltr";
  document.querySelector("#langToggle").textContent = lang === "ar" ? "EN" : "AR";
  document.querySelectorAll("[data-i18n]").forEach((el) => {
    el.textContent = t(el.dataset.i18n);
  });
  document.querySelectorAll("[data-i18n-placeholder]").forEach((el) => {
    el.placeholder = t(el.dataset.i18nPlaceholder);
  });
  render();
  applyStaticLanguage();
}


function estimateText(minutes) {
  return state.lang === "ar" ? `وقت الإنجاز المتوقع: ${minutes} دقيقة` : `Estimated completion: ${minutes} min`;
}

function orderDueAt(order, service) {
  if (order.dueAt) return new Date(order.dueAt);
  const createdAt = order.createdAt ? new Date(order.createdAt) : new Date();
  return new Date(createdAt.getTime() + serviceEstimate(service) * 60000);
}

function dueTimeText(order, service) {
  const dueAt = orderDueAt(order, service);
  const time = dueAt.toLocaleTimeString(state.lang === "ar" ? "ar-AE" : "en-US", { hour: "2-digit", minute: "2-digit" });
  return state.lang === "ar" ? `المهلة / وقت التسليم: ${time}` : `Deadline / delivery: ${time}`;
}

function countdownText(order, service) {
  if (order.status === "done") return state.lang === "ar" ? "اكتمل الطلب" : "Completed";
  const diff = orderDueAt(order, service).getTime() - Date.now();
  if (diff <= 0) return state.lang === "ar" ? "تأخر عن المهلة" : "Overdue";
  const totalSeconds = Math.floor(diff / 1000);
  const hours = Math.floor(totalSeconds / 3600);
  const minutes = Math.floor((totalSeconds % 3600) / 60);
  const seconds = totalSeconds % 60;
  const value = [hours, minutes, seconds].map((part) => String(part).padStart(2, "0")).join(":");
  return state.lang === "ar" ? `المتبقي: ${value}` : `Remaining: ${value}`;
}

function deadlineMarkup(order, service) {
  const late = isOrderDelayed(order, service);
  return `<p class="estimate-line deadline-line ${late ? "late" : ""}"><span>${dueTimeText(order, service)}</span><b>${countdownText(order, service)}</b></p>`;
}

function serviceEstimate(service) {
  return Number(service.estimateMinutes) || 30;
}

function minutesFromClock(value) {
  if (!value || !/^\d{2}:\d{2}$/.test(value)) return null;
  const [hours, minutes] = value.split(":").map(Number);
  return (hours * 60) + minutes;
}

function serviceAvailability(service, now = new Date()) {
  const from = minutesFromClock(service.availableFrom);
  const to = minutesFromClock(service.availableTo);
  if (from === null && to === null) return { available: true, label: uiText("متاحة دائماً", "Always available") };
  const current = now.getHours() * 60 + now.getMinutes();
  const start = from ?? 0;
  const end = to ?? 1439;
  const available = start <= end ? current >= start && current <= end : current >= start || current <= end;
  const range = `${service.availableFrom || "00:00"} - ${service.availableTo || "23:59"}`;
  return {
    available,
    label: available ? uiText(`متاحة الآن: ${range}`, `Available now: ${range}`) : uiText(`غير متاحة الآن: ${range}`, `Unavailable now: ${range}`)
  };
}

function isServiceAvailable(service) {
  return serviceAvailability(service).available;
}

function isClosedStatus(status) {
  return ["done", "cancelled", "rejected"].includes(status);
}

function isOrderDelayed(order, service) {
  return !isClosedStatus(order.status) && Date.now() > orderDueAt(order, service).getTime();
}

function delayMarkup(order, service) {
  if (!isOrderDelayed(order, service)) return "";
  return `<p class="delay-warning">تنبيه: الطلب سيتأخر عن الوقت المتوقع</p>`;
}
function statusLabel(status) {
  if (status === "progress") return t("progress");
  if (status === "done") return t("done");
  if (status === "cancelled") return t("cancelled");
  if (status === "rejected") return t("rejected");
  return t("new");
}

function renderRoomMode() {
  if (!roomModeStatus) return;
  const modes = JSON.parse(localStorage.getItem("hotelRoomModes") || "{}");
  const mode = modes[guestRoomSelect?.value || currentRoom] || "normal";
  const label = mode === "dnd" ? t("dndMode") : mode === "cleaning" ? t("cleaningMode") : t("modeNormal");
  roomModeStatus.textContent = `${t("currentMode")}: ${label}`;
}

function offerName(offer) {
  return state.lang === "ar" ? offer.ar : offer.en;
}

function renderOffers() {
  if (!todayOffersList) return;
  todayOffersList.innerHTML = hotelOffers.length
    ? hotelOffers.map((offer) => '<button class="offer-pill" type="button" data-offer-service="' + offer.serviceId + '">' + escapeHtml(offerName(offer)) + '</button>').join("")
    : '<p class="empty-state">' + uiText("لا توجد عروض اليوم", "No offers today") + '</p>';
}

function renderServices() {
  serviceGrid.innerHTML = services.map((service) => {
    const availability = serviceAvailability(service);
    return `
      <button class="service-card ${service.id === state.selectedService ? "active" : ""} ${availability.available ? "" : "unavailable"}" type="button" data-service="${service.id}" ${availability.available ? "" : "disabled"}>
        <span class="service-icon" aria-hidden="true">${icons[service.icon]}</span>
        <strong>${serviceName(service)}</strong>
        <span>${serviceDesc(service)}</span>
        <span class="service-time">${estimateText(serviceEstimate(service))}</span>
        <span class="availability-line">${availability.label}</span>
      </button>
    `;
  }).join("");
  const selected = services.find((service) => service.id === state.selectedService) || services[0];
  if (selected.id !== state.selectedService) state.selectedService = selected.id;
  selectedServiceName.textContent = serviceName(selected);
  const availability = serviceAvailability(selected);
  selectedEstimate.textContent = `${estimateText(serviceEstimate(selected))} - ${availability.label}`;
}

function renderServiceOptions() {
  const selectedService = services.find((service) => service.id === state.selectedService) || services[0];
  if (!isServiceAvailable(selectedService)) {
    serviceOptionsEl.innerHTML = `<p class="empty-state">${uiText("هذه الخدمة غير متاحة الآن", "This service is unavailable now")}</p>`;
    return;
  }
  const groups = serviceOptions[state.selectedService] || [];
  serviceOptionsEl.innerHTML = groups.map((group) => `
    <fieldset class="option-group">
      <legend>${localized(group, "titleAr", "titleEn")}</legend>
      <div class="option-items">
        ${group.items.map((item) => `
          <label class="check-option">
            <input type="checkbox" name="service-option" value="${item.id}" data-ar="${escapeHtml(item.ar)}" data-en="${escapeHtml(item.en)}" data-price="${Number(item.price) || 0}">
            <span>${localized(item)}</span>
            <b>${formatMoney(item.price)}</b>
            <span class="quantity-control">
              <small>${state.lang === "ar" ? "العدد" : "Qty"}</small>
              <input type="number" min="1" step="1" value="1" data-quantity-for="${item.id}" aria-label="${state.lang === "ar" ? "العدد" : "Quantity"}">
            </span>
          </label>
        `).join("")}
      </div>
    </fieldset>
  `).join("");
}

function getSelectedItems() {
  return Array.from(document.querySelectorAll('input[name="service-option"]:checked')).map((input) => {
    const quantityInput = document.querySelector(`[data-quantity-for="${CSS.escape(input.value)}"]`);
    return {
      id: input.value,
      ar: input.dataset.ar,
      en: input.dataset.en,
      price: Number(input.dataset.price) || 0,
      quantity: Math.max(1, Number(quantityInput?.value) || 1)
    };
  });
}

function formatOrderDetails(order, service) {
  const items = Array.isArray(order.items) ? order.items : [];
  const names = items.map((item) => {
    const quantity = Number(item.quantity) || 1;
    const lineTotal = (Number(item.price) || 0) * quantity;
    const quantityText = quantity > 1 ? ` × ${quantity}` : "";
    return `${state.lang === "ar" ? item.ar : item.en}${quantityText} (${formatMoney(lineTotal)})`;
  }).filter(Boolean);
  const parts = [];
  if (names.length) parts.push(`${t("selectedItems")}: ${names.join("، ")}`);
  if (order.details) parts.push(`${t("notes")}: ${escapeHtml(order.details)}`);
  return parts.length ? parts.join(" | ") : serviceDesc(service);
}

function chargeLabel(value) {
  return value === "account" ? t("chargeAccount") : t("chargeRoom");
}

function orderTotalMarkup(order) {
  const total = order.total ?? calculateTotal(order.items);
  if (!total) return "";
  return `<p class="price-line">${t("orderTotal")}: ${formatMoney(total)}</p>`;
}

function reportMetaMarkup(order) {
  if (!order.internalReport) return "";
  const image = order.reportImage ? '<a class="report-image-link" href="' + escapeHtml(order.reportImage) + '" target="_blank" rel="noreferrer"><img src="' + escapeHtml(order.reportImage) + '" alt="' + t("internalReport") + '"></a>' : "";
  return '<div class="report-meta"><span class="report-badge">' + t("internalReport") + '</span>'
    + (order.reportPriorityLabel ? '<p><b>' + t("reportPriority") + ':</b> ' + escapeHtml(order.reportPriorityLabel) + '</p>' : "")
    + (order.reportLocation ? '<p><b>' + t("reportLocation") + ':</b> ' + escapeHtml(order.reportLocation) + '</p>' : "")
    + (order.reporterName ? '<p><b>' + t("reporterName") + ':</b> ' + escapeHtml(order.reporterName) + '</p>' : "")
    + image
    + '</div>';
}

function orderFeedbackMarkup(order) {
  const note = order.staffNote ? '<p class="staff-note">' + escapeHtml(order.staffNote) + '</p>' : "";
  const stars = order.rating ? "★".repeat(Number(order.rating) || 0) : "";
  const rating = order.rating ? '<p class="rating-line">' + stars + (order.ratingComment ? ' - ' + escapeHtml(order.ratingComment) : "") + '</p>' : "";
  return note + rating;
}

function senderLabel(sender) {
  if (sender === "guest") return t("guestSender");
  if (sender === "admin") return t("adminSender");
  return t("staffSender");
}

function orderChatMarkup(order, compact = false) {
  const messages = Array.isArray(order.messages) ? order.messages : [];
  const body = messages.length
    ? messages.slice(-4).map((message) => '<div class="chat-message ' + escapeHtml(message.sender || "staff") + '"><strong>' + senderLabel(message.sender) + '</strong><span>' + escapeHtml(message.text) + '</span><small>' + new Date(message.createdAt || order.createdAt).toLocaleString(state.lang === "ar" ? "ar-AE" : "en-US") + '</small></div>').join("")
    : '<p class="chat-empty">' + t("noMessages") + '</p>';
  const sender = compact ? "guest" : (getRole() === "admin" ? "admin" : "staff");
  const draft = chatDrafts[order.id] || "";
  const action = '<div class="chat-compose"><input type="text" data-chat-input="' + order.id + '" value="' + escapeHtml(draft) + '" placeholder="' + t("messagePlaceholder") + '"><button class="status-button chat-send-button" type="button" data-chat-order="' + order.id + '" data-chat-sender="' + sender + '">' + t("sendMessage") + '</button></div>';
  return '<section class="order-chat"><h4>' + t("chatTitle") + '</h4>' + body + action + '</section>';
}

function addOrderMessage(order, sender, text) {
  if (!order || !text.trim()) return;
  if (!Array.isArray(order.messages)) order.messages = [];
  order.messages.push({ sender, text: text.trim(), createdAt: new Date().toISOString() });
  order.updatedAt = new Date().toISOString();
  saveOrder(order);
  render();
  showToast(t("messageSent"));
}


function orderAssignmentMarkup(order) {
  const assigned = order.assignedTo ? `<p class="assignment-line">${uiText("استلم الطلب", "Assigned to")}: <b>${escapeHtml(order.assignedTo)}</b></p>` : "";
  const completed = order.completedBy ? `<p class="assignment-line">${uiText("أنهى الطلب", "Completed by")}: <b>${escapeHtml(order.completedBy)}</b></p>` : "";
  return assigned + completed;
}

function orderMarkup(order, compact = false) {
  const service = services.find((item) => item.id === order.serviceId) || services[0];
  const statusClass = order.status === "done" ? "done" : order.status === "progress" ? "progress" : order.status === "cancelled" || order.status === "rejected" ? "closed" : "";
  const canAct = !isClosedStatus(order.status);
  const staffActions = compact || !staffCanChangeOrderStatus() ? "" : '<div class="order-actions">'
    + (canAct ? '<button class="status-button" type="button" data-status="progress" data-order="' + order.id + '">' + t("start") + '</button>' : "")
    + (canAct ? '<button class="status-button" type="button" data-status="done" data-order="' + order.id + '">' + t("complete") + '</button>' : "")
    + (canAct ? '<button class="status-button danger" type="button" data-status="rejected" data-order="' + order.id + '">' + t("reject") + '</button>' : "")
    + '</div>';
  const guestActions = compact ? '<div class="order-actions guest-order-actions">'
    + (order.status === "new" ? '<button class="status-button danger" type="button" data-guest-cancel="' + order.id + '">' + t("cancel") + '</button>' : "")
    + (order.status === "done" && !order.rating ? '<button class="status-button" type="button" data-rate-order="' + order.id + '">' + t("rateService") + '</button>' : "")
    + '</div>' : "";
  const room = compact ? "" : '<span class="room-chip">' + order.room + '</span>';
  return '<article class="order-card ' + (order.justArrived ? "new-arrival" : "") + '">'
    + room
    + '<div class="order-main">'
    + '<strong>' + serviceName(service) + '</strong>'
    + '<p>' + formatOrderDetails(order, service) + '</p>'
    + orderTotalMarkup(order)
    + '<p class="estimate-line">' + estimateText(order.estimateMinutes || serviceEstimate(service)) + '</p>'
    + deadlineMarkup(order, service)
    + delayMarkup(order, service)
    + orderFeedbackMarkup(order)
    + reportMetaMarkup(order)
    + orderAssignmentMarkup(order)
    + orderChatMarkup(order, compact)
    + '<p class="charge-line">' + t("chargeInfo") + ': ' + chargeLabel(order.chargeTo) + ' - ' + order.room + '</p>'
    + '<p>' + new Date(order.createdAt).toLocaleString(state.lang === "ar" ? "ar-AE" : "en-US") + '</p>'
    + '</div>'
    + '<span class="status-chip ' + statusClass + '">' + statusLabel(order.status) + '</span>'
    + staffActions
    + guestActions
    + '</article>';
}
function orderSearchText(order) {
  const service = services.find((item) => item.id === order.serviceId) || services[0];
  return [
    order.room,
    service.nameAr,
    service.nameEn,
    serviceDesc(service),
    formatOrderDetails(order, service),
    order.details,
    statusLabel(order.status)
  ].filter(Boolean).join(" ").toLowerCase();
}

function staffOrderRank(order) {
  const service = services.find((item) => item.id === order.serviceId) || services[0];
  if (isOrderDelayed(order, service)) return 0;
  if (order.status === "new") return 1;
  if (order.status === "progress") return 2;
  if (order.status === "rejected" || order.status === "cancelled") return 4;
  if (order.status === "done") return 5;
  return 3;
}

function sortStaffOrders(orders) {
  return [...orders].sort((a, b) => {
    const rank = staffOrderRank(a) - staffOrderRank(b);
    if (rank) return rank;
    const aService = services.find((item) => item.id === a.serviceId) || services[0];
    const bService = services.find((item) => item.id === b.serviceId) || services[0];
    const aDue = orderDueAt(a, aService).getTime();
    const bDue = orderDueAt(b, bService).getTime();
    if (!isClosedStatus(a.status) || !isClosedStatus(b.status)) return aDue - bDue;
    return new Date(b.updatedAt || b.createdAt).getTime() - new Date(a.updatedAt || a.createdAt).getTime();
  });
}

function staffOrderSection(title, orders, options = {}) {
  const count = orders.length;
  const body = count ? orders.map((order) => orderMarkup(order)).join("") : `<div class="empty-state">${t("empty")}</div>`;
  if (options.collapsible) {
    return `<details class="staff-order-section archive-section">
      <summary><span>${title}</span><b>${count}</b></summary>
      <p class="archive-hint">${t("archiveHint")}</p>
      <div class="order-list">${body}</div>
    </details>`;
  }
  return `<section class="staff-order-section">
    <div class="staff-section-title"><h3>${title}</h3><b>${count}</b></div>
    <div class="order-list">${body}</div>
  </section>`;
}
function staffRoomBoardMarkup(orders) {
  const groups = new Map();
  orders.forEach((order) => {
    const room = String(order.room || "");
    if (!room) return;
    if (!groups.has(room)) groups.set(room, []);
    groups.get(room).push(order);
  });

  const roomCards = [...groups.entries()].map(([room, roomOrders]) => {
    const sorted = sortStaffOrders(roomOrders);
    const activeCount = roomOrders.filter((order) => !isClosedStatus(order.status)).length;
    const lateCount = roomOrders.filter((order) => {
      const service = services.find((item) => item.id === order.serviceId) || services[0];
      return isOrderDelayed(order, service);
    }).length;
    const firstOrder = sorted[0];
    const firstService = services.find((item) => item.id === firstOrder?.serviceId) || services[0];
    return {
      room,
      activeCount,
      lateCount,
      total: roomOrders.length,
      latestTime: new Date(firstOrder?.updatedAt || firstOrder?.createdAt || Date.now()).getTime(),
      markup: `<button class="staff-room-card ${state.staffRoom === room ? "active" : ""} ${lateCount ? "has-late" : activeCount ? "has-active" : ""}" type="button" data-staff-room-card="${escapeHtml(room)}">
        <span class="room-card-alert">${lateCount ? t("lateCount") : activeCount ? t("activeCount") : statusLabel(firstOrder?.status || "done")}</span>
        <strong>${uiText("غرفة", "Room")} ${escapeHtml(room)}</strong>
        <small>${escapeHtml(serviceName(firstService))}</small>
        <span class="room-card-counts"><b>${activeCount}</b> ${t("activeCount")}${lateCount ? ` <em>${lateCount} ${t("lateCount")}</em>` : ""}</span>
      </button>`
    };
  }).sort((a, b) => {
    if (b.lateCount !== a.lateCount) return b.lateCount - a.lateCount;
    if (b.activeCount !== a.activeCount) return b.activeCount - a.activeCount;
    return b.latestTime - a.latestTime;
  });

  const selected = state.staffRoom
    ? `<div class="selected-room-strip"><span>${t("selectedRoomOrders")}: <b>${escapeHtml(state.staffRoom)}</b></span><button class="status-button" type="button" data-clear-staff-room>${t("clearRoom")}</button></div>`
    : "";
  const body = roomCards.length
    ? `<div class="staff-room-grid">${roomCards.map((item) => item.markup).join("")}</div>`
    : `<div class="empty-state">${t("empty")}</div>`;

  return `<section class="staff-room-board">
    <div class="staff-room-board-head"><div><h3>${t("roomBoardTitle")}</h3><p>${t("roomBoardHint")}</p></div><b>${roomCards.length}</b></div>
    ${selected}
    ${body}
  </section>`;
}
function renderOrders() {
  const roomOrders = state.orders.filter((order) => order.room === guestRoomSelect.value);
  if (getRole() === "guest") {
    roomOrders.forEach((order) => {
      const service = services.find((item) => item.id === order.serviceId) || services[0];
      if (isOrderDelayed(order, service) && !delayedAlertIds.has(order.id)) {
        delayedAlertIds.add(order.id);
        localStorage.setItem("hotelDelayedAlertIds", JSON.stringify([...delayedAlertIds]));
        showToast(uiText("تنبيه: طلبك سيتأخر عن الوقت المتوقع", "Alert: your request will be delayed"));
      }
    });
  }
  guestOrders.innerHTML = roomOrders.length ? roomOrders.map((order) => orderMarkup(order, true)).join("") : `<div class="empty-state">${t("empty")}</div>`;

  const staffDepartmentId = getRole() === "staff" && !staffCanViewAllDepartments() ? getStaffDepartmentId() : state.filter;
  const search = (state.staffSearch || "").trim().toLowerCase();
  let filtered = staffDepartmentId === "all"
    ? [...state.orders]
    : state.orders.filter((order) => orderBelongsToDepartment(order, staffDepartmentId));

  if (state.staffStatus && !["all", "active"].includes(state.staffStatus)) {
    filtered = state.staffStatus === "late"
      ? filtered.filter((order) => {
        const service = services.find((item) => item.id === order.serviceId) || services[0];
        return isOrderDelayed(order, service);
      })
      : filtered.filter((order) => order.status === state.staffStatus);
  }

  if (state.staffDate) {
    filtered = filtered.filter((order) => (order.createdAt || "").slice(0, 10) === state.staffDate);
  }

  if (search) {
    filtered = filtered.filter((order) => orderSearchText(order).includes(search));
  }

  const wantsOnlyActive = state.staffStatus === "active";
  const wantsAll = state.staffStatus === "all";
  const roomBoardSource = wantsOnlyActive ? filtered.filter((order) => !isClosedStatus(order.status)) : filtered;
  const roomBoard = staffRoomBoardMarkup(roomBoardSource);

  if (state.staffRoom) {
    const roomQuery = String(state.staffRoom);
    filtered = rooms.includes(roomQuery)
      ? filtered.filter((order) => String(order.room) === roomQuery)
      : filtered.filter((order) => String(order.room).includes(roomQuery));
  }

  const active = sortStaffOrders(filtered.filter((order) => !isClosedStatus(order.status)));
  const closed = sortStaffOrders(filtered.filter((order) => isClosedStatus(order.status)));

  if (wantsOnlyActive) {
    staffOrders.innerHTML = roomBoard + staffOrderSection(state.staffRoom ? `${t("selectedRoomOrders")} ${state.staffRoom}` : t("activeRequests"), active);
    return;
  }

  if (wantsAll) {
    staffOrders.innerHTML = roomBoard + staffOrderSection(state.staffRoom ? `${t("selectedRoomOrders")} ${state.staffRoom}` : t("activeRequests"), active) + staffOrderSection(t("closedArchive"), closed, { collapsible: true });
    return;
  }

  const sorted = sortStaffOrders(filtered);
  staffOrders.innerHTML = roomBoard + (sorted.length ? sorted.map((order) => orderMarkup(order)).join("") : `<div class="empty-state">${t("empty")}</div>`);
}


function departmentName(department) {
  return state.lang === "ar" ? department.ar : department.en;
}

function serviceOptionLabel(service) {
  return state.lang === "ar" ? service.nameAr : service.nameEn;
}

function makeId(prefix, value) {
  return `${prefix}_${String(value).trim().toLowerCase().replace(/[^a-z0-9]+/g, "_").replace(/^_|_$/g, "") || Date.now()}`;
}

function renderStaffFilters() {
  if (getRole() === "staff" && !staffCanViewAllDepartments()) {
    const department = getStaffDepartment();
    const permission = staffRoleLabel(getStaffPermission());
    state.filter = department.id;
    staffFilters.innerHTML = `
      <h2>${permission}</h2>
      <div class="staff-department-card">
        <span>${uiText("الطلبات المعروضة لهذا القسم فقط", "Only this department's requests are shown")}</span>
        <strong>${departmentName(department)}</strong>
      </div>
    `;
    return;
  }
  const title = getRole() === "staff" ? staffRoleLabel(getStaffPermission()) : t("filters");
  staffFilters.innerHTML = `<h2>${title}</h2>` + departments.map((department) => `
    <button class="filter ${state.filter === department.id ? "active" : ""}" type="button" data-filter="${department.id}">${departmentName(department)}</button>
  `).join("");
}

function renderOffersAdmin() {
  if (!offerAdminList) return;
  offerAdminList.innerHTML = hotelOffers.length ? hotelOffers.map((offer) => {
    const service = services.find((item) => item.id === offer.serviceId);
    return `
      <div class="admin-list-row">
        <strong>${escapeHtml(offerName(offer))}</strong>
        <span>${service ? serviceName(service) : offer.serviceId}</span>
        <button type="button" data-offer-delete="${offer.id}">${uiText("حذف", "Delete")}</button>
      </div>
    `;
  }).join("") : `<p class="empty-state">${uiText("لا توجد عروض", "No offers")}</p>`;
}
function renderAdminControls() {
  const hotel = encodeURIComponent(hotelPathSlug());
  const loginLinks = document.querySelectorAll(".login-links a");
  if (loginLinks[0]) loginLinks[0].href = `/hotel/${hotel}/guest`;
  if (loginLinks[1]) loginLinks[1].href = `/hotel/${hotel}/staff`;
  if (loginLinks[2]) loginLinks[2].href = `/hotel/${hotel}/admin`;
  const reportLink = document.querySelector("#internalReportLink");
  if (reportLink) reportLink.href = `/hotel/${hotel}/report`;
  if (!adminOptionService) return;
  const departmentOptions = departments.filter((department) => department.id !== "all").map((department) => `
    <option value="${department.id}">${departmentName(department)}</option>
  `).join("");
  adminServiceDepartment.innerHTML = departmentOptions;
  if (adminStaffDepartment) adminStaffDepartment.innerHTML = departmentOptions;
  if (adminStaffRole) {
    adminStaffRole.innerHTML = staffRoleOptions.map((role) => `<option value="${role.id}">${staffRoleLabel(role.id)}</option>`).join("");
  }
  if (invoiceRoomSelect) {
    invoiceRoomSelect.innerHTML = rooms.map((room) => `<option value="${room}">${room}</option>`).join("");
    if (!invoiceRoomSelect.value && rooms[0]) invoiceRoomSelect.value = rooms[0];
  }
  const serviceOptionsMarkup = services.map((service) => `
    <option value="${service.id}">${serviceOptionLabel(service)}</option>
  `).join("");
  adminOptionService.innerHTML = serviceOptionsMarkup;
  if (adminOfferService) adminOfferService.innerHTML = serviceOptionsMarkup;

  roomAdminList.innerHTML = rooms.map((room) => {
    const account = ensureGuestAccount(room);
    return `
      <div class="room-account-row">
        <div class="room-account-main">
          <strong>${uiText("غرفة", "Room")} ${room}</strong>
          ${room === currentRoom ? `<span class="room-current-badge">${uiText("غرفة هذا التابلت", "This tablet room")}</span>` : ""}
        </div>
        <div class="room-account-credentials">
          <span>${uiText("يوزر", "User")}: <b>${escapeHtml(account.username)}</b></span>
          <span>${uiText("باس", "Pass")}: <b>${escapeHtml(account.password)}</b></span>
          <a href="${guestLink(room)}" target="_blank" rel="noreferrer">${uiText("رابط النزيل", "Guest link")}</a>
        </div>
        <div class="room-account-actions">
          <button type="button" data-room-current="${room}">${uiText("تعيين", "Assign")}</button>
          <button type="button" data-room-password="${room}">${uiText("تغيير كلمة المرور", "Change password")}</button>
          <button type="button" data-room-delete="${room}">${uiText("حذف", "Delete")}</button>
        </div>
      </div>
    `;
  }).join("");

  departmentAdminList.innerHTML = departments.filter((department) => department.id !== "all").map((department) => `
    <div class="admin-row">
      <strong>${departmentName(department)}</strong>
      <span>${department.id}</span>
      <button type="button" data-department-delete="${department.id}">${uiText("حذف", "Delete")}</button>
    </div>
  `).join("");

  if (staffAccountList) {
    staffAccountList.innerHTML = staffAccounts.map((account) => {
      const department = departments.find((item) => item.id === account.department);
      const presence = staffPresenceStatus(account);
      return `
        <div class="staff-account-row">
          <div class="staff-account-main">
            <strong>${escapeHtml(account.username)}</strong>
            <span>${department ? departmentName(department) : account.department}</span>
            <em class="permission-badge">${staffRoleLabel(account.role)}</em>
            <em class="presence-badge ${presence}">${presenceLabel(presence)}</em>
            <small>${t("lastSeen")}: ${escapeHtml(formatLastSeen(account))}</small>
          </div>
          <div class="staff-account-credentials">
            <span>${uiText("يوزر", "User")}: <b>${escapeHtml(account.username)}</b></span>
            <span>${uiText("باس", "Pass")}: <b>${escapeHtml(account.password)}</b></span>
            <a href="${staffLink(account)}" target="_blank" rel="noreferrer">${uiText("رابط الموظف", "Staff link")}</a>
          </div>
          <div class="staff-account-actions">
            <button type="button" data-staff-password="${escapeHtml(account.username)}">${uiText("تغيير كلمة المرور", "Change password")}</button>
            <button type="button" data-staff-delete="${escapeHtml(account.username)}">${uiText("حذف", "Delete")}</button>
          </div>
        </div>
      `;
    }).join("");
  }
}
function renderCatalogManager() {
  catalogList.innerHTML = services.map((service) => {
    const groups = serviceOptions[service.id] || [];
    const options = groups.flatMap((group) => group.items.map((item) => item));
    return `
      <article class="catalog-item admin-service-card">
        <div class="admin-card-head">
          <div>
            <strong>${serviceName(service)}</strong>
            <span>${serviceDesc(service)}</span>
            <label class="estimate-control"><span>${uiText("وقت الإنجاز بالدقائق", "Completion time in minutes")}</span><input type="number" min="1" step="1" value="${serviceEstimate(service)}" data-estimate-service="${service.id}"></label>
            <label class="estimate-control"><span>${uiText("متاحة من", "Available from")}</span><input type="time" value="${service.availableFrom || ""}" data-available-from="${service.id}"></label>
            <label class="estimate-control"><span>${uiText("متاحة إلى", "Available to")}</span><input type="time" value="${service.availableTo || ""}" data-available-to="${service.id}"></label>
            <small class="availability-admin-note">${serviceAvailability(service).label}</small>
          </div>
          <button type="button" data-estimate-save="${service.id}">${uiText("حفظ الوقت", "Save time")}</button>
          <button type="button" data-service-delete="${service.id}">${uiText("حذف الكرت", "Delete card")}</button>
        </div>
        <div class="admin-option-list">
          ${options.length ? options.map((item) => `
            <div class="admin-option-row">
              <strong>${state.lang === "ar" ? item.ar : item.en}</strong>
              <label class="price-editor">
                <span>${uiText("السعر", "Price")}</span>
                <input type="number" min="0" step="1" value="${Number(item.price) || 0}" data-price-service="${service.id}" data-price-option="${item.id}">
              </label>
              <div class="option-actions">
                <button type="button" data-price-save="${service.id}" data-option-id="${item.id}">${uiText("حفظ السعر", "Save price")}</button>
                <button type="button" data-price-zero="${service.id}" data-option-id="${item.id}">${uiText("حذف السعر", "Remove price")}</button>
                <button type="button" data-option-delete="${service.id}" data-option-id="${item.id}">${uiText("حذف الخدمة", "Delete service")}</button>
              </div>
            </div>
          `).join("") : `<p class="empty-state">${uiText("لا توجد خدمات داخل هذا الكرت", "No services inside this card")}</p>`}
        </div>
      </article>
    `;
  }).join("");
}
function refreshAdminAndSave() {
  saveConfig();
  render();
  showToast(uiText("تم حفظ التعديل", "Changes saved"));
}
function invoiceItemRows(order) {
  const service = services.find((item) => item.id === order.serviceId) || services[0];
  const items = Array.isArray(order.items) && order.items.length ? order.items : [{
    ar: service.nameAr,
    en: service.nameEn,
    price: order.total || 0,
    quantity: 1
  }];
  return items.map((item) => {
    const quantity = Number(item.quantity) || 1;
    const price = Number(item.price) || 0;
    const lineTotal = price * quantity;
    return `
      <tr>
        <td>${escapeHtml(serviceName(service))}</td>
        <td>${escapeHtml(state.lang === "ar" ? item.ar : item.en)}</td>
        <td>${quantity}</td>
        <td>${formatMoney(price)}</td>
        <td>${formatMoney(lineTotal)}</td>
      </tr>
    `;
  }).join("");
}

function renderInvoice(room = invoiceRoomSelect?.value || currentRoom) {
  if (!invoiceOutput) return;
  const roomOrders = state.orders.filter((order) => order.room === room);
  const total = roomOrders.reduce((sum, order) => sum + (Number(order.total) || calculateTotal(order.items)), 0);
  const rows = roomOrders.map((order) => invoiceItemRows(order)).join("");
  const date = new Date().toLocaleString(state.lang === "ar" ? "ar-AE" : "en-US");
  invoiceOutput.innerHTML = `
    <section class="invoice-print-area">
      <div class="invoice-head">
        <div class="invoice-brand">
          ${hotelLogo ? `<img src="${hotelLogo}" alt="${uiText("لوغو الفندق", "Hotel logo")}">` : ""}
          <div>
            <h2>${uiText("فاتورة غرفة", "Room invoice")} ${escapeHtml(room)}</h2>
            <p>${escapeHtml(currentHotelName())}</p>
          </div>
        </div>
        <div>
          <strong>${date}</strong>
          <p>${uiText("عدد الطلبات", "Requests")}: ${roomOrders.length}</p>
        </div>
      </div>
      ${roomOrders.length ? `
        <table class="invoice-table">
          <thead>
            <tr>
              <th>${uiText("القسم / الخدمة", "Department / service")}</th>
              <th>${uiText("البند", "Item")}</th>
              <th>${uiText("العدد", "Qty")}</th>
              <th>${uiText("السعر", "Price")}</th>
              <th>${uiText("المجموع", "Total")}</th>
            </tr>
          </thead>
          <tbody>${rows}</tbody>
        </table>
        <div class="invoice-total">
          <span>${uiText("المجموع النهائي", "Final total")}</span>
          <strong>${formatMoney(total)}</strong>
        </div>
      ` : `<p class="empty-state">${uiText("لا توجد طلبات على هذه الغرفة", "No requests for this room")}</p>`}
      <div class="invoice-signature">
        <span>${uiText("توقيع الموظف", "Staff signature")}</span>
        <span>${uiText("توقيع النزيل", "Guest signature")}</span>
      </div>
    </section>
  `;
}
function csvEscape(value) {
  const text = String(value ?? "");
  return /[",\n]/.test(text) ? `"${text.replace(/"/g, '""')}"` : text;
}

function downloadTextFile(filename, content, type = "text/csv;charset=utf-8") {
  const blob = new Blob(["\ufeff" + content], { type });
  const url = URL.createObjectURL(blob);
  const link = document.createElement("a");
  link.href = url;
  link.download = filename;
  document.body.appendChild(link);
  link.click();
  link.remove();
  URL.revokeObjectURL(url);
}

function orderReportRows(orders) {
  return orders.map((order) => {
    const service = services.find((item) => item.id === order.serviceId) || services[0];
    return [
      order.id,
      order.room,
      serviceName(service),
      statusLabel(order.status),
      formatOrderDetails(order, service).replace(/<[^>]*>/g, ""),
      Number(order.total) || calculateTotal(order.items),
      order.chargeTo,
      order.createdAt,
      order.updatedAt || ""
    ];
  });
}

function exportOrdersReport(scope = "all") {
  const today = new Date().toISOString().slice(0, 10);
  const rows = scope === "today" ? state.orders.filter((order) => (order.createdAt || "").slice(0, 10) === today) : state.orders;
  const header = ["Order ID", "Room", "Service", "Status", "Details", "Total", "Billing", "Created", "Updated"];
  const csv = [header, ...orderReportRows(rows)].map((row) => row.map(csvEscape).join(",")).join("\n");
  downloadTextFile(`hotel-${scope}-orders-${today}.csv`, csv);
  addAudit("export_report", scope === "today" ? "طلبات اليوم" : "كل الطلبات");
}

function exportServicesReport() {
  const counts = new Map();
  state.orders.forEach((order) => {
    const service = services.find((item) => item.id === order.serviceId) || services[0];
    const current = counts.get(order.serviceId) || { service: serviceName(service), count: 0, total: 0 };
    current.count += 1;
    current.total += Number(order.total) || calculateTotal(order.items);
    counts.set(order.serviceId, current);
  });
  const header = ["Service", "Requests", "Total"];
  const rows = [...counts.values()].sort((a, b) => b.count - a.count).map((item) => [item.service, item.count, item.total]);
  const csv = [header, ...rows].map((row) => row.map(csvEscape).join(",")).join("\n");
  downloadTextFile(`hotel-services-report-${new Date().toISOString().slice(0, 10)}.csv`, csv);
  addAudit("export_report", "تقرير الخدمات الأكثر طلباً");
}

function auditActionLabel(action) {
  const labels = {
    export_report: ["تصدير تقرير", "Export report"],
    download_qr: ["تنزيل QR", "Download QR"],
    print_qr: ["طباعة QR", "Print QR"],
    create_order: ["إنشاء طلب", "Create order"],
    add_room: ["إضافة غرفة", "Add room"],
    delete_room: ["حذف غرفة", "Delete room"],
    add_service_card: ["إضافة كرت خدمة", "Add service card"],
    add_service_option: ["إضافة خدمة", "Add service option"],
    add_department: ["إضافة قسم", "Add department"],
    add_staff: ["إضافة موظف", "Add staff"],
    delete_staff: ["حذف موظف", "Delete staff"],
    delete_service_card: ["حذف كرت خدمة", "Delete service card"],
    delete_service_option: ["حذف خدمة", "Delete service option"],
    remove_price: ["حذف سعر", "Remove price"],
    save_price: ["حفظ سعر", "Save price"]
  };
  const label = labels[action];
  return label ? uiText(label[0], label[1]) : action;
}

function auditDetailsLabel(details = "") {
  const translations = {
    "طلبات اليوم": "Today's requests",
    "كل الطلبات": "All requests",
    "تقرير الخدمات الأكثر طلباً": "Most requested services report",
    "تقرير الأكثر طلباً": "Most requested report",
    "تقرير الأكثر طلبا": "Most requested report"
  };
  if (state.lang === "en" && translations[details]) return translations[details];
  return details;
}
function renderAuditLog() {
  if (!auditList) return;
  auditList.innerHTML = auditLog.length ? auditLog.slice(0, 40).map((entry) => `
    <div class="audit-row">
      <strong>${escapeHtml(auditActionLabel(entry.action))}</strong>
      <span>${escapeHtml(auditDetailsLabel(entry.details || ""))}</span>
      <small>${escapeHtml(entry.actor || "system")} - ${new Date(entry.createdAt).toLocaleString(state.lang === "ar" ? "ar-AE" : "en-US")}</small>
    </div>
  `).join("") : `<p class="empty-state">${uiText("لا يوجد نشاط بعد", "No activity yet")}</p>`;
}

function exportAuditLog() {
  const header = ["Action", "Details", "Actor", "Created"];
  const rows = auditLog.map((entry) => [entry.action, entry.details || "", entry.actor || "", entry.createdAt]);
  const csv = [header, ...rows].map((row) => row.map(csvEscape).join(",")).join("\n");
  downloadTextFile(`hotel-audit-log-${new Date().toISOString().slice(0, 10)}.csv`, csv);
}

function qrImageUrl(room) {
  return `https://api.qrserver.com/v1/create-qr-code/?size=220x220&data=${encodeURIComponent(guestLink(room))}`;
}

function renderQrTool() {
  if (!qrRoomSelect || !qrPreview) return;
  const current = qrRoomSelect.value || rooms[0] || currentRoom;
  qrRoomSelect.innerHTML = rooms.map((room) => `<option value="${room}" ${room === current ? "selected" : ""}>${room}</option>`).join("");
  const room = qrRoomSelect.value || current;
  const link = guestLink(room);
  qrPreview.innerHTML = `
    <img src="${qrImageUrl(room)}" alt="QR room ${escapeHtml(room)}">
    <strong>${uiText("غرفة", "Room")} ${escapeHtml(room)}</strong>
    <a href="${link}" target="_blank" rel="noreferrer">${escapeHtml(link)}</a>
  `;
}

function downloadQr() {
  const room = qrRoomSelect?.value || rooms[0] || currentRoom;
  const link = document.createElement("a");
  link.href = qrImageUrl(room);
  link.download = `room-${room}-qr.png`;
  document.body.appendChild(link);
  link.click();
  link.remove();
  addAudit("download_qr", `Room ${room}`);
}

function printQr() {
  const room = qrRoomSelect?.value || rooms[0] || currentRoom;
  const win = window.open("", "_blank");
  if (!win) return;
  win.document.write(`<!doctype html><title>Room ${room} QR</title><body style="font-family:Arial;text-align:center;padding:30px"><h1>Room ${room}</h1><img src="${qrImageUrl(room)}" style="width:260px;height:260px"><p>${guestLink(room)}</p><script>window.onload=()=>window.print()<\/script></body>`);
  win.document.close();
  addAudit("print_qr", `Room ${room}`);
}
function invoiceFileName(room = invoiceRoomSelect?.value || currentRoom) {
  const date = new Date().toISOString().slice(0, 10);
  return `invoice-room-${String(room).replace(/[^a-z0-9_-]/gi, "")}-${date}.html`;
}

function invoiceDocumentHtml() {
  renderInvoice();
  const invoice = invoiceOutput?.querySelector(".invoice-print-area");
  if (!invoice) return "";
  return `<!doctype html>
<html lang="${state.lang}" dir="${state.lang === "ar" ? "rtl" : "ltr"}">
<head>
  <meta charset="utf-8">
  <title>${uiText("فاتورة غرفة", "Room invoice")} ${escapeHtml(invoiceRoomSelect?.value || currentRoom)}</title>
  <style>
    body{font-family:Tahoma,Arial,sans-serif;margin:24px;color:#17211f;direction:${state.lang === "ar" ? "rtl" : "ltr"}}
    h2,p{margin:0}.invoice-brand{display:flex;align-items:center;gap:12px}.invoice-brand img{width:64px;height:64px;object-fit:contain;border:1px solid #d9dfdc;border-radius:8px}.invoice-print-area{display:grid;gap:14px}.invoice-head,.invoice-total,.invoice-signature{display:flex;justify-content:space-between;gap:12px}.invoice-head p{color:#66716d;margin-top:4px}.invoice-table{width:100%;border-collapse:collapse;border:1px solid #d9dfdc}.invoice-table th,.invoice-table td{padding:10px;border-bottom:1px solid #d9dfdc;text-align:start;vertical-align:top}.invoice-table th{background:#f5f7f6}.invoice-total{padding:12px;border:1px solid #d9dfdc;background:#e6f3f1;font-weight:900}.invoice-signature{margin-top:28px}.invoice-signature span{min-width:180px;padding-top:34px;border-top:1px solid #17211f;text-align:center;color:#66716d}
  </style>
</head>
<body>${invoice.outerHTML}</body>
</html>`;
}

function downloadInvoice() {
  const html = invoiceDocumentHtml();
  if (!html) return;
  const blob = new Blob([html], { type: "text/html;charset=utf-8" });
  const url = URL.createObjectURL(blob);
  const link = document.createElement("a");
  link.href = url;
  link.download = invoiceFileName();
  document.body.appendChild(link);
  link.click();
  link.remove();
  URL.revokeObjectURL(url);
  showToast(uiText("تم تنزيل الفاتورة", "Invoice downloaded"));
}

function printInvoice() {
  renderInvoice();
  document.body.classList.add("printing-invoice");
  const cleanup = () => document.body.classList.remove("printing-invoice");
  window.addEventListener("afterprint", cleanup, { once: true });
  window.print();
  window.setTimeout(cleanup, 2000);
}

function renderAdminInsights() {
  if (!adminInsights) return;
  const todayKey = new Date().toDateString();
  const todayOrders = state.orders.filter((order) => new Date(order.createdAt).toDateString() === todayKey);
  const todayRevenue = todayOrders.reduce((sum, order) => sum + (Number(order.total) || calculateTotal(order.items)), 0);
  const serviceCounts = new Map();
  todayOrders.forEach((order) => {
    const service = services.find((item) => item.id === order.serviceId) || services[0];
    const name = serviceName(service);
    serviceCounts.set(name, (serviceCounts.get(name) || 0) + 1);
  });
  const topService = Array.from(serviceCounts.entries()).sort((a, b) => b[1] - a[1])[0];
  const delayedCount = state.orders.filter((order) => {
    const service = services.find((item) => item.id === order.serviceId) || services[0];
    return !isClosedStatus(order.status) && isOrderDelayed(order, service);
  }).length;

  adminInsights.innerHTML = [
    [uiText("طلبات اليوم", "Today's requests"), todayOrders.length],
    [uiText("إيراد اليوم", "Today's revenue"), formatMoney(todayRevenue)],
    [uiText("أكثر خدمة", "Top service"), topService ? `${escapeHtml(topService[0])} (${topService[1]})` : "-"],
    [uiText("طلبات متأخرة", "Delayed requests"), delayedCount]
  ].map(([label, value]) => `<article class="insight-card"><span>${label}</span><strong>${value}</strong></article>`).join("");
}

function todayIsoDate() {
  return new Date().toISOString().slice(0, 10);
}

function addDaysIso(days) {
  const date = new Date();
  date.setDate(date.getDate() + days);
  return date.toISOString().slice(0, 10);
}

function normalizeHotelSlug(value) {
  return String(value || "")
    .trim()
    .toLowerCase()
    .replace(/[^a-z0-9]+/g, "-")
    .replace(/^-+|-+$/g, "") || `hotel-${Date.now()}`;
}

function hotelDisplayName(hotel) {
  return state.lang === "ar" ? (hotel.nameAr || hotel.nameEn || hotel.slug) : (hotel.nameEn || hotel.nameAr || hotel.slug);
}

function hotelEffectiveStatus(hotel) {
  if (hotel.status !== "active") return hotel.status || "paused";
  if (hotel.endDate && hotel.endDate < todayIsoDate()) return "expired";
  return "active";
}

function ensureDefaultHotelSubscription() {
  const existing = superHotels.find((hotel) => hotel.slug === "default");
  if (existing) {
    const shouldRename = !existing.nameAr || existing.nameAr === "الفندق الأساسي" || existing.nameEn === "Main hotel";
    if (shouldRename) {
      existing.nameAr = hotelName.ar || existing.nameAr || "الفندق الأساسي";
      existing.nameEn = hotelName.en || existing.nameEn || "Main hotel";
      existing.updatedAt = new Date().toISOString();
      localStorage.setItem("hotelSuperHotels", JSON.stringify(superHotels));
      return true;
    }
    return false;
  }
  superHotels.push({
    id: "default-hotel",
    nameAr: hotelName.ar || "الفندق الأساسي",
    nameEn: hotelName.en || "Main hotel",
    slug: "default",
    plan: "enterprise",
    allowedRooms: Math.max(rooms.length || 1, 1000),
    status: "active",
    startDate: todayIsoDate(),
    endDate: addDaysIso(365),
    adminUser: localStorage.getItem("hotelAdminUsername") || "admin",
    adminPass: localStorage.getItem("hotelAdminPassword") || "1234",
    createdAt: new Date().toISOString(),
    legacyDefault: true
  });
  localStorage.setItem("hotelSuperHotels", JSON.stringify(superHotels));
  return true;
}

function subscriptionStatusLabel(status) {
  if (status === "active") return t("subscriptionActive");
  if (status === "expired") return t("subscriptionExpired");
  return t("subscriptionPaused");
}

function hotelAdminLink(hotel) {
  return `${window.location.origin}${window.location.pathname}?role=admin&hotel=${encodeURIComponent(hotel.slug)}`;
}

function hotelGuestLinkBase(hotel) {
  return `${window.location.origin}${window.location.pathname}?role=guest&hotel=${encodeURIComponent(hotel.slug)}&room=ROOM_NUMBER`;
}

function saveSuperHotels() {
  localStorage.setItem("hotelSuperHotels", JSON.stringify(superHotels));
  saveConfig();
}

function renderSuperAdmin() {
  if (!superHotelList || !superMetrics) return;
  if (superHotelStart && !superHotelStart.value) superHotelStart.value = todayIsoDate();
  if (superHotelEnd && !superHotelEnd.value) superHotelEnd.value = addDaysIso(30);
  if (superHotelAdminUser && !superHotelAdminUser.value) superHotelAdminUser.value = "admin";
  if (superHotelAdminPass && !superHotelAdminPass.value) superHotelAdminPass.value = "1234";

  const totals = superHotels.reduce((acc, hotel) => {
    acc.total += 1;
    acc[hotelEffectiveStatus(hotel)] += 1;
    return acc;
  }, { total: 0, active: 0, paused: 0, expired: 0 });

  superMetrics.innerHTML = [
    [uiText("كل الفنادق", "All hotels"), totals.total],
    [t("subscriptionActive"), totals.active],
    [t("subscriptionPaused"), totals.paused],
    [t("subscriptionExpired"), totals.expired]
  ].map(([label, value]) => `<article class="metric mini"><span>${label}</span><strong>${value}</strong></article>`).join("");

  const query = superHotelQuery.trim().toLowerCase();
  const filtered = query
    ? superHotels.filter((hotel) => [hotel.nameAr, hotel.nameEn, hotel.slug, hotel.plan, hotel.status].filter(Boolean).join(" ").toLowerCase().includes(query))
    : superHotels;

  superHotelList.innerHTML = filtered.length ? filtered.map((hotel) => {
    const status = hotelEffectiveStatus(hotel);
    const roomText = `${Number(hotel.allowedRooms) || 0} ${uiText("غرفة", "rooms")}`;
    return `<article class="super-hotel-card ${status}">
      <div class="super-hotel-main">
        <span class="subscription-chip ${status}">${subscriptionStatusLabel(status)}</span>
        <strong>${escapeHtml(hotelDisplayName(hotel))}</strong>
        <small>${escapeHtml(hotel.slug)} - ${escapeHtml(hotel.plan || "starter")} - ${roomText}</small>
        <p>${uiText("ينتهي", "Ends")}: <b>${escapeHtml(hotel.endDate || "-")}</b></p>
        <p>${uiText("أدمن الفندق", "Hotel admin")}: <b>${escapeHtml(hotel.adminUser || "admin")}</b> / <b>${escapeHtml(hotel.adminPass || "1234")}</b></p>
      </div>
      <div class="super-links">
        <a href="${hotelAdminLink(hotel)}" target="_blank" rel="noreferrer">${uiText("رابط إدارة الفندق", "Hotel admin link")}</a>
        <button type="button" data-copy-link="${escapeHtml(hotelAdminLink(hotel))}">${uiText("نسخ الرابط", "Copy link")}</button>
        <button type="button" data-copy-link="${escapeHtml(hotelGuestLinkBase(hotel))}">${uiText("رابط النزيل", "Guest link")}</button>
      </div>
      <div class="super-actions">
        <button type="button" data-super-toggle="${escapeHtml(hotel.id)}">${status === "active" ? uiText("إيقاف الاشتراك", "Pause subscription") : uiText("تفعيل الاشتراك", "Activate subscription")}</button>
        <button type="button" data-super-renew="${escapeHtml(hotel.id)}">${uiText("تمديد 30 يوم", "Renew 30 days")}</button>
        <button type="button" class="danger" data-super-delete="${escapeHtml(hotel.id)}">${uiText("حذف الفندق", "Delete hotel")}</button>
      </div>
    </article>`;
  }).join("") : `<p class="empty-state">${uiText("لا توجد فنادق بعد", "No hotels yet")}</p>`;
}
function renderAdmin() {
  assignAdminSections();
  const total = state.orders.length;
  const done = state.orders.filter((order) => order.status === "done").length;
  const open = total - done;
  metrics.innerHTML = [
    [t("total"), total],
    [t("open"), open],
    [t("completed"), done],
    [t("avg"), `12 ${t("minutes")}`]
  ].map(([label, value]) => `<article class="metric"><span>${label}</span><strong>${value}</strong></article>`).join("");

  renderAdminInsights();
  renderAdminControls();
  renderCatalogManager();
  renderInvoice();
  renderLogo();
  renderThemeControls();
  renderHeroAdmin();
  renderOffersAdmin();
  renderQrTool();
  renderPmsAdmin();
  renderAuditLog();
  renderAdminSectionTabs();
  applyTheme();
}

function render() {
  renderStaffFilters();
  renderStaffPresencePanel();
  renderRoomMode();
  renderOffers();
  renderServices();
  renderServiceOptions();
  renderOrders();
  renderAdmin();
  renderSuperAdmin();
  applyStaticLanguage();
  renderHeroSlider();
  updateTopContext();
  showRoleView(getRole());
}

function showToast(message) {
  toast.textContent = message;
  toast.classList.add("show");
  window.setTimeout(() => toast.classList.remove("show"), 1800);
}

function createOrder(serviceId, details, room, items = [], chargeTo = "room") {
  const service = services.find((item) => item.id === serviceId) || services[0];
  if (!isServiceAvailable(service)) {
    showToast(uiText("هذه الخدمة غير متاحة الآن", "This service is unavailable now"));
    return false;
  }
  const estimateMinutes = serviceEstimate(service);
  const createdAt = new Date();
  const dueAt = new Date(createdAt.getTime() + estimateMinutes * 60000);
  const updatedAt = createdAt.toISOString();
  const order = {
    id: crypto.randomUUID(),
    serviceId,
    details,
    items,
    total: calculateTotal(items),
    room,
    chargeTo,
    status: "new",
    estimateMinutes,
    dueAt: dueAt.toISOString(),
    createdAt: createdAt.toISOString(),
    updatedAt
  };
  state.orders.unshift(order);
  saveOrder(order);
  addAudit("create_order", `${serviceName(service)} - Room ${room}`);
  render();
  return true;
}

serviceGrid.addEventListener("click", (event) => {
  const card = event.target.closest("[data-service]");
  if (!card) return;
  state.selectedService = card.dataset.service;
  renderServices();
  renderServiceOptions();
});

todayOffersList?.addEventListener("click", (event) => {
  const button = event.target.closest("[data-offer-service]");
  if (!button) return;
  const service = services.find((item) => item.id === button.dataset.offerService);
  if (service && !isServiceAvailable(service)) {
    showToast(uiText("هذه الخدمة غير متاحة الآن", "This service is unavailable now"));
    return;
  }
  state.selectedService = button.dataset.offerService;
  renderServices();
  renderServiceOptions();
  requestForm.scrollIntoView({ behavior: "smooth", block: "start" });
});

document.querySelectorAll("[data-room-mode]").forEach((button) => {
  button.addEventListener("click", () => {
    const modes = JSON.parse(localStorage.getItem("hotelRoomModes") || "{}");
    const room = guestRoomSelect?.value || currentRoom;
    modes[room] = modes[room] === button.dataset.roomMode ? "normal" : button.dataset.roomMode;
    localStorage.setItem("hotelRoomModes", JSON.stringify(modes));
    if (button.dataset.roomMode === "cleaning" && modes[room] === "cleaning") {
      createOrder("housekeeping", t("cleaningMode"), room, [{ id: "room_cleaning", ar: "تنظيف الغرفة", en: "Room cleaning", price: 0 }]);
    }
    renderRoomMode();
  });
});

requestForm.addEventListener("submit", (event) => {
  event.preventDefault();
  const sent = createOrder(state.selectedService, detailsInput.value.trim(), guestRoomSelect.value, getSelectedItems(), chargeSelect.value);
  if (!sent) return;
  detailsInput.value = "";
  renderServiceOptions();
  showToast(t("sent"));
});

guestOrders?.addEventListener("input", (event) => {
  const input = event.target.closest("[data-chat-input]");
  if (input) chatDrafts[input.dataset.chatInput] = input.value;
});
guestOrders?.addEventListener("click", (event) => {
  const chatButton = event.target.closest("[data-chat-order]");
  if (chatButton) {
    const order = state.orders.find((item) => item.id === chatButton.dataset.chatOrder);
    const input = chatButton.closest(".chat-compose")?.querySelector("[data-chat-input]");
    const text = input?.value || "";
    if (order && text) {
      delete chatDrafts[order.id];
      addOrderMessage(order, chatButton.dataset.chatSender || "guest", text);
      input.value = "";
    }
    return;
  }
  const cancelId = event.target.closest("[data-guest-cancel]")?.dataset.guestCancel;
  const rateId = event.target.closest("[data-rate-order]")?.dataset.rateOrder;
  if (cancelId) {
    const order = state.orders.find((item) => item.id === cancelId);
    if (!order || order.status !== "new") return;
    order.status = "cancelled";
    order.staffNote = t("cancelReason");
    order.updatedAt = new Date().toISOString();
    saveOrder(order);
    render();
  }
  if (rateId) {
    const order = state.orders.find((item) => item.id === rateId);
    if (!order || order.status !== "done") return;
    const value = Number(window.prompt(state.lang === "ar" ? "قيّم الخدمة من 1 إلى 5" : "Rate service from 1 to 5", "5"));
    if (!value) return;
    order.rating = Math.max(1, Math.min(5, value));
    order.ratingComment = window.prompt(state.lang === "ar" ? "تعليق اختياري" : "Optional comment", "") || "";
    order.updatedAt = new Date().toISOString();
    saveOrder(order);
    render();
    showToast(t("ratingSaved"));
  }
});


function scopedSessionKey(key) {
  return `${key}:v3:${hotelPathSlug()}:${getRole()}`;
}
function isGuestUnlocked() {
  return sessionStorage.getItem(scopedSessionKey("hotelGuestUnlocked")) === "true";
}

function setGuestLocked(locked) {
  if (locked) {
    appShell.hidden = true;
    adminLock.hidden = true;
    staffLock.hidden = true;
    if (superAdminLock) superAdminLock.hidden = true;
    guestLock.hidden = false;
  } else {
    appShell.hidden = false;
    guestLock.hidden = true;
  }
}
function isStaffUnlocked() {
  return sessionStorage.getItem(scopedSessionKey("hotelStaffUnlocked")) === "true";
}

function setStaffLocked(locked) {
  if (locked) {
    appShell.hidden = true;
    adminLock.hidden = true;
    guestLock.hidden = true;
    if (superAdminLock) superAdminLock.hidden = true;
    staffLock.hidden = false;
  } else {
    appShell.hidden = false;
    staffLock.hidden = true;
  }
}
function isAdminUnlocked() {
  return sessionStorage.getItem(scopedSessionKey("hotelAdminUnlocked")) === "true";
}

function setAdminLocked(locked) {
  if (locked) {
    appShell.hidden = true;
    staffLock.hidden = true;
    guestLock.hidden = true;
    if (superAdminLock) superAdminLock.hidden = true;
    adminLock.hidden = false;
  } else {
    appShell.hidden = false;
    adminLock.hidden = true;
  }
}

function isSuperAdminUnlocked() {
  return sessionStorage.getItem("hotelSuperAdminUnlocked") === "true";
}

function setSuperAdminLocked(locked) {
  if (locked) {
    appShell.hidden = true;
    adminLock.hidden = true;
    staffLock.hidden = true;
    guestLock.hidden = true;
    superAdminLock.hidden = false;
  } else {
    appShell.hidden = false;
    superAdminLock.hidden = true;
  }
}
function getRole() {
  const cleanPath = window.location.pathname.replace(/\/+$/, "");
  const hotelRole = cleanPath.match(/^\/hotel\/[^/]+\/(guest|staff|admin)$/);
  if (hotelRole) return hotelRole[1];
  const role = new URLSearchParams(window.location.search).get("role") || "guest";
  return ["guest", "staff", "admin", "superadmin"].includes(role) ? role : "guest";
}

function showRoleView(role) {
  document.body.dataset.role = role;
  document.querySelectorAll(".tab, .view").forEach((item) => item.classList.remove("active"));
  const viewKey = role === "superadmin" ? "superAdmin" : role;
  const targetTab = document.querySelector(`.tab[data-view="${viewKey}"]`);
  const targetView = document.querySelector(`#${viewKey}View`);
  if (targetTab) targetTab.classList.add("active");
  if (targetView) targetView.classList.add("active");
}


function logoutCurrentRole() {
  const role = getRole();
  if (role === "staff") {
    const account = activeStaffAccount();
    if (account) updateStaffPresence(account.username, "offline");
  }
  if (role === "guest") sessionStorage.removeItem(scopedSessionKey("hotelGuestUnlocked"));
  if (role === "staff") sessionStorage.removeItem(scopedSessionKey("hotelStaffUnlocked"));
  if (role === "admin") sessionStorage.removeItem(scopedSessionKey("hotelAdminUnlocked"));
  if (role === "superadmin") sessionStorage.removeItem("hotelSuperAdminUnlocked");
  applyRoleAccess();
  render();
  showToast("Signed out");
}

function applyRoleAccess() {
  const role = getRole();
  if (role === "guest" && !isGuestUnlocked()) {
    setGuestLocked(true);
    return;
  }
  setGuestLocked(false);
  if (role === "staff" && !isStaffUnlocked()) {
    setStaffLocked(true);
    return;
  }
  setStaffLocked(false);
  if (role === "admin" && !isAdminUnlocked()) {
    setAdminLocked(true);
    return;
  }
  setAdminLocked(false);
  if (role === "superadmin" && !isSuperAdminUnlocked()) {
    setSuperAdminLocked(true);
    return;
  }
  setSuperAdminLocked(false);
  if (role === "staff") {
    heartbeatStaffPresence(true, "online");
    state.filter = staffCanViewAllDepartments() ? "all" : getStaffDepartmentId();
  }
  const tabs = document.querySelector(".mode-tabs");
  if (tabs) tabs.hidden = true;
  showRoleView(role);
}
document.addEventListener("click", (event) => {
  const tab = event.target.closest("[data-admin-tab]");
  if (!tab) return;
  activeAdminSection = tab.dataset.adminTab;
  localStorage.setItem("hotelAdminSection", activeAdminSection);
  renderAdminSectionTabs();
});
document.querySelectorAll(".tab").forEach((tab) => {
  tab.addEventListener("click", () => {
    const role = getRole();
    if (["guest", "staff", "admin"].includes(role)) {
      showRoleView(role);
      return;
    }
    document.querySelectorAll(".tab, .view").forEach((item) => item.classList.remove("active"));
    tab.classList.add("active");
    document.querySelector(`#${tab.dataset.view}View`).classList.add("active");
  });
});

staffFilters?.addEventListener("click", (event) => {
  const filter = event.target.closest(".filter");
  if (!filter) return;
  if (getRole() === "staff" && !staffCanViewAllDepartments()) return;
  staffFilters.querySelectorAll(".filter").forEach((item) => item.classList.remove("active"));
  filter.classList.add("active");
  state.filter = filter.dataset.filter;
  renderOrders();
});


function updateTopContext() {
  const role = getRole();
  if (!topContext || !topContextLabel || !currentRoomDisplay) return;
  topContext.hidden = false;
  if (role === "guest") {
    topContextLabel.textContent = t("roomNumberLabel");
    currentRoomDisplay.textContent = guestRoomSelect.value;
  } else if (role === "staff") {
    const department = getStaffDepartment();
    topContextLabel.textContent = staffRoleLabel(getStaffPermission());
    currentRoomDisplay.textContent = staffCanViewAllDepartments() ? uiText("كل الأقسام", "All departments") : (department ? departmentName(department) : "Staff");
  } else if (role === "superadmin") {
    topContextLabel.textContent = state.lang === "ar" ? "الصفحة" : "Page";
    currentRoomDisplay.textContent = state.lang === "ar" ? "مالك النظام" : "Owner";
  } else {
    topContextLabel.textContent = state.lang === "ar" ? "الصفحة" : "Page";
    currentRoomDisplay.textContent = state.lang === "ar" ? "الإدارة" : "Admin";
  }
}
function syncRoomDisplay() {
  currentRoomDisplay.textContent = guestRoomSelect.value;
  requestRoomDisplay.textContent = guestRoomSelect.value;
  renderOrders();
}
staffOrders.addEventListener("input", (event) => {
  const input = event.target.closest("[data-chat-input]");
  if (input) chatDrafts[input.dataset.chatInput] = input.value;
});
staffOrders.addEventListener("click", (event) => {
  const clearRoomButton = event.target.closest("[data-clear-staff-room]");
  if (clearRoomButton) {
    state.staffRoom = "";
    if (staffRoomFilter) staffRoomFilter.value = "";
    renderOrders();
    return;
  }

  const roomCard = event.target.closest("[data-staff-room-card]");
  if (roomCard) {
    state.staffRoom = roomCard.dataset.staffRoomCard || "";
    if (staffRoomFilter) staffRoomFilter.value = state.staffRoom;
    renderOrders();
    return;
  }

  const chatButton = event.target.closest("[data-chat-order]");
  if (chatButton) {
    const order = state.orders.find((item) => item.id === chatButton.dataset.chatOrder);
    if (order && getRole() === "staff" && !staffCanViewAllDepartments() && !orderBelongsToDepartment(order, getStaffDepartmentId())) {
      showToast(uiText("هذا الطلب لقسم آخر", "This request belongs to another department"));
      return;
    }
    const input = chatButton.closest(".chat-compose")?.querySelector("[data-chat-input]");
    const text = input?.value || "";
    if (order && text) {
      delete chatDrafts[order.id];
      addOrderMessage(order, chatButton.dataset.chatSender || "staff", text);
      input.value = "";
    }
    return;
  }
  const button = event.target.closest("[data-status]");
  if (!button) return;
  const order = state.orders.find((item) => item.id === button.dataset.order);
  if (!order) return;
  if (getRole() === "staff" && !staffCanViewAllDepartments() && !orderBelongsToDepartment(order, getStaffDepartmentId())) {
    showToast(uiText("هذا الطلب لقسم آخر", "This request belongs to another department"));
    return;
  }
  if (!staffCanChangeOrderStatus()) {
    showToast(state.lang === "ar" ? "هذه الصلاحية للعرض والمحاسبة فقط" : "This role is view and billing only");
    return;
  }
  order.status = button.dataset.status;
  const actor = activeStaffAccount()?.username || (getRole() === "admin" ? "admin" : "staff");
  if (order.status === "progress" && !order.assignedTo) order.assignedTo = actor;
  if (order.status === "done") order.completedBy = actor;
  if (getRole() === "staff") updateStaffPresence(actor, "online");
  order.updatedAt = new Date().toISOString();
  saveOrder(order);
  render();
});



function findOption(serviceId, optionId) {
  const groups = serviceOptions[serviceId] || [];
  for (const group of groups) {
    const item = group.items.find((option) => option.id === optionId);
    if (item) return item;
  }
  return null;
}

pmsAdminForm?.addEventListener("submit", async (event) => {
  event.preventDefault();
  await savePmsAdminSettings();
});

checkPmsStatusButton?.addEventListener("click", async () => {
  await refreshPmsStatus();
});
document.querySelector("#roomAdminForm")?.addEventListener("submit", (event) => {
  event.preventDefault();
  const room = adminRoomNumber.value.trim();
  if (!room || rooms.includes(room)) return;
  rooms.push(room);
  ensureGuestAccount(room);
  addAudit("add_room", room);
  adminRoomNumber.value = "";
  refreshAdminAndSave();
});

roomAdminList?.addEventListener("click", async (event) => {
  const current = event.target.closest("[data-room-current]")?.dataset.roomCurrent;
  const passwordRoom = event.target.closest("[data-room-password]")?.dataset.roomPassword;
  const remove = event.target.closest("[data-room-delete]")?.dataset.roomDelete;
  if (current) {
    currentRoom = current;
    guestRoomSelect.value = currentRoom;
    syncRoomDisplay();
    refreshAdminAndSave();
  }
  if (passwordRoom) {
    const account = ensureGuestAccount(passwordRoom);
    const nextPassword = window.prompt(uiText("كلمة مرور جديدة للغرفة", "New room password"), generateStrongPassword(14));
    if (!nextPassword) return;
    account.password = nextPassword.trim();
    addAudit("change_room_password", passwordRoom);
    refreshAdminAndSave();
    showToast(uiText("تم تغيير كلمة مرور الغرفة", "Room password changed"));
    return;
  }
  if (remove && rooms.length > 1) {
    const deletedCount = await deleteOrdersForRoom(remove);
    rooms = rooms.filter((room) => room !== remove);
    delete guestAccounts[remove];
    if (state.staffRoom === remove) {
      state.staffRoom = "";
      if (staffRoomFilter) staffRoomFilter.value = "";
    }
    if (currentRoom === remove) currentRoom = rooms[0];
    guestRoomSelect.value = currentRoom;
    addAudit("delete_room", `Room ${remove} - deleted orders: ${deletedCount}`);
    syncRoomDisplay();
    refreshAdminAndSave();
    showToast(uiText(`تم حذف الغرفة و ${deletedCount} طلبات`, `Room deleted with ${deletedCount} orders`));
  }
});

serviceAdminForm?.addEventListener("submit", (event) => {
  event.preventDefault();
  const nameAr = adminServiceAr.value.trim();
  const nameEn = adminServiceEn.value.trim() || nameAr;
  if (!nameAr) return;
  const id = makeId("custom", nameEn || nameAr);
  services.push({ id, department: adminServiceDepartment.value, nameAr, nameEn, descAr: adminServiceDesc.value.trim() || nameAr, descEn: adminServiceDesc.value.trim() || nameEn, icon: "message" });
  addAudit("add_service_card", nameEn || nameAr);
  serviceOptions[id] = [{ titleAr: "الخدمات", titleEn: "Services", items: [] }];
  serviceAdminForm.reset();
  refreshAdminAndSave();
});

optionAdminForm?.addEventListener("submit", (event) => {
  event.preventDefault();
  const serviceId = adminOptionService.value;
  const nameAr = adminOptionAr.value.trim();
  const nameEn = adminOptionEn.value.trim() || nameAr;
  if (!serviceId || !nameAr) return;
  if (!serviceOptions[serviceId]) serviceOptions[serviceId] = [{ titleAr: "الخدمات", titleEn: "Services", items: [] }];
  if (!serviceOptions[serviceId][0]) serviceOptions[serviceId].push({ titleAr: "الخدمات", titleEn: "Services", items: [] });
  serviceOptions[serviceId][0].items.push({ id: makeId("option", nameEn || nameAr), ar: nameAr, en: nameEn, price: Number(adminOptionPrice.value) || 0 });
  addAudit("add_service_option", nameEn || nameAr);
  optionAdminForm.reset();
  refreshAdminAndSave();
});

departmentAdminForm?.addEventListener("submit", (event) => {
  event.preventDefault();
  const ar = adminDepartmentAr.value.trim();
  const en = adminDepartmentEn.value.trim() || ar;
  if (!ar) return;
  const id = makeId("dept", en || ar);
  departments.push({ id, ar, en });
  addAudit("add_department", en || ar);
  departmentAdminForm.reset();
  refreshAdminAndSave();
});

departmentAdminList?.addEventListener("click", (event) => {
  const id = event.target.closest("[data-department-delete]")?.dataset.departmentDelete;
  if (!id) return;
  departments = departments.filter((department) => department.id !== id || department.id === "all");
  services.forEach((service) => {
    if (service.department === id) service.department = "extras";
  });
  staffAccounts.forEach((account) => {
    if (account.department === id) account.department = "extras";
  });
  if (state.filter === id) state.filter = "all";
  refreshAdminAndSave();
});

staffAccountForm?.addEventListener("submit", (event) => {
  event.preventDefault();
  const username = adminStaffUsername.value.trim().toLowerCase();
  const password = adminStaffPassword.value.trim() || generateStrongPassword(14);
  const department = adminStaffDepartment.value;
  const role = adminStaffRole?.value || "staff";
  if (!username || !password || staffAccounts.some((account) => account.username.toLowerCase() === username)) return;
  staffAccounts.push({ username, password, department, role, presence: "offline", lastSeen: "" });
  addAudit("add_staff", `${username} - ${role}`);
  staffAccountForm.reset();
  refreshAdminAndSave();
});

staffAccountList?.addEventListener("click", (event) => {
  const passwordUsername = event.target.closest("[data-staff-password]")?.dataset.staffPassword;
  if (passwordUsername) {
    const account = staffAccounts.find((item) => item.username === passwordUsername);
    if (!account) return;
    const nextPassword = window.prompt(uiText("كلمة مرور جديدة للقسم أو الموظف", "New department or staff password"), generateStrongPassword(14));
    if (!nextPassword) return;
    account.password = nextPassword.trim();
    addAudit("change_staff_password", passwordUsername);
    refreshAdminAndSave();
    showToast(uiText("تم تغيير كلمة مرور القسم", "Department password changed"));
    return;
  }
  const username = event.target.closest("[data-staff-delete]")?.dataset.staffDelete;
  if (!username) return;
  addAudit("delete_staff", username);
  staffAccounts = staffAccounts.filter((account) => account.username !== username);
  refreshAdminAndSave();
});

catalogList?.addEventListener("click", (event) => {
  const serviceDelete = event.target.closest("[data-service-delete]")?.dataset.serviceDelete;
  const optionDeleteButton = event.target.closest("[data-option-delete]");
  const priceSaveButton = event.target.closest("[data-price-save]");
  const priceZeroButton = event.target.closest("[data-price-zero]");
  const estimateSaveButton = event.target.closest("[data-estimate-save]");

  if (estimateSaveButton) {
    const serviceId = estimateSaveButton.dataset.estimateSave;
    const service = services.find((item) => item.id === serviceId);
    const input = catalogList.querySelector(`[data-estimate-service="${serviceId}"]`);
    const fromInput = catalogList.querySelector(`[data-available-from="${serviceId}"]`);
    const toInput = catalogList.querySelector(`[data-available-to="${serviceId}"]`);
    if (service && input) {
      service.estimateMinutes = Math.max(1, Number(input.value) || 30);
      service.availableFrom = fromInput?.value || "";
      service.availableTo = toInput?.value || "";
    }
    refreshAdminAndSave();
  }

  if (serviceDelete && services.length > 1) {
    const index = services.findIndex((service) => service.id === serviceDelete);
    if (index >= 0) {
      addAudit("delete_service_card", services[index].nameEn || services[index].nameAr);
      services.splice(index, 1);
    }
    delete serviceOptions[serviceDelete];
    if (state.selectedService === serviceDelete) state.selectedService = services[0].id;
    refreshAdminAndSave();
  }

  if (optionDeleteButton) {
    const serviceId = optionDeleteButton.dataset.optionDelete;
    const optionId = optionDeleteButton.dataset.optionId;
    (serviceOptions[serviceId] || []).forEach((group) => {
      const removed = group.items.find((item) => item.id === optionId);
      if (removed) addAudit("delete_service_option", removed.en || removed.ar);
      group.items = group.items.filter((item) => item.id !== optionId);
    });
    refreshAdminAndSave();
  }

  if (priceZeroButton) {
    const serviceId = priceZeroButton.dataset.priceZero;
    const optionId = priceZeroButton.dataset.optionId;
    const item = findOption(serviceId, optionId);
    if (item) {
      item.price = 0;
      addAudit("remove_price", item.en || item.ar);
    }
    refreshAdminAndSave();
  }

  if (priceSaveButton) {
    const serviceId = priceSaveButton.dataset.priceSave;
    const optionId = priceSaveButton.dataset.optionId;
    const input = catalogList.querySelector(`[data-price-service="${serviceId}"][data-price-option="${optionId}"]`);
    const item = findOption(serviceId, optionId);
    if (item && input) {
      item.price = Number(input.value) || 0;
      addAudit("save_price", `${item.en || item.ar}: ${item.price}`);
    }
    refreshAdminAndSave();
  }
});


staffSearch?.addEventListener("input", () => {
  state.staffSearch = staffSearch.value;
  renderOrders();
});

staffStatusFilter?.addEventListener("change", () => {
  state.staffStatus = staffStatusFilter.value;
  renderOrders();
});

staffRoomFilter?.addEventListener("input", () => {
  state.staffRoom = staffRoomFilter.value.trim();
  renderOrders();
});

staffDateFilter?.addEventListener("change", () => {
  state.staffDate = staffDateFilter.value;
  renderOrders();
});


logoAdminForm?.addEventListener("submit", async (event) => {
  event.preventDefault();
  const file = adminLogoInput?.files?.[0];
  hotelName = {
    ar: adminHotelNameAr?.value.trim() || "\u0641\u0646\u062f\u0642 \u0644\u0627\u0641\u064a\u0646\u0627",
    en: adminHotelNameEn?.value.trim() || "Lavina Hotel"
  };
  if (file) hotelLogo = await readLogoFile(file);
  renderLogo();
  saveConfig();
  showToast(uiText("تم حفظ اللوغو", "Logo saved"));
});



heroAdminForm?.addEventListener("submit", async (event) => {
  event.preventDefault();
  const newImages = await readImageFiles(heroImageInput);
  if (newImages.length) heroImages = [...heroImages, ...newImages];
  heroSlideIndex = 0;
  if (heroImageInput) heroImageInput.value = "";
  renderHeroSlider();
  renderHeroAdmin();
  startHeroSlider();
  saveConfig();
  showToast(uiText("تم حفظ صور السلايدر", "Slider images saved"));
});

offerAdminForm?.addEventListener("submit", (event) => {
  event.preventDefault();
  const ar = adminOfferAr.value.trim();
  const en = adminOfferEn.value.trim() || ar;
  if (!ar) return;
  hotelOffers.push({ id: makeId("offer", en || ar), ar, en, serviceId: adminOfferService.value || services[0].id });
  offerAdminForm.reset();
  renderOffers();
  renderOffersAdmin();
  saveConfig();
  showToast(uiText("تمت إضافة العرض", "Offer added"));
});

offerAdminList?.addEventListener("click", (event) => {
  const id = event.target.closest("[data-offer-delete]")?.dataset.offerDelete;
  if (!id) return;
  hotelOffers = hotelOffers.filter((offer) => offer.id !== id);
  renderOffers();
  renderOffersAdmin();
  saveConfig();
  showToast(uiText("تم حذف العرض", "Offer deleted"));
});

heroAdminPreview?.addEventListener("click", (event) => {
  const button = event.target.closest("[data-hero-delete]");
  if (!button) return;
  const index = Number(button.dataset.heroDelete);
  heroImages.splice(index, 1);
  if (!heroImages.length) heroImages = [...defaultHeroImages];
  heroSlideIndex = 0;
  renderHeroSlider();
  renderHeroAdmin();
  startHeroSlider();
  saveConfig();
  showToast(uiText("تم حذف الصورة", "Image deleted"));
});

resetHeroImagesButton?.addEventListener("click", () => {
  heroImages = [...defaultHeroImages];
  heroSlideIndex = 0;
  if (heroImageInput) heroImageInput.value = "";
  renderHeroSlider();
  renderHeroAdmin();
  startHeroSlider();
  saveConfig();
  showToast(uiText("تمت استعادة الصورة الافتراضية", "Default image restored"));
});


heroSlideSecondsInput?.addEventListener("change", () => {
  heroSlideSeconds = Math.max(2, Number(heroSlideSecondsInput.value) || 5);
  heroSlideSecondsInput.value = heroSlideSeconds;
  startHeroSlider();
  saveConfig();
  showToast(uiText("تم تحديث سرعة السلايدر", "Slider speed updated"));
});
heroDots?.addEventListener("click", (event) => {
  const button = event.target.closest("[data-hero-slide]");
  if (!button) return;
  heroSlideIndex = Number(button.dataset.heroSlide) || 0;
  renderHeroSlider();
  startHeroSlider();
});
themeAdminForm?.addEventListener("submit", (event) => {
  event.preventDefault();
  hotelTheme = readThemeControls();
  applyTheme();
  saveConfig();
  showToast(uiText("تم حفظ المظهر", "Theme saved"));
});

Object.values(themeInputs).forEach((input) => {
  input?.addEventListener("input", () => {
    hotelTheme = readThemeControls();
    applyTheme();
  });
});

resetThemeButton?.addEventListener("click", () => {
  hotelTheme = { ...defaultTheme };
  renderThemeControls();
  applyTheme();
  saveConfig();
  showToast(uiText("تمت استعادة المظهر الافتراضي", "Default theme restored"));
});
removeLogoButton?.addEventListener("click", () => {
  hotelLogo = "";
  if (adminLogoInput) adminLogoInput.value = "";
  renderLogo();
  saveConfig();
  showToast(uiText("تم حذف اللوغو", "Logo removed"));
});

adminLogoInput?.addEventListener("change", async () => {
  const file = adminLogoInput.files?.[0];
  if (!file) return;
  hotelLogo = await readLogoFile(file);
  renderLogo();
});
showInvoiceButton?.addEventListener("click", () => renderInvoice());
invoiceRoomSelect?.addEventListener("change", () => renderInvoice());
printInvoiceButton?.addEventListener("click", printInvoice);
downloadInvoiceButton?.addEventListener("click", downloadInvoice);
qrRoomSelect?.addEventListener("change", renderQrTool);
downloadQrButton?.addEventListener("click", downloadQr);
printQrButton?.addEventListener("click", printQr);
exportTodayReportButton?.addEventListener("click", () => exportOrdersReport("today"));
exportAllReportButton?.addEventListener("click", () => exportOrdersReport("all"));
exportServicesReportButton?.addEventListener("click", exportServicesReport);
exportAuditLogButton?.addEventListener("click", exportAuditLog);
clearAuditLogButton?.addEventListener("click", () => {
  auditLog = [];
  localStorage.setItem("hotelAuditLog", JSON.stringify(auditLog));
  renderAuditLog();
  showToast(uiText("تم مسح سجل النشاط", "Audit log cleared"));
});
generateStaffPasswordButton?.addEventListener("click", () => {
  if (adminStaffPassword) adminStaffPassword.value = generateStrongPassword(14);
});

guestLockForm?.addEventListener("submit", (event) => {
  event.preventDefault();
  const typedUsername = guestUsernameInput.value.trim();
  const account = Object.values(guestAccounts).find((item) => item.username === typedUsername && item.password === guestPasswordInput.value);
  if (account) {
    sessionStorage.setItem(scopedSessionKey("hotelGuestUnlocked"), "true");
    currentRoom = account.room;
    guestRoomSelect.value = account.room;
    syncRoomDisplay();
    guestUsernameInput.value = "";
    guestPasswordInput.value = "";
    applyRoleAccess();
    showToast(uiText("تم دخول النزيل", "Guest logged in"));
  } else {
    showToast(uiText("اسم المستخدم أو كلمة المرور غير صحيحة", "Username or password is incorrect"));
  }
});
staffLockForm?.addEventListener("submit", (event) => {
  event.preventDefault();
  const username = staffUsernameInput.value.trim().toLowerCase();
  const account = getStaffAccounts().find((item) => item.username.toLowerCase() === username && item.password === staffPasswordInput.value);
  if (account) {
    sessionStorage.setItem(scopedSessionKey("hotelStaffUnlocked"), "true");
    sessionStorage.setItem("hotelStaffUsername", account.username);
    sessionStorage.setItem("hotelStaffDepartment", account.department);
    sessionStorage.setItem("hotelStaffRole", account.role || "staff");
    localStorage.setItem("hotelStaffUsername", account.username);
    localStorage.setItem("hotelStaffDepartment", account.department);
    localStorage.setItem("hotelStaffRole", account.role || "staff");
    updateStaffPresence(account.username, "online");
    staffUsernameInput.value = "";
    staffPasswordInput.value = "";
    applyRoleAccess();
    render();
    showToast(uiText("تم دخول الموظف", "Staff logged in"));
  } else {
    showToast(uiText("اسم المستخدم أو كلمة المرور غير صحيحة", "Username or password is incorrect"));
  }
});

staffPresencePanel?.addEventListener("click", (event) => {
  const button = event.target.closest("[data-presence-set]");
  if (!button) return;
  const account = activeStaffAccount();
  if (!account) return;
  updateStaffPresence(account.username, button.dataset.presenceSet || "online");
  render();
  showToast(`${t("staffPresenceTitle")}: ${presenceLabel(button.dataset.presenceSet || "online")}`);
});

adminLockForm?.addEventListener("submit", (event) => {
  event.preventDefault();
  const currentHotel = hotelFromUrl() ? superHotels.find((hotel) => hotel.slug === hotelFromUrl()) : null;
  const username = currentHotel?.adminUser || localStorage.getItem("hotelAdminUsername") || "admin";
  const password = currentHotel?.adminPass || localStorage.getItem("hotelAdminPassword") || "1234";
  if (adminUsernameInput.value.trim() === username && adminPasswordInput.value === password) {
    sessionStorage.setItem(scopedSessionKey("hotelAdminUnlocked"), "true");
    adminUsernameInput.value = "";
    adminPasswordInput.value = "";
    applyRoleAccess();
    showToast(uiText("تم فتح الداشبورد", "Dashboard opened"));
  } else {
    showToast(uiText("اسم المستخدم أو كلمة المرور غير صحيحة", "Username or password is incorrect"));
  }
});
document.querySelector("#langToggle").addEventListener("click", () => {
  setLanguage(state.lang === "ar" ? "en" : "ar");
});
logoutButton?.addEventListener("click", logoutCurrentRole);



superAdminLockForm?.addEventListener("submit", (event) => {
  event.preventDefault();
  if (superUsernameInput.value.trim() === "super" && superPasswordInput.value === "9999") {
    sessionStorage.setItem("hotelSuperAdminUnlocked", "true");
    superUsernameInput.value = "";
    superPasswordInput.value = "";
    applyRoleAccess();
    render();
  } else {
    showToast(state.lang === "ar" ? "بيانات مالك النظام غير صحيحة" : "Invalid owner credentials");
  }
});

superHotelForm?.addEventListener("submit", (event) => {
  event.preventDefault();
  const nameAr = superHotelNameAr.value.trim();
  const nameEn = superHotelNameEn.value.trim() || nameAr;
  const slug = normalizeHotelSlug(superHotelSlug.value || nameEn || nameAr);
  if (!nameAr || superHotels.some((hotel) => hotel.slug === slug)) {
    showToast(state.lang === "ar" ? "اسم الفندق مطلوب أو الكود موجود مسبقاً" : "Hotel name is required or code already exists");
    return;
  }
  superHotels.unshift({
    id: crypto.randomUUID(),
    nameAr,
    nameEn,
    slug,
    plan: superHotelPlan.value,
    allowedRooms: Math.max(1, Number(superHotelRooms.value) || 1),
    status: superHotelStatus.value,
    startDate: superHotelStart.value || todayIsoDate(),
    endDate: superHotelEnd.value || addDaysIso(30),
    adminUser: superHotelAdminUser.value.trim() || "admin",
    adminPass: superHotelAdminPass.value.trim() || "1234",
    createdAt: new Date().toISOString()
  });
  superHotelForm.reset();
  saveSuperHotels();
  renderSuperAdmin();
  showToast(state.lang === "ar" ? "تمت إضافة الفندق" : "Hotel added");
});

superHotelSearch?.addEventListener("input", () => {
  superHotelQuery = superHotelSearch.value;
  renderSuperAdmin();
});

superHotelList?.addEventListener("click", async (event) => {
  const copyButton = event.target.closest("[data-copy-link]");
  if (copyButton) {
    const link = copyButton.dataset.copyLink;
    try {
      await navigator.clipboard.writeText(link);
      showToast(state.lang === "ar" ? "تم نسخ الرابط" : "Link copied");
    } catch (error) {
      window.prompt(state.lang === "ar" ? "انسخ الرابط" : "Copy link", link);
    }
    return;
  }

  const toggleId = event.target.closest("[data-super-toggle]")?.dataset.superToggle;
  const renewId = event.target.closest("[data-super-renew]")?.dataset.superRenew;
  const deleteId = event.target.closest("[data-super-delete]")?.dataset.superDelete;
  if (toggleId) {
    const hotel = superHotels.find((item) => item.id === toggleId);
    if (hotel) {
      hotel.status = hotelEffectiveStatus(hotel) === "active" ? "paused" : "active";
      if (hotel.status === "active" && (!hotel.endDate || hotel.endDate < todayIsoDate())) hotel.endDate = addDaysIso(30);
      hotel.updatedAt = new Date().toISOString();
      saveSuperHotels();
      renderSuperAdmin();
    }
  }
  if (renewId) {
    const hotel = superHotels.find((item) => item.id === renewId);
    if (hotel) {
      const base = hotel.endDate && hotel.endDate > todayIsoDate() ? new Date(`${hotel.endDate}T00:00:00`) : new Date();
      base.setDate(base.getDate() + 30);
      hotel.endDate = base.toISOString().slice(0, 10);
      hotel.status = "active";
      hotel.updatedAt = new Date().toISOString();
      saveSuperHotels();
      renderSuperAdmin();
    }
  }
  if (deleteId) {
    superHotels = superHotels.filter((hotel) => hotel.id !== deleteId);
    saveSuperHotels();
    renderSuperAdmin();
  }
});
async function initializeApp() {
  setLanguage(state.lang);
  applyRoleAccess();
  await loadBackendState();
  const addedDefaultHotel = ensureDefaultHotelSubscription();
  ensureCoreDepartments();
  ensureRoomServiceRestaurantMenu();
  if (addedDefaultHotel) saveSuperHotels();
  rooms.forEach((room) => ensureGuestAccount(room));
  applyGuestLinkPreset();
  applyStaffLinkPreset();
  renderLogo();
  guestRoomSelect.value = roomFromUrl() || currentRoom;
  currentRoom = guestRoomSelect.value;
  syncRoomDisplay();
  applyRoleAccess();
  await syncOrdersFromBackend({ renderAfter: false });
  setLanguage(state.lang);
  startHeroSlider();
  setInterval(() => {
    if (!isChatInputActive()) renderOrders();
  }, 1000);
  setInterval(() => syncOrdersFromBackend({ renderAfter: !isChatInputActive() }), 2000);
  setInterval(() => heartbeatStaffPresence(false, "online"), 15000);
  document.addEventListener("visibilitychange", () => {
    if (!document.hidden) heartbeatStaffPresence(true, "online");
  });
  window.addEventListener("focus", () => heartbeatStaffPresence(true, "online"));
  window.addEventListener("storage", (event) => {
    if (event.key === "hotelStaffAccounts" && event.newValue) {
      try { staffAccounts = JSON.parse(event.newValue).map(normalizeStaffAccount); } catch {}
      if (getRole() === "admin") renderAdminControls();
      if (getRole() === "staff") renderStaffPresencePanel();
    }
  });
  setInterval(() => {
    if (getRole() === "admin" && isAdminUnlocked()) {
      staffAccounts = getStaffAccounts();
      renderAdminControls();
    }
  }, 5000);
}

initializeApp();


































































