function AvailabilityModel(){const e=this;e.checkInDate=ko.observable(new Date),e.checkOutDate=ko.observable(new Date),e.guests=ko.observable(1),e.bedType=ko.observable("");const i=e=>Array.isArray(e)?e.filter(e=>e&&!1!==e.isActive).map(e=>{const i=Math.round(100*(Number(e.priceDelta)||0))/100,t=i>0?` (+£${i.toFixed(2)})`:"";return{id:e.id||e.value,label:e.label||"",priceDelta:i,displayLabel:`${e.label||""}${t}`}}).filter(e=>e.id&&e.label):[];e.bedOptions=ko.observableArray("undefined"!=typeof window&&Array.isArray(window.ROOM_BED_OPTIONS)?i(window.ROOM_BED_OPTIONS):i([])),e.setBedOptions=t=>{e.bedOptions(i(t))},e.price=ko.observable(null),e.originalPrice=ko.observable(null),e.discountPercent=ko.observable(0),e.isUnavailable=ko.observable(!1),e.unavailabilityReason=ko.observable(null),e.unavailabilityMessage=ko.pureComputed(()=>{if(!e.isUnavailable())return"";switch(e.unavailabilityReason()){case"blocked":return"The selected room is unavailable on these dates. Please choose an alternative date or explore our other suites.";case"unavailable":return"Those dates are already booked. Please try a different range.";case"locked-range":return"Your selection includes blocked days. Adjust the dates to continue.";default:return"The selected dates are currently unavailable. Please pick another set of dates."}}),e.unavailableDates=ko.observableArray([]),e.resetPricing=()=>{e.price(null),e.originalPrice(null),e.discountPercent(0)};const t=e=>`${String.fromCharCode(163)}${(Number(e)||0).toFixed(2)}`;e.selectedBedOption=ko.pureComputed(()=>{const i=e.bedType();if(!i)return null;return e.bedOptions().find(e=>e&&e.id===i)||null}),e.bedOptions.subscribe(i=>{const t=e.bedType();if(!t)return;Array.isArray(i)&&i.some(e=>e.id===t)||e.bedType("")}),e.bedSurcharge=ko.pureComputed(()=>{const i=e.selectedBedOption();if(!i)return 0;const t=Number(i.priceDelta);return Number.isFinite(t)?t:0}),e.formattedBedSurcharge=ko.pureComputed(()=>t(e.bedSurcharge()));const n=(e,i)=>{const t=Number(e),n=Number(i);if(!Number.isFinite(t))return null;const a=Number.isFinite(n)?n:0;return Math.round(100*(t+a))/100};e.displayPrice=ko.pureComputed(()=>n(e.price(),e.bedSurcharge())),e.displayOriginalPrice=ko.pureComputed(()=>n(e.originalPrice(),e.bedSurcharge())),e.formattedPrice=ko.pureComputed(()=>t(e.displayPrice())),e.formattedOriginalPrice=ko.pureComputed(()=>t(e.displayOriginalPrice())),e.hasDiscount=ko.pureComputed(()=>{if(!(Number(e.discountPercent())>0))return!1;const i=Number(e.displayOriginalPrice()),t=Number(e.displayPrice());return!(!Number.isFinite(i)||!Number.isFinite(t))&&i-t>.009}),e.getUnavailableDates=async()=>{const i=new Date,t=new Date;t.setFullYear(i.getFullYear()+2);const n={checkin:i.toISOString().split("T")[0],checkout:t.toISOString().split("T")[0]};try{const i=await fetch(`/rooms/${ROOM_ID}/unavailability`,{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify(n)});if(!i.ok)throw new Error("Failed to check availability");const t=await i.json();e.unavailableDates(t)}catch(i){console.error("Error checking availability:",i),e.isUnavailable(!0),e.unavailabilityReason(null)}},e.checkAvailability=async()=>{const i={checkin:ko.unwrap(e.checkInDate),checkout:ko.unwrap(e.checkOutDate),guests:ko.unwrap(e.guests)};try{const t=await fetch(`/rooms/${SLUG}/availability`,{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify(i)});if(!t.ok)throw new Error("Failed to check availability");const n=await t.json();if(n&&n.rental){const i=n.rental;e.isUnavailable(!!i.isUnavailable),e.unavailabilityReason(i.unavailabilityReason||null),void 0!==i.price&&null!==i.price?e.price(i.price):e.price(null),void 0!==i.originalPrice&&null!==i.originalPrice?e.originalPrice(i.originalPrice):void 0!==i.price&&null!==i.price?e.originalPrice(i.price):e.originalPrice(null),e.discountPercent(Number(i.discountPercent)||0)}else e.isUnavailable(!0),e.unavailabilityReason(null),e.resetPricing()}catch(i){console.error("Error checking availability:",i),e.isUnavailable(!0),e.unavailabilityReason(null),e.resetPricing()}},e.inlinePicker=null,e.popupPicker=null,e.initLitepickers=async()=>{const i=i=>{const t=i.format("YYYY-MM-DD");return e.unavailableDates().some(e=>"string"==typeof e?e===t:!(!e.start||!e.end)&&(t>=e.start&&t<=e.end))},t=t=>{const n=new Date;return n.setHours(0,0,0,0),new Litepicker({...t,format:"YYYY-MM-DD",singleMode:!1,numberOfMonths:2,numberOfColumns:2,minDate:n,lockDays:e.unavailableDates(),tooltipText:{one:"night",other:"nights"},tooltipNumber:e=>e-1,setup:t=>{t.on("selected",(t,n)=>{const a=[];let r=t.clone();for(;r.isBefore(n,"day");)a.push(r.clone()),r.add(1,"day");if(a.some(i))return e.checkInDate(t.format("YYYY-MM-DD")),e.checkOutDate(n.format("YYYY-MM-DD")),e.isUnavailable(!0),e.unavailabilityReason("locked-range"),e.syncDatePickers(),void e.checkAvailability();e.checkInDate(t.format("YYYY-MM-DD")),e.checkOutDate(n.format("YYYY-MM-DD")),e.syncDatePickers(),e.checkAvailability()})}})};e.inlinePicker=t({element:document.getElementById("availability-picker-inline"),parentEl:document.getElementById("litepicker-inline-container"),inlineMode:!0}),e.popupPicker=t({element:document.getElementById("availability-picker-popup"),inlineMode:!1}),e.unavailableDates.subscribe(i=>{e.inlinePicker&&e.inlinePicker.setOptions({lockDays:i}),e.popupPicker&&e.popupPicker.setOptions({lockDays:i})})},e.syncDatePickers=function(){const i=e.checkInDate(),t=e.checkOutDate();if(i&&t){const n=new Date(i),a=new Date(t);if(e.popupPicker){const i=e.popupPicker.getStartDate()?.getTime(),t=e.popupPicker.getEndDate()?.getTime();i===n.getTime()&&t===a.getTime()||e.popupPicker.setDateRange(n,a,!0)}if(e.inlinePicker){const i=e.inlinePicker.getStartDate()?.getTime(),t=e.inlinePicker.getEndDate()?.getTime();i===n.getTime()&&t===a.getTime()||e.inlinePicker.setDateRange(n,a,!0)}}},e.guests.subscribe(i=>{e.checkAvailability()}),e.updatePickerLayout=()=>{const i=window.innerWidth<768?{numberOfMonths:1,numberOfColumns:1}:{numberOfMonths:2,numberOfColumns:2};e.inlinePicker&&e.inlinePicker.setOptions(i),e.popupPicker&&e.popupPicker.setOptions(i)},e.checkAvailability()}function BookingModel(){this.availabilityModel=new AvailabilityModel}const SLUG=window.location.pathname.split("/").filter(Boolean).pop(),bookingsView=new BookingModel;document.addEventListener("DOMContentLoaded",()=>{ko.applyBindings(bookingsView,document.getElementById("root"))});