/* global React */

function CTAStrip({ title, body, primaryLabel = "Check Availability", secondaryLabel = null, onPrimary, onSecondary }) {
  return (
    <section className="ws-cta-strip">
      <div className="ws-cta-strip__inner">
        <div style={{ flex: "0 0 auto", color: "var(--ws-gold)", display: "flex", alignItems: "center", gap: 24 }}>
          <svg width="80" height="80" viewBox="0 0 80 80" fill="none" stroke="currentColor" strokeWidth="1" strokeLinecap="round" strokeLinejoin="round">
            <path d="M14 70 V36 L40 18 L66 36 V70" />
            <path d="M28 70 V52 H52 V70" />
            <line x1="36" y1="40" x2="36" y2="50" />
            <line x1="44" y1="40" x2="44" y2="50" />
            <path d="M14 70 H6 M66 70 H74" />
            <path d="M10 74 Q14 68 18 74 Q22 70 26 74" opacity=".5" />
            <path d="M54 74 Q58 68 62 74 Q66 70 70 74" opacity=".5" />
          </svg>
        </div>
        <div style={{ flex: 1 }}>
          <h3 className="ws-cta-strip__title">{title}</h3>
          {body && <p className="ws-cta-strip__body">{body}</p>}
        </div>
        <div className="ws-cta-strip__actions">
          <button className="ws-btn ws-btn--gold" onClick={onPrimary}>{primaryLabel}</button>
          {secondaryLabel && onSecondary && (
            <button className="ws-btn ws-btn--text" onClick={onSecondary} style={{ color: "var(--ws-gold)" }}>
              {secondaryLabel} →
            </button>
          )}
        </div>
      </div>
    </section>
  );
}

function Benefits({ items }) {
  return (
    <div className="ws-benefits">
      {items.map((b, i) => (
        <div className="ws-benefit" key={i}>
          <div className="ws-benefit__icon"><Icon name={b.icon} size={26} strokeWidth={1.25} /></div>
          <h4 className="ws-benefit__title">{b.title}</h4>
          <p className="ws-benefit__text">{b.text}</p>
        </div>
      ))}
    </div>
  );
}

function RoomCard({ photo, title, text, onClick }) {
  return (
    <div className="ws-room-card" onClick={onClick} role="button" tabIndex={0}
         onKeyDown={(e) => { if (onClick && (e.key === "Enter" || e.key === " ")) { e.preventDefault(); onClick(); } }}
         style={{ cursor: onClick ? "pointer" : "default" }}>
      <div className="ws-room-card__photo" style={{ backgroundImage: `url(${photo})` }} />
      <div className="ws-room-card__body">
        <h3 className="ws-room-card__title">{title}</h3>
        <p className="ws-room-card__text">{text}</p>
        <span className="ws-room-card__link">View Details <Icon name="arrow-right" size={12} /></span>
      </div>
    </div>
  );
}

// Lightbox-style modal that opens when a RoomCard is clicked.
// Pass a room object: { photos: [...], title, text, long, amenities: [{icon,label}, ...] }
function RoomModal({ room, onClose, onBook }) {
  const [idx, setIdx] = React.useState(0);
  React.useEffect(() => { setIdx(0); }, [room]);
  React.useEffect(() => {
    if (!room) return;
    const photos = room.photos || [];
    const onKey = (e) => {
      if (e.key === "Escape") onClose();
      if (e.key === "ArrowLeft"  && photos.length > 1) setIdx((i) => (i - 1 + photos.length) % photos.length);
      if (e.key === "ArrowRight" && photos.length > 1) setIdx((i) => (i + 1) % photos.length);
    };
    document.addEventListener("keydown", onKey);
    const prev = document.body.style.overflow;
    document.body.style.overflow = "hidden";
    return () => {
      document.removeEventListener("keydown", onKey);
      document.body.style.overflow = prev;
    };
  }, [room, onClose]);

  if (!room) return null;
  const photos = room.photos || [];
  const cur = photos[idx] || photos[0];
  const multi = photos.length > 1;
  const prev = (e) => { e.stopPropagation(); setIdx((i) => (i - 1 + photos.length) % photos.length); };
  const next = (e) => { e.stopPropagation(); setIdx((i) => (i + 1) % photos.length); };

  return (
    <div className="ws-modal" onClick={onClose}>
      <div className="ws-modal__card" onClick={(e) => e.stopPropagation()}>
        <button className="ws-modal__close" onClick={onClose} aria-label="Close">
          <Icon name="x" size={20} />
        </button>

        <div className="ws-modal__photo-wrap">
          <img className="ws-modal__photo" src={cur} alt={`${room.title} at 59 William Street`} />
          {multi && (
            <React.Fragment>
              <button className="ws-modal__photo-arrow ws-modal__photo-arrow--prev" onClick={prev} aria-label="Previous photo">
                <Icon name="chevron-left" size={18} />
              </button>
              <button className="ws-modal__photo-arrow ws-modal__photo-arrow--next" onClick={next} aria-label="Next photo">
                <Icon name="chevron-right" size={18} />
              </button>
              <div className="ws-modal__photo-count">{idx + 1} / {photos.length}</div>
              <div className="ws-modal__photo-dots">
                {photos.map((_, i) => (
                  <button key={i}
                          className={"ws-modal__photo-dot" + (i === idx ? " is-active" : "")}
                          onClick={(e) => { e.stopPropagation(); setIdx(i); }}
                          aria-label={`Photo ${i + 1}`} />
                ))}
              </div>
            </React.Fragment>
          )}
        </div>

        <div className="ws-modal__body">
          <div className="ws-modal__eyebrow">The Rooms</div>
          <h2 className="ws-modal__title">{room.title}</h2>
          <span className="ws-opener__rule" style={{ marginBottom: 22, color: "var(--ws-gold)" }}>
            <span className="d" />
          </span>
          <p className="ws-modal__text">{room.long || room.text}</p>
          {room.amenities && room.amenities.length > 0 && (
            <ul className="ws-modal__amenities">
              {room.amenities.map((a, i) => (
                <li key={i}><Icon name={a.icon} size={16} /> {a.label}</li>
              ))}
            </ul>
          )}
          <div style={{ display: "flex", gap: 14, marginTop: 30, flexWrap: "wrap" }}>
            <button className="ws-btn ws-btn--gold" onClick={() => { onClose(); onBook && onBook(); }}>Book Your Stay</button>
            <button className="ws-btn ws-btn--text" style={{ color: "var(--ws-gold-deep)" }} onClick={onClose}>
              Back to Rooms
            </button>
          </div>
        </div>
      </div>
    </div>
  );
}

const WS_DATE_DISPLAY = new Intl.DateTimeFormat("en-IE", { day: "2-digit", month: "short", year: "numeric" });
const WS_MONTH_DISPLAY = new Intl.DateTimeFormat("en-IE", { month: "long", year: "numeric" });
const WS_WEEKDAYS = ["Mon", "Tue", "Wed", "Thu", "Fri", "Sat", "Sun"];

function padDatePart(value) {
  return String(value).padStart(2, "0");
}

function toISODate(date) {
  return `${date.getUTCFullYear()}-${padDatePart(date.getUTCMonth() + 1)}-${padDatePart(date.getUTCDate())}`;
}

function fromISODate(value) {
  if (!value) return null;
  const parts = value.split("-").map(Number);
  if (parts.length !== 3 || parts.some(Number.isNaN)) return null;
  return new Date(Date.UTC(parts[0], parts[1] - 1, parts[2]));
}

function addDaysISO(value, days) {
  const date = fromISODate(value);
  if (!date) return "";
  date.setUTCDate(date.getUTCDate() + days);
  return toISODate(date);
}

function addMonths(date, months) {
  return new Date(Date.UTC(date.getUTCFullYear(), date.getUTCMonth() + months, 1));
}

function isoRangeOverlaps(checkIn, checkOut, blockedDates) {
  if (!checkIn || !checkOut || checkOut <= checkIn) return false;
  return blockedDates.some((range) => checkIn < range.end && checkOut > range.start);
}

function isDateBlocked(iso, blockedDates) {
  return blockedDates.some((range) => iso >= range.start && iso < range.end);
}

function formatDateLabel(value) {
  const date = fromISODate(value);
  return date ? WS_DATE_DISPLAY.format(date) : "Select date";
}

function buildCalendarDays(monthDate) {
  const year = monthDate.getUTCFullYear();
  const month = monthDate.getUTCMonth();
  const first = new Date(Date.UTC(year, month, 1));
  const offset = (first.getUTCDay() + 6) % 7;
  const total = new Date(Date.UTC(year, month + 1, 0)).getUTCDate();
  const days = Array.from({ length: offset }, () => null);
  for (let day = 1; day <= total; day += 1) {
    days.push(new Date(Date.UTC(year, month, day)));
  }
  while (days.length % 7 !== 0) days.push(null);
  return days;
}

function DatePicker({ label, value, min, onChange, ariaLabel, blockedDates = [] }) {
  const initialMonth = fromISODate(value) || fromISODate(min) || new Date();
  const [open, setOpen] = React.useState(false);
  const [visibleMonth, setVisibleMonth] = React.useState(new Date(Date.UTC(initialMonth.getUTCFullYear(), initialMonth.getUTCMonth(), 1)));
  const wrapRef = React.useRef(null);
  const selected = fromISODate(value);
  const minValue = min || toISODate(new Date());

  React.useEffect(() => {
    const nextMonth = fromISODate(value) || fromISODate(minValue);
    if (nextMonth) setVisibleMonth(new Date(Date.UTC(nextMonth.getUTCFullYear(), nextMonth.getUTCMonth(), 1)));
  }, [value, minValue]);

  React.useEffect(() => {
    if (!open) return;
    const closeFromOutside = (event) => {
      if (wrapRef.current && !wrapRef.current.contains(event.target)) setOpen(false);
    };
    const closeFromEscape = (event) => {
      if (event.key === "Escape") setOpen(false);
    };
    document.addEventListener("mousedown", closeFromOutside);
    document.addEventListener("keydown", closeFromEscape);
    return () => {
      document.removeEventListener("mousedown", closeFromOutside);
      document.removeEventListener("keydown", closeFromEscape);
    };
  }, [open]);

  const minMonth = fromISODate(minValue);
  const previousMonth = addMonths(visibleMonth, -1);
  const previousDisabled = minMonth && (
    previousMonth.getUTCFullYear() < minMonth.getUTCFullYear() ||
    (previousMonth.getUTCFullYear() === minMonth.getUTCFullYear() && previousMonth.getUTCMonth() < minMonth.getUTCMonth())
  );
  const selectDate = (date) => {
    const nextValue = toISODate(date);
    if (nextValue < minValue) return;
    onChange(nextValue);
    setOpen(false);
  };

  return (
    <div className={"ws-date-field" + (open ? " is-open" : "")} ref={wrapRef}>
      <label className="ws-label">{label}</label>
      <button
        type="button"
        className={"ws-date-trigger" + (value ? " has-value" : "")}
        aria-label={ariaLabel}
        aria-expanded={open ? "true" : "false"}
        onClick={() => setOpen((current) => !current)}
      >
        <span>{formatDateLabel(value)}</span>
        <Icon name="calendar-days" size={16} />
      </button>
      {open && (
        <React.Fragment>
        <button className="ws-date-backdrop" type="button" aria-label="Close calendar" onClick={() => setOpen(false)} />
        <div className="ws-date-popover">
          <div className="ws-date-head">
            <button type="button" className="ws-date-nav" aria-label="Previous month" disabled={previousDisabled} onClick={() => setVisibleMonth(previousMonth)}>
              <Icon name="chevron-left" size={16} />
            </button>
            <div className="ws-date-month">{WS_MONTH_DISPLAY.format(visibleMonth)}</div>
            <button type="button" className="ws-date-nav" aria-label="Next month" onClick={() => setVisibleMonth(addMonths(visibleMonth, 1))}>
              <Icon name="chevron-right" size={16} />
            </button>
          </div>
          <div className="ws-date-weekdays">
            {WS_WEEKDAYS.map((day) => <span key={day}>{day}</span>)}
          </div>
          <div className="ws-date-grid">
            {buildCalendarDays(visibleMonth).map((date, index) => {
              if (!date) return <span key={`blank-${index}`} className="ws-date-blank" />;
              const iso = toISODate(date);
              const blocked = isDateBlocked(iso, blockedDates);
              const disabled = iso < minValue || blocked;
              const active = selected && iso === toISODate(selected);
              return (
                <button
                  type="button"
                  key={iso}
                  className={"ws-date-day" + (disabled ? " is-disabled" : "") + (blocked ? " is-blocked" : "") + (active ? " is-selected" : "")}
                  disabled={disabled}
                  title={blocked ? "Unavailable" : undefined}
                  onClick={() => selectDate(date)}
                >
                  {date.getUTCDate()}
                </button>
              );
            })}
          </div>
          <div className={"ws-date-note" + (blockedDates.length ? " has-blocked" : "")}>
            {blockedDates.length ? "Unavailable dates are marked in red." : "No unavailable dates are published by the connected calendar right now."}
          </div>
        </div>
        </React.Fragment>
      )}
    </div>
  );
}

function BookingWidget({ onSubmit, onEnquire }) {
  const today = new Date().toISOString().slice(0, 10);
  const [form, setForm] = React.useState({
    checkIn: "",
    checkOut: "",
    guests: "2",
    bedrooms: "Any",
    name: "",
    email: "",
    phone: "",
    message: "",
  });
  const [status, setStatus] = React.useState({ state: "idle", message: "" });
  const [availability, setAvailability] = React.useState({ blocked: [], loading: true, error: "" });

  React.useEffect(() => {
    let active = true;
    fetch("/api/availability")
      .then((response) => response.json())
      .then((result) => {
        if (!active) return;
        setAvailability({
          blocked: Array.isArray(result.blocked) ? result.blocked : [],
          loading: false,
          error: result.ok ? "" : (result.error || "We can't check the calendar just now. Please send an enquiry or contact us directly."),
        });
      })
      .catch(() => {
        if (active) setAvailability({ blocked: [], loading: false, error: "We can't check the calendar just now. Please send an enquiry or contact us directly." });
      });
    return () => { active = false; };
  }, []);

  const setField = (field, value) => setForm((current) => {
    if (field === "checkIn" && current.checkOut && current.checkOut <= value) {
      return { ...current, checkIn: value, checkOut: "" };
    }
    return { ...current, [field]: value };
  });
  const submit = async () => {
    if (form.checkIn && form.checkOut && form.checkOut <= form.checkIn) {
      setStatus({ state: "error", message: "Please choose a check-out date after check-in." });
      return;
    }
    if (isoRangeOverlaps(form.checkIn, form.checkOut, availability.blocked)) {
      setStatus({ state: "error", message: "Those dates appear unavailable. Please choose different dates or contact us directly." });
      return;
    }
    setStatus({ state: "loading", message: "Sending your enquiry..." });
    const response = await fetch("/api/enquiries", {
      method: "POST",
      headers: { "content-type": "application/json" },
      body: JSON.stringify({ type: "booking", ...form }),
    });
    const result = await response.json();
    if (!response.ok || !result.ok) {
      setStatus({ state: "error", message: result.error || "Please check your dates and contact details, then try again." });
      return;
    }
    setStatus({ state: "sent", message: `Thank you. We've received your enquiry. Reference ${result.reference}.` });
    onSubmit && onSubmit(result.reference);
  };
  const availabilityText = availability.loading
    ? "Checking the booking calendar..."
    : availability.error
      ? availability.error
      : availability.blocked.length
        ? `${availability.blocked.length} unavailable date ${availability.blocked.length === 1 ? "range" : "ranges"} loaded from the Airbnb calendar.`
        : "Airbnb calendar connected. No unavailable dates are published right now.";

  return (
    <div className="ws-booking-card">
      <div className="ws-booking-card__head">
        <div>
          <div className="ws-booking-card__eyebrow">Direct Stay Enquiry</div>
          <h3>Choose Your Dates</h3>
        </div>
        <div className={"ws-booking-card__availability" + (availability.error ? " is-error" : "")}>
          {availabilityText}
        </div>
      </div>

      <div className="field-row field-row--primary">
        <div className="field">
          <DatePicker label="Check-In" value={form.checkIn} min={today} onChange={(value) => setField("checkIn", value)} ariaLabel="Select check-in date" blockedDates={availability.blocked} />
        </div>

        <div className="field">
          <DatePicker label="Check-Out" value={form.checkOut} min={form.checkIn ? addDaysISO(form.checkIn, 1) : today} onChange={(value) => setField("checkOut", value)} ariaLabel="Select check-out date" blockedDates={availability.blocked} />
        </div>

        <div className="field">
          <label className="ws-label">Guests</label>
          <select className="ws-input" value={form.guests} onChange={(e) => setField("guests", e.target.value)}>
            {[1,2,3,4,5,6,7,8,9,10].map((n) => <option key={n} value={n}>{n} {n === 1 ? "Guest" : "Guests"}</option>)}
          </select>
        </div>
        <div className="field">
          <label className="ws-label">Bedrooms</label>
          <select className="ws-input" value={form.bedrooms} onChange={(e) => setField("bedrooms", e.target.value)}>
            {["Any","1","2","3","4"].map((n) => <option key={n} value={n}>{n === "Any" ? "Any" : `${n} Bedroom${n === "1" ? "" : "s"}`}</option>)}
          </select>
        </div>
      </div>

      <div className="field-row field-row--contact">
        <div className="field">
          <label className="ws-label">Your Name</label>
          <input className="ws-input" value={form.name} onChange={(e) => setField("name", e.target.value)} placeholder="Your name" />
        </div>

        <div className="field">
          <label className="ws-label">Email Address</label>
          <input className="ws-input" type="email" value={form.email} onChange={(e) => setField("email", e.target.value)} placeholder="you@example.com" />
        </div>

        <div className="field">
          <label className="ws-label">Phone Number</label>
          <input className="ws-input" value={form.phone} onChange={(e) => setField("phone", e.target.value)} placeholder="Optional" />
        </div>
      </div>

      <div className="field field--message">
        <label className="ws-label">Message</label>
        <textarea className="ws-textarea" rows={3} value={form.message} onChange={(e) => setField("message", e.target.value)} placeholder="Anything we should know about your stay?" />
      </div>

      <div className="ws-booking-card__actions">
        <button className="ws-btn ws-btn--gold" onClick={submit} disabled={status.state === "loading"}>
          {status.state === "loading" ? "Sending enquiry..." : "Send Stay Enquiry"}
        </button>
        <button className="ws-btn ws-btn--ghost" style={{ color:"var(--ws-gold-deep)", borderColor:"var(--ws-gold-deep)" }} onClick={onEnquire}>
          <Icon name="mail" size={14} /> Ask a Question
        </button>
      </div>

      {status.message && (
        <div className={"ws-booking-card__status " + (status.state === "error" ? "is-error" : "is-success")}>
          {status.message}
        </div>
      )}
      <div className="foot">Direct enquiries avoid third-party booking fees from this site.</div>
      <div className="foot"><a href={window.SITE_CONTACT.airbnbUrl} target="_blank" rel="noopener noreferrer">View the Airbnb listing</a></div>
    </div>
  );
}

window.CTAStrip = CTAStrip;
window.Benefits = Benefits;
window.RoomCard = RoomCard;
window.RoomModal = RoomModal;
window.BookingWidget = BookingWidget;
