/* ===================== Ajanvarauslomake (booking modal) =====================
   Avautuu laskurin "Varaa aika" -napista. Kerää asiakkaan tiedot + laskurin
   ikkunavalinnat, lähettää ne window.klTrack:n kautta backendiin (Resend +
   Google Sheets) ja näyttää kiitossivun, jolta voi myös soittaa suoraan.
   ============================================================================ */

const fmtEur = (n) =>
  (Math.round(n * 100) / 100).toLocaleString("fi-FI", { minimumFractionDigits: 0, maximumFractionDigits: 2 }) + " €";

/* ── Aika-apurit ──────────────────────────────────────────────────────── */
const BK_WD     = ["Ma", "Ti", "Ke", "To", "Pe", "La", "Su"];
const BK_DOW    = ["su", "ma", "ti", "ke", "to", "pe", "la"];
const BK_MONTHS = ["tammikuu","helmikuu","maaliskuu","huhtikuu","toukokuu","kesäkuu",
                   "heinäkuu","elokuu","syyskuu","lokakuu","marraskuu","joulukuu"];

const bkYmd = (d) => `${d.getFullYear()}-${String(d.getMonth()+1).padStart(2,"0")}-${String(d.getDate()).padStart(2,"0")}`;
const bkSameDay = (a, b) => a && b && bkYmd(a) === bkYmd(b);
const bkDateLabel = (d) => `${BK_DOW[d.getDay()]} ${d.getDate()}.${d.getMonth()+1}.${d.getFullYear()}`;
const bkMin2hhmm = (m) => `${String(Math.floor(m/60)).padStart(2,"0")}:${String(m%60).padStart(2,"0")}`;

/* ── Interaktiivinen kuukausikalenteri ────────────────────────────────── */
function MiniCalendar({ value, onSelect }) {
  const today = new Date(); today.setHours(0,0,0,0);
  const [view, setView] = useState(() => new Date(today.getFullYear(), today.getMonth(), 1));
  const y = view.getFullYear(), m = view.getMonth();
  const startOffset = (new Date(y, m, 1).getDay() + 6) % 7; // ma-alkuinen
  const daysInMonth = new Date(y, m+1, 0).getDate();
  const canPrev = (y > today.getFullYear()) || (y === today.getFullYear() && m > today.getMonth());

  const cells = [];
  for (let i = 0; i < startOffset; i++) cells.push(null);
  for (let d = 1; d <= daysInMonth; d++) cells.push(new Date(y, m, d));

  return (
    <div className="bkm__cal">
      <div className="bkm__calHead">
        <button type="button" className="bkm__calNav" disabled={!canPrev}
          onClick={() => canPrev && setView(new Date(y, m-1, 1))} aria-label="Edellinen kuukausi">‹</button>
        <span className="bkm__calMonth">{BK_MONTHS[m]} {y}</span>
        <button type="button" className="bkm__calNav"
          onClick={() => setView(new Date(y, m+1, 1))} aria-label="Seuraava kuukausi">›</button>
      </div>
      <div className="bkm__calGrid bkm__calWd">
        {BK_WD.map((w) => <span key={w} className="bkm__calWdCell">{w}</span>)}
      </div>
      <div className="bkm__calGrid">
        {cells.map((d, i) => {
          if (!d) return <span key={i} className="bkm__calCell bkm__calCell--empty"/>;
          const past = d < today;
          const weekend = d.getDay() === 0 || d.getDay() === 6;
          const sel = bkSameDay(d, value);
          return (
            <button key={i} type="button" disabled={past}
              className={"bkm__calCell" + (sel ? " is-sel" : "") + (past ? " is-past" : "") + (weekend && !sel ? " is-we" : "")}
              onClick={() => onSelect(d)}>{d.getDate()}</button>
          );
        })}
      </div>
    </div>
  );
}

/* ── Interaktiivinen aikaikkuna (vedettävät kahvat, väh. 1 h) ──────────── */
const BK_TMIN = 420, BK_TMAX = 1200, BK_TSTEP = 30, BK_TGAP = 60; // 07:00–20:00, 30 min, min 1 h

function TimeWindow({ start, end, onStart, onEnd }) {
  const railRef = useRef(null);
  const dragRef = useRef(null);          // 'start' | 'end' | null
  const sref = useRef({ start, end });
  sref.current = { start, end };
  const pct = (v) => ((v - BK_TMIN) / (BK_TMAX - BK_TMIN)) * 100;

  const valFromX = (clientX) => {
    const rail = railRef.current;
    if (!rail) return null;
    const rect = rail.getBoundingClientRect();
    const ratio = Math.max(0, Math.min(1, (clientX - rect.left) / rect.width));
    return Math.round((BK_TMIN + ratio * (BK_TMAX - BK_TMIN)) / BK_TSTEP) * BK_TSTEP;
  };

  // Sido pointer-kuuntelijat kerran; lukee tuoreet arvot sref:stä.
  useEffect(() => {
    const move = (e) => {
      if (!dragRef.current) return;
      const v = valFromX(e.clientX);
      if (v == null) return;
      const { start, end } = sref.current;
      if (dragRef.current === "start") onStart(Math.min(v, end - BK_TGAP));
      else onEnd(Math.max(v, start + BK_TGAP));
      if (e.cancelable) e.preventDefault();
    };
    const up = () => { dragRef.current = null; document.body.style.userSelect = ""; };
    window.addEventListener("pointermove", move, { passive: false });
    window.addEventListener("pointerup", up);
    return () => { window.removeEventListener("pointermove", move); window.removeEventListener("pointerup", up); };
  }, []);

  const grab = (which) => (e) => {
    e.stopPropagation();
    dragRef.current = which;
    document.body.style.userSelect = "none";
  };

  // Klikkaus kiskoon: tartu lähimpään kahvaan ja siirrä se heti.
  const railDown = (e) => {
    const v = valFromX(e.clientX);
    if (v == null) return;
    const which = Math.abs(v - start) <= Math.abs(v - end) ? "start" : "end";
    dragRef.current = which;
    document.body.style.userSelect = "none";
    if (which === "start") onStart(Math.min(v, end - BK_TGAP));
    else onEnd(Math.max(v, start + BK_TGAP));
  };

  const key = (which) => (e) => {
    let d = 0;
    if (e.key === "ArrowLeft" || e.key === "ArrowDown") d = -BK_TSTEP;
    else if (e.key === "ArrowRight" || e.key === "ArrowUp") d = BK_TSTEP;
    else return;
    e.preventDefault();
    if (which === "start") onStart(Math.max(BK_TMIN, Math.min(start + d, end - BK_TGAP)));
    else onEnd(Math.min(BK_TMAX, Math.max(end + d, start + BK_TGAP)));
  };

  return (
    <div className="bkm__time">
      <div className="bkm__timeVal">klo {bkMin2hhmm(start)} – {bkMin2hhmm(end)}</div>
      <div className="bkm__slider" ref={railRef} onPointerDown={railDown}>
        <div className="bkm__sliderRail"/>
        <div className="bkm__sliderFill" style={{ left: pct(start)+"%", right: (100-pct(end))+"%" }}/>
        <div className="bkm__thumb" style={{ left: pct(start)+"%" }} role="slider" tabIndex={0}
          aria-label="Alkamisaika" aria-valuetext={bkMin2hhmm(start)}
          onPointerDown={grab("start")} onKeyDown={key("start")}/>
        <div className="bkm__thumb" style={{ left: pct(end)+"%" }} role="slider" tabIndex={0}
          aria-label="Loppumisaika" aria-valuetext={bkMin2hhmm(end)}
          onPointerDown={grab("end")} onKeyDown={key("end")}/>
      </div>
      <div className="bkm__timeMarks"><span>7</span><span>10</span><span>13</span><span>16</span><span>20</span></div>
      <div className="bkm__timeHint">Vedä kahvoista sopiva aikaväli — väh. 1 tunti.</div>
    </div>
  );
}

function BookingModal({ open, onClose, ctx }) {
  const [form, setForm] = useState({
    name: "", phone: "", email: "", street: "", zipCode: "",
    service: D.services[0].title, message: "",
  });
  const [screen, setScreen] = useState("ask");
  const [isReturning, setIsReturning] = useState(false);
  const [sending, setSending] = useState(false);
  const [err, setErr] = useState("");
  const [prefDate, setPrefDate]   = useState(null);   // toivepäivä (Date | null)
  const [timeStart, setTimeStart] = useState(540);    // 09:00
  const [timeEnd, setTimeEnd]     = useState(900);    // 15:00

  // Sync service + pre-fill postinumero from calculator when modal opens
  useEffect(() => {
    if (!open) return;
    setScreen("ask");
    setIsReturning(false);
    setPrefDate(null);
    setTimeStart(540);
    setTimeEnd(900);
    setForm((f) => ({
      ...f,
      service: ctx.service || D.services[0].title,
      zipCode: ctx.zipInput || f.zipCode,
    }));
  }, [open, ctx.service, ctx.zipInput]);

  // Lock scroll + Esc key
  useEffect(() => {
    if (!open) return;
    const prev = document.body.style.overflow;
    document.body.style.overflow = "hidden";
    const onKey = (e) => { if (e.key === "Escape") onClose(); };
    window.addEventListener("keydown", onKey);
    return () => { document.body.style.overflow = prev; window.removeEventListener("keydown", onKey); };
  }, [open, onClose]);

  if (!open) return null;

  const set = (k) => (e) => setForm((f) => ({ ...f, [k]: e.target.value }));

  const submit = (e) => {
    e.preventDefault();
    setErr("");
    if (!form.name.trim() || !form.phone.trim()) {
      setErr("Täytä vähintään nimi ja puhelinnumero.");
      return;
    }
    setSending(true);
    const wishDateLabel = prefDate ? bkDateLabel(prefDate) : "";
    const wishTime = `${bkMin2hhmm(timeStart)}–${bkMin2hhmm(timeEnd)}`;
    const wishSlot = (wishDateLabel ? wishDateLabel + " " : "") + "klo " + wishTime;
    window.klTrack({
      type: "varaus",
      source: "ajanvarauslomake",
      name: form.name.trim(),
      phone: form.phone.trim(),
      email: form.email.trim(),
      address: form.street.trim(),
      service: form.service,
      message: form.message.trim(),
      zip: form.zipCode.trim() || "",
      isReturning,
      wishDate: prefDate ? bkYmd(prefDate) : "",
      wishDateLabel,
      wishTime,
      wishSlot,
      count: ctx.count,
      gross: ctx.gross,
      deduction: ctx.deduction,
      afterDeduction: ctx.afterDeduction,
      travelFee: ctx.travelFee || 0,
      travelKm: ctx.geoKm,
      lines: ctx.lines,
      calc: ctx.qty,
    });
    setTimeout(() => { setSending(false); setScreen("done"); }, 650);
  };

  return (
    <div className="bkm" role="dialog" aria-modal="true" aria-label="Ajanvaraus">
      <button className="bkm__scrim" aria-label="Sulje" onClick={onClose}/>
      <div className="bkm__panel">
        <button className="bkm__close" aria-label="Sulje" onClick={onClose}>✕</button>

        {screen === "ask" && (
          <div className="bkm__head">
            <span className="bkm__badge">
              <Ic.cal style={{width:18,height:18,color:"var(--brand)"}}/> Ajanvaraus
            </span>
            <h2>Oletko palaava asiakas?</h2>
            <p className="bkm__sub">Se auttaa meitä palvelemaan sinua paremmin.</p>
            <div style={{display:"flex",flexDirection:"column",gap:10,marginTop:28}}>
              <button className="btn btn--primary btn--block btn--lg" type="button"
                onClick={() => { setIsReturning(false); setScreen("form"); }}>
                Ei, olen uusi asiakas
              </button>
              <button className="btn btn--ghost btn--block" type="button"
                onClick={() => { setIsReturning(true); setScreen("form"); }}>
                Kyllä, olen jo asiakkaanne
              </button>
            </div>
          </div>
        )}

        {screen === "form" && (
          <>
            <div className="bkm__head">
              <span className="bkm__badge">
                <Ic.cal style={{width:18,height:18,color:"var(--brand)"}}/> Ajanvaraus
              </span>
              <h2>Varaa ikkunanpesu</h2>
              <p className="bkm__sub">
                Jätä yhteystietosi — Henri tai Severi on sinuun yhteydessä ja sovitaan sopiva aika.
                Voit myös soittaa suoraan lähetyksen jälkeen.
              </p>
            </div>

            {/* Summary of calculator selections */}
            <div className="bkm__summary">
              <div className="bkm__sumHead">Valintasi</div>
              {ctx.lines.length > 0 ? (
                <ul className="bkm__lines">
                  {ctx.lines.map((l) => (
                    <li key={l.id}><span>{l.name} × {l.qty}</span><b>{fmtEur(l.total)}</b></li>
                  ))}
                </ul>
              ) : (
                <p className="bkm__empty">
                  Et ole vielä valinnut ikkunoita laskurista — voit silti jättää varauksen
                  ja tarkennetaan puhelimessa.
                </p>
              )}
              <div className="bkm__sumTotals">
                <div className="bkm__row"><span>Hinta yhteensä</span><b>{fmtEur(ctx.gross)}</b></div>
                {(ctx.travelFee || 0) > 0 && (
                  <div className="bkm__row">
                    <span>Matkustuskulut ({ctx.geoKm} km)</span>
                    <b>+{fmtEur(ctx.travelFee)}</b>
                  </div>
                )}
                <div className="bkm__row">
                  <span>Kotitalousvähennys 35 %</span><b>−{fmtEur(ctx.deduction)}</b>
                </div>
                <div className="bkm__row bkm__row--accent">
                  <span>Vähennyksen jälkeen (arvio)</span><b>{fmtEur(ctx.afterDeduction)}</b>
                </div>
              </div>
            </div>

            <form className="bkm__form" onSubmit={submit}>
              <label className="bkm__field">
                <span>Nimi *</span>
                <input value={form.name} onChange={set("name")} placeholder="Etu- ja sukunimi" required/>
              </label>
              <div className="bkm__grid2">
                <label className="bkm__field">
                  <span>Puhelin *</span>
                  <input type="tel" value={form.phone} onChange={set("phone")} placeholder="040 123 4567" required/>
                </label>
                <label className="bkm__field">
                  <span>Sähköposti</span>
                  <input type="email" value={form.email} onChange={set("email")} placeholder="nimi@esimerkki.fi"/>
                </label>
              </div>
              <div className="bkm__grid2 bkm__grid2--73">
                <label className="bkm__field">
                  <span>Katuosoite</span>
                  <input value={form.street} onChange={set("street")} placeholder="Esim. Esimerkkikatu 12 A 3"/>
                </label>
                <label className="bkm__field">
                  <span>Postinumero</span>
                  <input inputMode="numeric" maxLength="5" value={form.zipCode}
                    onChange={set("zipCode")} placeholder="90100"/>
                </label>
              </div>
              <div className="bkm__field">
                <span>Toivepäivä — milloin sinulle sopisi?</span>
                <MiniCalendar value={prefDate} onSelect={setPrefDate}/>
              </div>
              <div className="bkm__field">
                <span>Toiveaika — paras aika tulla pesemään</span>
                <TimeWindow start={timeStart} end={timeEnd} onStart={setTimeStart} onEnd={setTimeEnd}/>
              </div>
              <div className="bkm__wishNote">
                <b>Huom:</b> Tämä on toiveaikasi. Emme voi vielä taata juuri tätä aikaa, sillä
                kalenterissamme voi olla jo varauksia. Otamme sinuun yhteyttä ja varmistamme
                sopivan ajan.
              </div>

              <label className="bkm__field">
                <span>Pesutapa</span>
                <select value={form.service} onChange={set("service")}>
                  {D.services.map((s) => <option key={s.id} value={s.title}>{s.title}</option>)}
                </select>
              </label>
              <label className="bkm__field">
                <span>Toive ajankohdasta / lisätiedot</span>
                <textarea rows={3} value={form.message} onChange={set("message")}
                  placeholder="Esim. arkisin klo 16 jälkeen, korkeita ikkunoita, jne."/>
              </label>

              {err && <div className="bkm__err">{err}</div>}

              <button className="btn btn--primary btn--block btn--lg" type="submit" disabled={sending}>
                {sending ? "Lähetetään…" : <><Ic.cal style={{width:19,height:19}}/> Lähetä varaus</>}
              </button>
              <p className="bkm__fineprint">
                Varaus ei sido sinua — voit perua milloin tahansa puhelimitse tai sähköpostilla.
              </p>
              <p className="bkm__fineprint bkm__fineprint--pay">
                <Ic.wallet style={{width:13,height:13,verticalAlign:"middle",marginRight:4}}/>
                {D.payment.note} {D.payment.methods.join(" · ")}.
              </p>
              <div className="bkm__contacts">
                <a href={`mailto:${D.email}`} className="bkm__contactLink">
                  <Ic.mail style={{width:15,height:15}}/> {D.email}
                </a>
              </div>
            </form>
          </>
        )}

        {screen === "done" && (
          <div className="bkm__done">
            <div className="bkm__doneIc"><Ic.check style={{width:34,height:34}}/></div>
            <h2>Kiitos varauksesta!</h2>
            <div className="bkm__doneSlot">
              <Ic.cal style={{width:16,height:16,color:"var(--brand)"}}/>
              <span>Toiveaikasi: <b>{(prefDate ? bkDateLabel(prefDate) + " " : "")}klo {bkMin2hhmm(timeStart)}–{bkMin2hhmm(timeEnd)}</b></span>
            </div>
            <p className="bkm__sub">
              Varauksesi on vastaanotettu. Tämä on <b>toiveaikasi</b> — otamme sinuun yhteyttä ja
              varmistamme ajan. Haluatko nopeuttaa? Soita suoraan:
            </p>
            <div className="bkm__callRow">
              <a className="btn btn--primary bkm__callBtn" href={D.phoneHref}
                 data-name={D.brand} data-source="kiitossivu">
                <Ic.phone style={{width:18,height:18}}/> Soita · {D.phone}
              </a>
            </div>
            <div className="bkm__contacts" style={{marginTop:16}}>
              <a href={`mailto:${D.email}`} className="bkm__contactLink">
                <Ic.mail style={{width:15,height:15}}/> {D.email}
              </a>
            </div>
            <p className="bkm__fineprint bkm__fineprint--pay" style={{marginTop:16}}>
              <Ic.wallet style={{width:13,height:13,verticalAlign:"middle",marginRight:4}}/>
              {D.payment.note}
            </p>
            <button className="btn btn--ghost btn--block" onClick={onClose} style={{marginTop:14}}>Sulje</button>
          </div>
        )}
      </div>
    </div>
  );
}

Object.assign(window, { BookingModal });
