/* Sea La Vie — booking widget (production v3, posts to api.php) */
const { useState, useRef, useEffect, useMemo } = React;

function OrnamentRow() {
  return (
    <div className="ornament-row">
      <span></span><span className="dot"></span><span></span>
    </div>
  );
}

function MonthCalendar({ year, month, onPick, range, setMonth, showPrices, isUnavailable, priceUSD }) {
  const dim = daysInMonth(year, month);
  const fdow = firstDow(year, month);
  const today = new Date();
  today.setHours(0,0,0,0);
  const [currency] = useCurrency();

  const cells = [];
  for (let i = 0; i < fdow; i++) cells.push(<div key={`e${i}`} className="cal-day empty"></div>);
  for (let d = 1; d <= dim; d++) {
    const date = new Date(year, month, d);
    const key = dateKey(year, month, d);
    const past = date < today;
    const unav = !past && isUnavailable && isUnavailable(key);
    let cls = "cal-day";
    if (past) cls += " disabled";
    else if (unav) cls += " unavailable";

    let inRange = false, isStart = false, isEnd = false;
    if (range && range[0] && range[1]) {
      if (date.getTime() === range[0].getTime()) isStart = true;
      else if (date.getTime() === range[1].getTime()) isEnd = true;
      else if (date > range[0] && date < range[1]) inRange = true;
    } else if (range && range[0] && date.getTime() === range[0].getTime()) {
      isStart = true;
    }
    if (inRange) cls += " in-range";
    if (isStart) cls += " range-start selected";
    if (isEnd) cls += " range-end selected";

    const dow = date.getDay();
    const isWeekend = dow === 0 || dow === 6;
    const baseUSD = priceUSD || 440;
    const dayPriceUSD = isWeekend ? Math.round(baseUSD * 1.3) : baseUSD;
    const price = formatPrice(dayPriceUSD, currency);

    cells.push(
      <div key={d} className={cls} onClick={() => !past && !unav && onPick && onPick(date)}>
        {d}
        {showPrices && !past && !unav && !isStart && !isEnd && !inRange && (
          <span className="price-tag">{price}</span>
        )}
      </div>
    );
  }

  return (
    <div className="cal-month">
      <div className="cal-header">
        {setMonth ? <button className="cal-nav" onClick={() => setMonth(-1)}>‹</button> : <span style={{width:24}}></span>}
        <div className="cal-title">{MONTHS[month]} {year}</div>
        {setMonth ? <button className="cal-nav" onClick={() => setMonth(1)}>›</button> : <span style={{width:24}}></span>}
      </div>
      <div className="cal-grid">
        {DOW.map((d, i) => <div key={i} className="cal-dow">{d}</div>)}
        {cells}
      </div>
    </div>
  );
}

function DateRangePopover({ range, onChange, onClose, isUnavailable, priceUSD }) {
  const [year, setYear] = useState(() => range && range[0] ? range[0].getFullYear() : 2026);
  const [month, setMonthState] = useState(() => range && range[0] ? range[0].getMonth() : 10);
  const ref = useRef(null);

  useEffect(() => {
    function onClick(e) { if (ref.current && !ref.current.contains(e.target)) onClose(); }
    document.addEventListener("mousedown", onClick);
    return () => document.removeEventListener("mousedown", onClick);
  }, [onClose]);

  function shift(delta) {
    let m = month + delta, y = year;
    while (m < 0) { m += 12; y -= 1; }
    while (m > 11) { m -= 12; y += 1; }
    setMonthState(m); setYear(y);
  }

  function pick(date) {
    if (!range[0] || (range[0] && range[1])) onChange([date, null]);
    else if (date <= range[0]) onChange([date, null]);
    else {
      let hasUnav = false;
      for (let dt = new Date(range[0]); dt < date; dt.setDate(dt.getDate() + 1)) {
        if (isUnavailable && isUnavailable(dateKeyFor(dt))) { hasUnav = true; break; }
      }
      if (hasUnav) onChange([date, null]);
      else onChange([range[0], date]);
    }
  }

  const isMobile = typeof window !== "undefined" && window.innerWidth < 760;
  const nextMonth = month === 11 ? 0 : month + 1;
  const nextYear  = month === 11 ? year + 1 : year;

  return (
    <div className="cal-pop wide" ref={ref} onClick={e => e.stopPropagation()}>
      <MonthCalendar year={year} month={month} onPick={pick} range={range} setMonth={shift} showPrices isUnavailable={isUnavailable} priceUSD={priceUSD} />
      {!isMobile && (
        <MonthCalendar year={nextYear} month={nextMonth} onPick={pick} range={range} showPrices isUnavailable={isUnavailable} priceUSD={priceUSD} />
      )}
      <div style={{position:"absolute", bottom: 16, left: 24, right: 24, display:"flex", justifyContent:"space-between", alignItems:"center", flexWrap:"wrap", gap: 12}}>
        <div className="cal-legend">
          <span><span className="sw avail"></span>Available</span>
          <span><span className="sw sel"></span>Your stay</span>
          <span><span className="sw unav"></span>Reserved</span>
        </div>
        <button className="btn-line" style={{padding:"6px 0", fontSize: 10}} onClick={onClose}>Apply <span className="arrow"></span></button>
      </div>
    </div>
  );
}

function GuestPopover({ guests, onChange, onClose, maxGuests }) {
  const ref = useRef(null);
  useEffect(() => {
    function onClick(e) { if (ref.current && !ref.current.contains(e.target)) onClose(); }
    document.addEventListener("mousedown", onClick);
    return () => document.removeEventListener("mousedown", onClick);
  }, [onClose]);

  const totalCounting = guests.adults + guests.children;
  const cap = maxGuests || 4;

  function step(key, delta, min = 0) {
    if (delta > 0 && (key === "adults" || key === "children")) {
      if (totalCounting >= cap) return;
    }
    const v = Math.max(min, guests[key] + delta);
    onChange({ ...guests, [key]: v });
  }

  const rows = [
    { key: "adults", l: "Adults", s: "Ages 13+", min: 1 },
    { key: "children", l: "Children", s: "Ages 4 – 12", min: 0 },
    { key: "infants", l: "Infants", s: "Under 4 · doesn't count toward max", min: 0 }
  ];

  return (
    <div className="guest-pop" ref={ref} onClick={e => e.stopPropagation()}>
      <div style={{padding: "0 0 14px", marginBottom: 6, borderBottom: "1px solid var(--line-soft)", fontSize: 11, letterSpacing: "0.18em", textTransform: "uppercase", color: "var(--ink-mute)"}}>
        Up to {cap} guests per residence
      </div>
      {rows.map(r => {
        const isCounted = r.key === "adults" || r.key === "children";
        const canInc = !isCounted || totalCounting < cap;
        return (
          <div className="guest-row" key={r.key}>
            <div className="label-block"><div className="l">{r.l}</div><div className="s">{r.s}</div></div>
            <div className="guest-stepper">
              <button onClick={() => step(r.key, -1, r.min)} disabled={guests[r.key] <= r.min}>−</button>
              <div className="count">{guests[r.key]}</div>
              <button onClick={() => step(r.key, 1, r.min)} disabled={(isCounted && !canInc) || guests[r.key] >= cap}>+</button>
            </div>
          </div>
        );
      })}
    </div>
  );
}

function VillaPopover({ value, onChange, onClose, availability, range }) {
  const ref = useRef(null);
  useEffect(() => {
    function onClick(e) { if (ref.current && !ref.current.contains(e.target)) onClose(); }
    document.addEventListener("mousedown", onClick);
    return () => document.removeEventListener("mousedown", onClick);
  }, [onClose]);

  function isVillaAvailable(villaId) {
    if (!range || !range[0] || !range[1]) return true;
    const list = availability[villaId] || [];
    for (let dt = new Date(range[0]); dt < range[1]; dt.setDate(dt.getDate() + 1)) {
      if (list.includes(dateKeyFor(dt))) return false;
    }
    return true;
  }

  return (
    <div className="villa-pop" ref={ref} onClick={e => e.stopPropagation()}>
      <button onClick={() => { onChange("any"); onClose(); }}>
        <div>
          <div className="vl">All four residences</div>
          <div className="vs">Whole estate buyout</div>
        </div>
        <div className="stat avail">Enquire</div>
      </button>
      {VILLAS.map(v => {
        const avail = isVillaAvailable(v.id);
        return (
          <button key={v.id} onClick={() => { onChange(v.id); onClose(); }}>
            <div>
              <div className="vl">{v.name.join(" ")}</div>
              <div className="vs">{v.badge}</div>
            </div>
            <div className={`stat ${avail ? "avail" : "unav"}`}>{avail ? "Available" : "On request"}</div>
          </button>
        );
      })}
    </div>
  );
}

function ConfirmReservation({ booking, onClose, onConfirmed }) {
  const [step, setStep] = useState("review");
  const [ref, setRef] = useState("");
  const [submitting, setSubmitting] = useState(false);
  const [error, setError] = useState("");
  const [form, setForm] = useState({ name: "", email: "", phone: "", message: "" });
  const [currency] = useCurrency();

  const { range, villaId, guests } = booking;
  const villa = VILLAS.find(v => v.id === villaId);
  const villaName = villa ? villa.name.join(" ") : "All Four Residences";
  const nights = Math.max(1, Math.round((range[1] - range[0]) / 86400000));
  // Estate buyout = sum of all four villas
  const baseUSD = villa ? villa.priceUSD : VILLAS.reduce((s, v) => s + v.priceUSD, 0);
  const subtotal = baseUSD * nights;
  const fee = Math.round(subtotal * 0.06);
  const tax = Math.round(subtotal * 0.16);
  const total = subtotal + fee + tax;
  const totalGuests = guests.adults + guests.children;
  const fp = (usd) => formatPrice(usd, currency);

  function up(k, v) { setForm(prev => ({ ...prev, [k]: v })); }

  async function confirm() {
    setError("");
    if (!form.name.trim() || !form.email.trim()) {
      setError("Please share your name and email so we can confirm with you.");
      return;
    }
    setSubmitting(true);

    // Build date keys (exclusive of departure)
    const dateKeys = [];
    for (let dt = new Date(range[0]); dt < range[1]; dt.setDate(dt.getDate() + 1)) {
      dateKeys.push(dateKeyFor(dt));
    }

    const payload = {
      villaId,
      arrival: dateKeyFor(range[0]),
      departure: dateKeyFor(range[1]),
      nights,
      guests: totalGuests,
      dateKeys,
      name: form.name.trim(),
      email: form.email.trim(),
      phone: form.phone.trim(),
      message: form.message.trim()
    };

    try {
      const r = await apiBook(payload);
      if (r && r.ok) {
        setRef(r.ref);
        setStep("success");
        onConfirmed(r.ref, dateKeys);
      } else {
        setError(r && r.error ? r.error : "Could not submit. Please try again or email us directly.");
      }
    } catch (e) {
      // Backend not available — fall back to mailto
      const subj = encodeURIComponent(`Reservation enquiry — ${villaName} · ${fmtDate(range[0])} → ${fmtDate(range[1])}`);
      const body = encodeURIComponent(
        `Hello Sea La Vie team,\n\nI'd like to reserve ${villaName} for ${nights} night${nights>1?"s":""}.\n\n` +
        `Arrival: ${fmtDate(range[0])}\nDeparture: ${fmtDate(range[1])}\nGuests: ${totalGuests}\n\n` +
        `Name: ${form.name}\nEmail: ${form.email}\nPhone: ${form.phone}\n\n${form.message}\n\nThank you,`
      );
      window.location.href = `mailto:${CONTACT.email}?subject=${subj}&body=${body}`;
      setRef("SLV-EMAIL");
      setStep("success");
      onConfirmed("SLV-EMAIL", dateKeys);
    } finally {
      setSubmitting(false);
    }
  }

  return (
    <div className="modal-backdrop" onClick={onClose}>
      <div className="confirm-modal" onClick={e => e.stopPropagation()}>
        {step === "review" && (
          <>
            <div className="head">
              <button className="modal-close" onClick={onClose}>×</button>
              <div className="eyebrow">Confirm reservation</div>
              <h2>Your stay at <em>{villaName}</em></h2>
              <p>Tell us where to reach you and we'll hold the residence for fifteen minutes while a curator personally confirms.</p>
            </div>
            <div className="body">
              <div className="summary">
                <div><div className="l">Arrival</div><div className="v">{fmtDate(range[0])}</div></div>
                <div><div className="l">Departure</div><div className="v">{fmtDate(range[1])}</div></div>
                <div><div className="l">Residence</div><div className="v">{villaName}</div></div>
                <div><div className="l">Guests</div><div className="v">{totalGuests} · {nights} night{nights>1?"s":""}</div></div>
              </div>

              <div className="form-grid">
                <div className="field-group full">
                  <label>Full Name</label>
                  <input type="text" value={form.name} onChange={e => up("name", e.target.value)} placeholder="As it appears on your passport" />
                </div>
                <div className="field-group">
                  <label>Email</label>
                  <input type="email" value={form.email} onChange={e => up("email", e.target.value)} placeholder="you@example.com" />
                </div>
                <div className="field-group">
                  <label>Phone</label>
                  <input type="tel" value={form.phone} onChange={e => up("phone", e.target.value)} placeholder="+254 …" />
                </div>
                <div className="field-group full">
                  <label>Special requests</label>
                  <input type="text" value={form.message} onChange={e => up("message", e.target.value)} placeholder="Anniversary, dietary needs, airport transfer…" />
                </div>
              </div>

              <div className="price-row"><span>{fp(baseUSD)} × {nights} nights</span><span>{fp(subtotal)}</span></div>
              <div className="price-row"><span>Concierge fee</span><span>{fp(fee)}</span></div>
              <div className="price-row"><span>VAT (16%)</span><span>{fp(tax)}</span></div>
              <div className="total"><div className="lbl">Total in {currency}</div><div className="amt">{fp(total)}</div></div>

              {error && <div className="err-msg" style={{marginTop: 14}}>{error}</div>}
            </div>
            <div className="actions">
              <button className="ghost" onClick={onClose} disabled={submitting}>Cancel</button>
              <button className="submit" onClick={confirm} disabled={submitting}>{submitting ? "Sending…" : "Confirm reservation"}</button>
            </div>
          </>
        )}
        {step === "success" && (
          <div className="success-state">
            <div className="check">✓</div>
            <div className="eyebrow">Reservation received</div>
            <h2>Karibu — <em>welcome</em></h2>
            <div className="ref">{ref}</div>
            <p style={{maxWidth: 460, margin: "0 auto", color: "var(--ink-soft)", fontSize: 14, lineHeight: 1.7}}>
              A confirmation has been sent to <strong>{form.email}</strong>. Your travel curator will reach out from <strong>{CONTACT.email}</strong> within twenty-four hours to finalise payment and begin planning your time on the coast.
            </p>
            <button className="submit" style={{maxWidth: 220, margin: "32px auto 0"}} onClick={onClose}>Close</button>
          </div>
        )}
      </div>
    </div>
  );
}

function BookingWidget({ initialVilla }) {
  const [active, setActive] = useState("Reserve");
  const [open, setOpen] = useState(null);
  const [range, setRange] = useState([new Date(2026, 10, 14), new Date(2026, 10, 21)]);
  const [guests, setGuests] = useState({ adults: 2, children: 0, infants: 0 });
  const [villaId, setVillaId] = useState(initialVilla || "bahari");
  const [showConfirm, setShowConfirm] = useState(false);
  const avail = useAvailability();

  const tabs = ["Reserve", "Residences", "Experiences", "Wellness", "Dining"];
  const totalGuests = guests.adults + guests.children;

  function guestLabel() {
    const parts = [`${totalGuests} ${totalGuests === 1 ? "Guest" : "Guests"}`];
    if (guests.infants) parts.push(`${guests.infants} Infant${guests.infants > 1 ? "s" : ""}`);
    return parts.join(" · ");
  }

  function isUnavailable(key) {
    if (villaId === "any") return avail.anyBooked(key);
    return avail.isBooked(villaId, key);
  }

  function handleTabClick(t) {
    setActive(t);
    const routes = {
      "Residences": "residences.html",
      "Experiences": "experiences.html",
      "Wellness": "wellness.html",
      "Dining": "cuisine.html"
    };
    if (routes[t]) window.location.href = routes[t];
  }

  function attemptReserve() {
    if (!range[0] || !range[1]) { setOpen("dates"); return; }
    if (villaId === "any") {
      // For "any" we send straight to the confirm flow as an enquiry
      setShowConfirm(true);
      return;
    }
    for (let dt = new Date(range[0]); dt < range[1]; dt.setDate(dt.getDate()+1)) {
      if (avail.isBooked(villaId, dateKeyFor(dt))) {
        alert("Those dates are no longer fully available. Please choose new dates or another residence.");
        setOpen("dates");
        return;
      }
    }
    setShowConfirm(true);
  }

  function handleConfirmed(ref, dateKeys) {
    if (villaId !== "any") avail.addBooking(villaId, dateKeys);
  }

  const villa = VILLAS.find(v => v.id === villaId);
  const villaName = villa ? villa.name.join(" ") : "All residences";
  const villaSub  = villa ? villa.badge : "Whole estate";

  return (
    <>
      <div className="booking-widget" id="booking">
        <div className="booking-tabs">
          {tabs.map(t => (
            <button key={t} className={active === t ? "active" : ""} onClick={() => handleTabClick(t)}>{t}</button>
          ))}
        </div>
        <div className="booking-form">
          <div className="booking-field" onClick={() => setOpen(open === "dates" ? null : "dates")}>
            <div className="label">Arrival</div>
            <div className="value">{range[0] ? fmtShort(range[0]) : "Select date"}</div>
            <div className="sub">{range[0] ? range[0].getFullYear() : "When the holiday begins"}</div>
            {open === "dates" && <DateRangePopover range={range} onChange={setRange} onClose={() => setOpen(null)} isUnavailable={isUnavailable} priceUSD={villa ? villa.priceUSD : 440} />}
          </div>
          <div className="booking-field" onClick={() => setOpen(open === "dates" ? null : "dates")}>
            <div className="label">Departure</div>
            <div className="value">{range[1] ? fmtShort(range[1]) : "Select date"}</div>
            <div className="sub">{range[1] ? `${Math.round((range[1]-range[0])/86400000)} nights` : "Until you must return"}</div>
          </div>
          <div className="booking-field" onClick={() => setOpen(open === "guests" ? null : "guests")}>
            <div className="label">Guests</div>
            <div className="value">{guestLabel()}</div>
            <div className="sub">Ages 13 and over</div>
            {open === "guests" && <GuestPopover guests={guests} onChange={setGuests} onClose={() => setOpen(null)} maxGuests={villaId === "any" ? 16 : 4} />}
          </div>
          <div className="booking-field" onClick={() => setOpen(open === "villa" ? null : "villa")}>
            <div className="label">Residence</div>
            <div className="value">{villaName}</div>
            <div className="sub">{villaSub}</div>
            {open === "villa" && <VillaPopover value={villaId} onChange={setVillaId} onClose={() => setOpen(null)} availability={avail.data} range={range} />}
          </div>
          <button className="booking-search" onClick={attemptReserve}>Reserve</button>
        </div>
      </div>

      {showConfirm && (
        <ConfirmReservation
          booking={{ range, villaId, guests }}
          onClose={() => setShowConfirm(false)}
          onConfirmed={handleConfirmed}
        />
      )}
    </>
  );
}

Object.assign(window, { OrnamentRow, MonthCalendar, BookingWidget, DateRangePopover, GuestPopover, VillaPopover, ConfirmReservation });
