/* Booking bar + apartment detail modal + Smoobu booking modal */

const { useState: useStateBk, useEffect: useEffectBk, useRef: useRefBk } = React;

/* Smoobu booking-tool settings id (all apartments) */
const SMOOBU_BOOKING_ID = "1764342";

/* The all-apartments view of a Smoobu booking tool shows EVERY property in the
   account — there is no way to untick one in the dashboard. Casa Laudieri's
   account also holds a Meran property that is not part of this house, so the
   unfiltered view has to be narrowed with Smoobu's documented group filter:
     ?apartmentGroups[]=<id>&apartmentGroups[]=<id>…
   Keep this list in step with SMOOBU_APT_IDS in app.jsx. */
const SMOOBU_GROUP_IDS = [3341847, 3341852, 3341857];

function BookingBar({ t, apartments, onBook, initialApt }) {
  const [apt, setApt] = useStateBk(initialApt || 'any');
  const [open, setOpen] = useStateBk(false);
  const wrapRef = useRefBk(null);

  useEffectBk(() => {
    if (!open) return;
    const onDoc = (e) => { if (wrapRef.current && !wrapRef.current.contains(e.target)) setOpen(false); };
    document.addEventListener('mousedown', onDoc);
    return () => document.removeEventListener('mousedown', onDoc);
  }, [open]);

  const floorOf = (a) => (a.sub || '').split('·')[0].trim();
  const labelFor = (id) => {
    if (id === 'any') return t.booking.any;
    const a = apartments.find((x) => x.id === id);
    return a ? `${a.name} · ${floorOf(a)}` : t.booking.any;
  };
  const choose = (id) => { setApt(id); setOpen(false); };

  return (
    <div className="booking-bar booking-bar--simple reveal-repeat">
      <div className="field apt-select" ref={wrapRef}>
        <label>{t.booking.apartment}</label>
        <button type="button" className={"apt-select-trigger" + (open ? " open" : "")} onClick={() => setOpen((v) => !v)} aria-haspopup="listbox" aria-expanded={open}>
          <span>{labelFor(apt)}</span>
          <span className="apt-select-caret" aria-hidden="true">⌄</span>
        </button>
        {open &&
        <ul className="apt-select-menu" role="listbox">
            <li role="option" aria-selected={apt === 'any'} className={apt === 'any' ? 'sel' : ''} onClick={() => choose('any')}>{t.booking.any}</li>
            {apartments.map((a) =>
          <li key={a.id} role="option" aria-selected={apt === a.id} className={apt === a.id ? 'sel' : ''} onClick={() => choose(a.id)}>{a.name} · {floorOf(a)}</li>
          )}
          </ul>
        }
      </div>
      <button className="btn btn-solid" onClick={() => onBook({ apt })}>
        {t.booking.cta}
        <span style={{ marginLeft: 4 }}>→</span>
      </button>
    </div>);

}

/* ---------- Booking modal ---------- */
/* Smoobu's own embed snippet, verbatim from the booking-tool settings page:
 *   <div id="apartmentIframeAll">
 *   <script src="https://login.smoobu.com/js/Settings/BookingToolIframe.js"><\/script>
 *   <script>BookingToolIframe.initialize({"url":
 *     "https://login.smoobu.com/en/booking-tool/iframe/1764342",
 *     "baseUrl": "https://login.smoobu.com",
 *     "target": "#apartmentIframeAll"})<\/script>
 *   </div>
 *
 * Per Smoobu's "show only some of your properties in one embed" guide, the URL
 * carries one apartmentGroups[] entry per property, joined with &, so the tool
 * lists only this house's three and not Meran.
 *
 * Run from an effect rather than inline markup, because React owns this DOM
 * and the modal mounts after page load. */

const SMOOBU_IFRAME_URL =
  `https://login.smoobu.com/en/booking-tool/iframe/${SMOOBU_BOOKING_ID}` +
  '?' + SMOOBU_GROUP_IDS.map((id) => `apartmentGroups[]=${id}`).join('&');

const MODAL_CLOSE = { en: 'Close', it: 'Chiudi', de: 'Schließen' };

/* ---------- Modal accessibility ----------
   Neither modal handled Escape or contained focus: a keyboard user could tab
   out of an open dialog into the page behind it, with no way to close. This
   hook adds Escape-to-close, cycles Tab within the dialog, and restores focus
   to whatever opened it. */
function useModalA11y(open, onClose) {
  const ref = useRefBk(null);
  const returnTo = useRefBk(null);
  useEffectBk(() => {
    if (!open) return;
    returnTo.current = document.activeElement;
    const node = ref.current;
    const sel = 'a[href],button:not([disabled]),input:not([disabled]),select,textarea,[tabindex]:not([tabindex="-1"])';
    const focusables = () => Array.from(node ? node.querySelectorAll(sel) : []).filter((el) => el.offsetParent !== null);
    /* The overlay is still mid-transition on the tick the open prop flips, so
       its children have no offsetParent yet and focusables() would come back
       empty. Wait for the next frame, then fall back to the dialog itself. */
    let raf = requestAnimationFrame(() => {
      const first = focusables()[0];
      if (first) first.focus();
      else if (node) node.focus();
    });
    const onKey = (e) => {
      if (e.key === 'Escape') { e.stopPropagation(); onClose && onClose(); return; }
      if (e.key !== 'Tab') return;
      const f = focusables();
      if (!f.length) return;
      const a = f[0], z = f[f.length - 1];
      /* If focus has escaped the dialog (or never entered it), pull it back:
         without this the browser's default Tab walks into the page behind. */
      if (!node || !node.contains(document.activeElement)) {
        e.preventDefault();
        (e.shiftKey ? z : a).focus();
        return;
      }
      if (e.shiftKey && document.activeElement === a) { e.preventDefault(); z.focus(); }
      else if (!e.shiftKey && document.activeElement === z) { e.preventDefault(); a.focus(); }
    };
    document.addEventListener('keydown', onKey, true);
    return () => {
      cancelAnimationFrame(raf);
      document.removeEventListener('keydown', onKey, true);
      if (returnTo.current && returnTo.current.focus) returnTo.current.focus();
    };
  }, [open, onClose]);
  return ref;
}

function SmoobuModal({ open, onClose, lang, t, params }) {
  const dialogRef = useModalA11y(open, onClose);
  useEffectBk(() => {
    if (!open) {document.body.style.overflow = '';return;}
    document.body.style.overflow = 'hidden';
    let cancelled = false;

    function init() {
      if (cancelled || !window.BookingToolIframe) return;
      const el = document.getElementById('apartmentIframeAll');
      if (!el) return;
      el.innerHTML = '';
      window.BookingToolIframe.initialize({
        "url": SMOOBU_IFRAME_URL,
        "baseUrl": "https://login.smoobu.com",
        "target": "#apartmentIframeAll"
      });
    }

    if (window.BookingToolIframe) {
      init();
    } else {
      let s = document.getElementById('smoobu-bt-js');
      if (!s) {
        s = document.createElement('script');
        s.id = 'smoobu-bt-js';
        s.type = 'text/javascript';
        s.src = 'https://login.smoobu.com/js/Settings/BookingToolIframe.js';
        document.body.appendChild(s);
      }
      s.addEventListener('load', init);
    }

    return () => {cancelled = true;document.body.style.overflow = '';};
  }, [open]);

  return (
    <div className={"modal-overlay" + (open ? " open" : "")} onClick={onClose}>
      <div className="modal smoobu-modal" ref={dialogRef} role="dialog" aria-modal="true" tabIndex={-1} aria-label={t.nav.book} onClick={(e) => e.stopPropagation()}>
        <div className="modal-head">
          <div>
            <h2 className="display display-s serif">{t.nav.book}</h2>
          </div>
          <button className="modal-close" aria-label={MODAL_CLOSE[lang] || MODAL_CLOSE.en} onClick={onClose}>×</button>
        </div>
        <div className="modal-body">
          <div id="apartmentIframeAll" key={open ? 'on' : 'off'}></div>
        </div>
      </div>
    </div>);

}

/* ---------- Apartment gallery (click-through, 10 slots each) ---------- */

function AptGallery({ apt }) {
  const [idx, setIdx] = useStateBk(0);
  useEffectBk(() => { setIdx(0); }, [apt && apt.id]);
  if (!apt) return null;
  // Build the slide list from available images: slot 1 = the preview photo,
  // then any gal-<id>-N that has a wired source. Empty slots are skipped.
  const sids = [`apt-${apt.id}`];
  for (let n = 2; n <= 10; n++) {
    sids.push(`gal-${apt.id}-${n}`);
  }
  const count = sids.length;
  const go = (d) => setIdx((p) => (p + d + count) % count);
  const cur = Math.min(idx, count - 1);
  return (
    <div className="apt-gallery">
      <div className="apt-gallery-stage">
        {sids.map((sid, i) =>
        <div key={sid} className="apt-gallery-slide" style={{ opacity: i === cur ? 1 : 0, pointerEvents: i === cur ? 'auto' : 'none' }}>
            <Ph slot={sid} label={`${apt.name} · ${i + 1}`} seed={i + 1} aspect="16 / 10" src={CASA_PHOTOS[sid]} locked />
          </div>
        )}
        {count > 1 &&
        <React.Fragment>
            <button type="button" className="apt-gallery-nav prev" onClick={() => go(-1)} aria-label="Previous">‹</button>
            <button type="button" className="apt-gallery-nav next" onClick={() => go(1)} aria-label="Next">›</button>
          </React.Fragment>
        }
      </div>
      {count > 1 &&
      <div className="apt-gallery-dots">
          {sids.map((sid, i) =>
        <button key={sid} type="button" className={"apt-gallery-dot" + (i === cur ? " on" : "")} onClick={() => setIdx(i)} aria-label={`Image ${i + 1}`}></button>
        )}
        </div>
      }
    </div>);

}

/* ---------- Apartment detail modal ---------- */

function ApartmentModal({ apt, lang, t, open, onClose, onReserve }) {
  const dialogRef = useModalA11y(open, onClose);
  useEffectBk(() => {if (open) {document.body.style.overflow = 'hidden';} else {document.body.style.overflow = '';}}, [open]);

  if (!apt) return null;

  return (
    <div className={"modal-overlay" + (open ? " open" : "")} onClick={onClose}>
      <div className="modal" ref={dialogRef} role="dialog" aria-modal="true" tabIndex={-1} aria-label={apt.name} onClick={(e) => e.stopPropagation()}>
        <div className="modal-head">
          <div>
            <div className="eyebrow">{apt.sub}</div>
            <h2 className="display display-s serif" style={{ marginTop: 4 }}>{apt.name}</h2>
          </div>
          <button className="modal-close" aria-label={MODAL_CLOSE[lang] || MODAL_CLOSE.en} onClick={onClose}>×</button>
        </div>
        <div className="modal-body">
          <AptGallery apt={apt} />
          <p className="body-l" style={{ margin: '12px 0 0' }}>{apt.desc}</p>

          <div className="specs-grid">
            <div><div className="lbl">{t.apartments.sleeps}</div><div className="val">{apt.sleeps}</div></div>
            <div><div className="lbl">{t.apartments.sizeLabel || 'Size'}</div><div className="val">{apt.size}</div></div>
            <div><div className="lbl">{t.apartments.roomsLabel || 'Rooms'}</div><div className="val">{apt.bedrooms}</div></div>
          </div>

          <div className="eyebrow" style={{ marginBottom: 16 }}>{t.apartments.amenitiesLabel || 'Amenities'}</div>
          <ul className="amenities">
            {apt.amenities.map((a, i) => <li key={i}>{a}</li>)}
          </ul>

          <div className="apt-book-cta">
            <div>
              <div className="numeral" style={{ fontSize: 28, color: 'var(--ink)' }}>
                <span className="body-s" style={{ marginRight: 8, color: 'var(--mute)' }}>{t.apartments.from}</span>
                {apt.price}
                <span className="body-s" style={{ marginLeft: 6 }}>· {t.apartments.perNight}</span>
              </div>
              <p className="body-s" style={{ marginTop: 6 }}>{t.apartments.seasonalNote}</p>
            </div>
            <button className="btn btn-solid" onClick={() => onReserve(apt)}>
              {t.booking.cta}
              <span style={{ marginLeft: 4 }}>→</span>
            </button>
          </div>
        </div>
      </div>
    </div>);

}

Object.assign(window, { BookingBar, ApartmentModal, SmoobuModal });
