/* global React, CONTACT */

/* ============================================================
   Booking page — "Book a Visit"
   20-min slots, Mon–Fri 9:30–13:00 / 14:00–16:30, Sat 9:00–13:00
   Multiple people can book the same slot (no capacity check for now)
   3-step flow: Purpose → Date + slot → Name + phone
   ============================================================ */

const VISIT_PURPOSES = [
  {
    id: "worktops",
    icon: "◼",
    title: "Kitchen or bathroom worktops",
    sub: "Browse slabs, get a feel for colour and finish",
  },
  {
    id: "memorial",
    icon: "◇",
    title: "Memorial or headstone",
    sub: "Discuss a tribute stone in a quiet setting",
  },
  {
    id: "browse",
    icon: "◎",
    title: "Just browsing",
    sub: "Looking around, no pressure",
  },
];

// Each entry is an array of [startH, startM, endH, endM] sessions
const SHOWROOM_HOURS = {
  0: null,                                        // Sunday — closed
  1: [[9, 30, 13, 0], [14, 0, 16, 30]],          // Monday
  2: [[9, 30, 13, 0], [14, 0, 16, 30]],          // Tuesday
  3: [[9, 30, 13, 0], [14, 0, 16, 30]],          // Wednesday
  4: [[9, 30, 13, 0], [14, 0, 16, 30]],          // Thursday
  5: [[9, 30, 13, 0], [14, 0, 16, 30]],          // Friday
  6: null,                                        // Saturday — drop-in only, no booking
};

const SLOT_MINUTES = 20;

function pad(n) { return String(n).padStart(2, "0"); }

function slotsForDay(dow) {
  const sessions = SHOWROOM_HOURS[dow];
  if (!sessions) return [];
  const slots = [];
  for (const [sh, sm, eh, em] of sessions) {
    let h = sh, m = sm;
    const endTotal = eh * 60 + em;
    while (h * 60 + m < endTotal) {
      slots.push(`${pad(h)}:${pad(m)}`);
      m += SLOT_MINUTES;
      if (m >= 60) { h++; m -= 60; }
    }
  }
  return slots;
}

function formatDateLong(dateStr) {
  const [y, mo, d] = dateStr.split("-").map(Number);
  const date = new Date(y, mo - 1, d);
  return date.toLocaleDateString("en-IE", { weekday: "long", day: "numeric", month: "long", year: "numeric" });
}

function formatSlot(time) {
  const [h, m] = time.split(":").map(Number);
  const end = new Date(2000, 0, 1, h, m + SLOT_MINUTES);
  return `${time} – ${pad(end.getHours())}:${pad(end.getMinutes())}`;
}

function getNext60Days() {
  const days = [];
  const today = new Date();
  today.setHours(0, 0, 0, 0);
  for (let i = 1; i <= 60; i++) {
    const d = new Date(today);
    d.setDate(d.getDate() + i);
    const dow = d.getDay();
    if (SHOWROOM_HOURS[dow]) {
      const y = d.getFullYear();
      const mo = pad(d.getMonth() + 1);
      const day = pad(d.getDate());
      days.push({ dateStr: `${y}-${mo}-${day}`, dow, d });
    }
  }
  return days;
}

/* ============================================================
   Step indicator
   ============================================================ */
function BookingSteps({ step }) {
  const labels = ["Visit type", "Date & time", "Your details"];
  return (
    <div className="bk-steps">
      {labels.map((l, i) => (
        <React.Fragment key={i}>
          <div className={"bk-step" + (i + 1 === step ? " active" : i + 1 < step ? " done" : "")}>
            <span className="bk-step-num">{i + 1 < step ? "✓" : i + 1}</span>
            <span className="bk-step-label">{l}</span>
          </div>
          {i < labels.length - 1 && <div className={"bk-step-line" + (i + 1 < step ? " done" : "")} />}
        </React.Fragment>
      ))}
    </div>
  );
}

/* ============================================================
   Step 1 — Purpose
   ============================================================ */
function StepPurpose({ value, onChange }) {
  return (
    <div className="bk-step-body">
      <h2 className="bk-h2">What brings you in?</h2>
      <p className="bk-sub">Choose the option that best fits — helps us have the right person ready for you.</p>
      <div className="bk-purpose-grid">
        {VISIT_PURPOSES.map((p) => (
          <button key={p.id}
            className={"bk-purpose-card" + (value === p.id ? " selected" : "")}
            onClick={() => onChange(p.id)}>
            <span className="bk-purpose-icon">{p.icon}</span>
            <span className="bk-purpose-title">{p.title}</span>
            <span className="bk-purpose-sub">{p.sub}</span>
          </button>
        ))}
      </div>
    </div>
  );
}

/* ============================================================
   Step 2 — Date + slot
   ============================================================ */
function StepDateTime({ date, slot, onDate, onSlot }) {
  const days = React.useMemo(() => getNext60Days(), []);
  const [weekOffset, setWeekOffset] = React.useState(0);

  const DOW_LABELS = ["Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat"];

  // Group available days into calendar weeks
  const weeks = React.useMemo(() => {
    const result = [];
    if (!days.length) return result;
    const first = days[0].d;
    // Start of first available day's week (Monday = 0 for display)
    const startOfWeek = new Date(first);
    const dow = (first.getDay() + 6) % 7; // Monday-based
    startOfWeek.setDate(startOfWeek.getDate() - dow);

    const endDate = new Date(days[days.length - 1].d);
    const cursor = new Date(startOfWeek);
    while (cursor <= endDate) {
      const week = [];
      for (let i = 0; i < 7; i++) {
        const d = new Date(cursor);
        const y = d.getFullYear();
        const mo = pad(d.getMonth() + 1);
        const day = pad(d.getDate());
        const ds = `${y}-${mo}-${day}`;
        const avail = days.find(a => a.dateStr === ds);
        week.push({ d: new Date(d), dateStr: ds, available: !!avail, dowLabel: DOW_LABELS[d.getDay()] });
        cursor.setDate(cursor.getDate() + 1);
      }
      result.push(week);
    }
    return result;
  }, [days]);

  const visibleWeek = weeks[weekOffset] || [];
  const slots = date ? slotsForDay(new Date(date + "T00:00:00").getDay()) : [];

  const weekLabel = (() => {
    if (!visibleWeek.length) return "";
    const first = visibleWeek.find(d => d.available) || visibleWeek[0];
    const last  = visibleWeek.filter(d => d.available).slice(-1)[0] || visibleWeek[6];
    return first.d.toLocaleDateString("en-IE", { day: "numeric", month: "short" }) +
      " – " + last.d.toLocaleDateString("en-IE", { day: "numeric", month: "short", year: "numeric" });
  })();

  function prevWeek() { if (weekOffset > 0) { setWeekOffset(w => w - 1); } }
  function nextWeek() { if (weekOffset < weeks.length - 1) { setWeekOffset(w => w + 1); } }

  const today = new Date(); today.setHours(0,0,0,0);
  function isPast(d) { return d < today; }

  return (
    <div className="bk-step-body">
      <h2 className="bk-h2">Pick a date</h2>
      <p className="bk-sub">Bookings available Mon–Fri. Saturdays are open 9:00–13:00 for drop-ins — no booking needed, just come in.</p>

      <div className="bk-cal">
        <div className="bk-cal-nav">
          <button className="bk-cal-arr" onClick={prevWeek} disabled={weekOffset === 0}>‹</button>
          <span className="bk-cal-label">{weekLabel}</span>
          <button className="bk-cal-arr" onClick={nextWeek} disabled={weekOffset >= weeks.length - 1}>›</button>
        </div>
        <div className="bk-cal-row">
          {visibleWeek.map((day) => (
            <button key={day.dateStr}
              disabled={!day.available || isPast(day.d)}
              className={"bk-cal-day" +
                (!day.available || isPast(day.d) ? " unavail" : "") +
                (day.dateStr === date ? " selected" : "")}
              onClick={() => { if (day.available && !isPast(day.d)) { onDate(day.dateStr); onSlot(""); } }}>
              <span className="bk-cal-dow">{day.dowLabel}</span>
              <span className="bk-cal-num">{day.d.getDate()}</span>
            </button>
          ))}
        </div>
      </div>

      {date && (
        <div className="bk-slots">
          <div className="bk-slots-label">Available times on {new Date(date + "T00:00:00").toLocaleDateString("en-IE", { weekday: "long", day: "numeric", month: "long" })}</div>
          <div className="bk-slots-grid">
            {slots.map(s => (
              <button key={s}
                className={"bk-slot" + (slot === s ? " selected" : "")}
                onClick={() => onSlot(s)}>
                {formatSlot(s)}
              </button>
            ))}
          </div>
        </div>
      )}

      <div style={{marginTop:24, padding:"12px 16px", background:"#f0f7fa", borderLeft:"2px solid var(--teal)", borderRadius:2, fontSize:13, color:"var(--slate)"}}>
        <strong>Saturday 9:00 – 13:00</strong> — drop-in welcome, no booking required. Just come in and we'll look after you.
      </div>
    </div>
  );
}

/* ============================================================
   Step 3 — Contact details
   ============================================================ */
function StepDetails({ name, phone, email, notes, onChange }) {
  return (
    <div className="bk-step-body">
      <h2 className="bk-h2">Your details</h2>
      <p className="bk-sub">Name, number and email — we'll send a confirmation so you don't forget the day.</p>
      <div className="bk-fields">
        <div className="bk-field">
          <label>Name</label>
          <input type="text" placeholder="First name or full name"
            value={name} onChange={e => onChange("name", e.target.value)} />
        </div>
        <div className="bk-field">
          <label>Phone</label>
          <input type="tel" placeholder="087 000 0000"
            value={phone} onChange={e => onChange("phone", e.target.value)} />
        </div>
        <div className="bk-field">
          <label>Email <span style={{fontWeight:400,color:"rgba(0,0,0,0.55)"}}>· we'll send a confirmation</span></label>
          <input type="email" placeholder="you@example.ie" autoComplete="email"
            value={email} onChange={e => onChange("email", e.target.value)} />
        </div>
        <div className="bk-field">
          <label>Anything we should know? <span style={{fontWeight:400,color:"rgba(0,0,0,0.55)"}}>(optional)</span></label>
          <textarea rows={3} placeholder="e.g. I have a rough sketch of the kitchen, or a particular stone in mind"
            value={notes} onChange={e => onChange("notes", e.target.value)} />
        </div>
      </div>
    </div>
  );
}

/* ============================================================
   Confirmation screen
   ============================================================ */
function BookingConfirmed({ booking }) {
  const purposeLabel = (VISIT_PURPOSES.find(p => p.id === booking.purpose) || {}).title || booking.purpose;
  return (
    <div className="bk-confirmed">
      <div className="bk-confirmed-icon">✓</div>
      <h2>You're booked in.</h2>
      <p>We're looking forward to seeing <strong>{booking.name}</strong> at the showroom.</p>
      <div className="bk-confirmed-card">
        <div><span>When</span><strong>{formatDateLong(booking.date)} at {formatSlot(booking.slot)}</strong></div>
        <div><span>Visit type</span><strong>{purposeLabel}</strong></div>
        <div><span>Where</span><strong>5 Lower Main St, Kilbeggan, Co. Westmeath</strong></div>
        <div><span>Phone</span><strong>{CONTACT.phoneDisplay}</strong></div>
      </div>
      {booking.email && (
        <p className="bk-confirmed-note" style={{marginBottom: 8}}>
          A confirmation is on its way to <strong>{booking.email}</strong> — check spam if it doesn't land in a minute.
        </p>
      )}
      <p className="bk-confirmed-note">
        If you need to change your time just give us a call on <a href={CONTACT.phoneHref}>{CONTACT.phoneDisplay}</a> and we'll sort it out.
      </p>
    </div>
  );
}

/* ============================================================
   Main Booking component
   ============================================================ */
function Booking({ navigate }) {
  const [step, setStep] = React.useState(1);
  const [purpose, setPurpose] = React.useState("");
  const [date, setDate] = React.useState("");
  const [slot, setSlot] = React.useState("");
  const [name, setName] = React.useState("");
  const [phone, setPhone] = React.useState("");
  const [email, setEmail] = React.useState("");
  const [notes, setNotes] = React.useState("");
  const [submitted, setSubmitted] = React.useState(false);
  const [submitting, setSubmitting] = React.useState(false);

  function canNext() {
    if (step === 1) return !!purpose;
    if (step === 2) return !!date && !!slot;
    if (step === 3) return name.trim().length >= 2 && phone.trim().length >= 7 && /^\S+@\S+\.\S+$/.test(email.trim());
    return false;
  }

  function handleNext() {
    if (canNext()) setStep(s => s + 1);
  }

  function handleBack() {
    setStep(s => s - 1);
  }

  async function handleSubmit() {
    if (!canNext()) return;
    setSubmitting(true);

    try {
      const res = await fetch("/api/booking", {
        method: "POST",
        headers: { "Content-Type": "application/json" },
        body: JSON.stringify({ purpose, date, slot, name, phone, email, notes }),
      });
      if (!res.ok) throw new Error("API error " + res.status);
    } catch (err) {
      const purposeLabel = (VISIT_PURPOSES.find(p => p.id === purpose) || {}).title || purpose;
      const subject = `Showroom visit — ${name} — ${formatDateLong(date)}`;
      const body = [
        `Name: ${name}`, `Phone: ${phone}`, ``,
        `Visit type: ${purposeLabel}`,
        `Date: ${formatDateLong(date)}`, `Time: ${formatSlot(slot)}`,
        notes ? `Notes: ${notes}` : "",
      ].filter(Boolean).join("\n");
      window.open(`mailto:${CONTACT.email}?subject=${encodeURIComponent(subject)}&body=${encodeURIComponent(body)}`);
    }

    setSubmitting(false);
    setSubmitted(true);
  }

  if (submitted) {
    return (
      <div>
        <section className="section dark" style={{paddingTop: "clamp(96px, 11vw, 148px)", paddingBottom: 0}}>
          <div className="container">
            <BookingConfirmed booking={{ purpose, date, slot, name, phone, email }} />
          </div>
        </section>
      </div>
    );
  }

  return (
    <div>
      {/* Page hero */}
      <section className="section dark" style={{paddingTop: "clamp(96px, 11vw, 148px)", paddingBottom: "clamp(40px, 5vw, 72px)"}}>
        <div className="container">
          <div className="kicker on-dark" style={{color: "#7CC3D8", marginBottom: 20}}>Showroom · Kilbeggan</div>
          <h1 className="display" style={{color: "white", maxWidth: 760}}>Book a showroom visit</h1>
          <p className="lede" style={{color: "rgba(255,255,255,0.75)", maxWidth: 560, marginTop: 24, fontSize: 17}}>
            Come and see the stone in person. No obligation — most people find it makes the decision much easier.
          </p>
        </div>
      </section>

      {/* Form area */}
      <section className="section light" style={{paddingTop: "clamp(48px, 6vw, 88px)", paddingBottom: "clamp(64px, 8vw, 120px)"}}>
        <div className="container">
          <div className="bk-wrap">
            <BookingSteps step={step} />

            <div className="bk-card">
              {step === 1 && (
                <StepPurpose value={purpose} onChange={v => { setPurpose(v); }} />
              )}
              {step === 2 && (
                <StepDateTime date={date} slot={slot} onDate={setDate} onSlot={setSlot} />
              )}
              {step === 3 && (
                <StepDetails name={name} phone={phone} email={email} notes={notes}
                  onChange={(field, val) => {
                    if (field === "name") setName(val);
                    if (field === "phone") setPhone(val);
                    if (field === "email") setEmail(val);
                    if (field === "notes") setNotes(val);
                  }} />
              )}

              <div className="bk-actions">
                {step > 1 && (
                  <button className="bk-back" onClick={handleBack}>← Back</button>
                )}
                {step < 3 ? (
                  <button className={"btn btn-teal bk-next" + (!canNext() ? " disabled" : "")}
                    onClick={handleNext} disabled={!canNext()}>
                    Continue →
                  </button>
                ) : (
                  <button className={"btn btn-teal bk-next" + (!canNext() || submitting ? " disabled" : "")}
                    onClick={handleSubmit} disabled={!canNext() || submitting}>
                    {submitting ? "Booking…" : "Confirm visit →"}
                  </button>
                )}
              </div>
            </div>

            {/* Side info */}
            <div className="bk-aside">
              <div className="bk-aside-block">
                <div className="bk-aside-label">Showroom hours</div>
                <div className="bk-aside-row"><span>Mon – Fri</span><span>9:30–13:00 / 14:00–16:30</span></div>
                <div className="bk-aside-row"><span>Saturday</span><span>9:00–13:00 · drop-in only</span></div>
                <div className="bk-aside-row closed"><span>Sunday</span><span>Closed</span></div>
              </div>
              <div className="bk-aside-block">
                <div className="bk-aside-label">Where to find us</div>
                <p className="bk-aside-addr">5 Lower Main St, Kilbeggan<br />Co. Westmeath<br />N91 FNK1</p>
                <a href="https://maps.google.com/?q=Kilbeggan+Co+Westmeath" target="_blank" rel="noopener noreferrer"
                  className="bk-aside-map">Open in Maps →</a>
              </div>
              <div className="bk-aside-block">
                <div className="bk-aside-label">Prefer to call?</div>
                <a className="bk-aside-phone" href={CONTACT.phoneHref}>{CONTACT.phoneDisplay}</a>
                <div style={{fontSize: 13, color: "rgba(0,0,0,0.65)", marginTop: 6}}>We're happy to find a time on the phone too.</div>
              </div>
            </div>
          </div>
        </div>
      </section>
    </div>
  );
}

Object.assign(window, { Booking });
