// ARS — Availability calendar page (own React root)
const { useState: useS, useEffect: useE, useMemo: useM } = React;
const W = window.ARS.WINDOWS;
const MONTHS = ["January", "February", "March", "April", "May", "June", "July", "August", "September", "October", "November", "December"];
const DOW = ["Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat"];

function monthMatrix(year, month) {
  const first = new Date(year, month, 1);
  const start = new Date(year, month, 1 - first.getDay());
  const weeks = [];
  for (let w = 0; w < 6; w++) {
    const row = [];
    for (let d = 0; d < 7; d++) { const dt = new Date(start); dt.setDate(start.getDate() + w * 7 + d); row.push(dt); }
    weeks.push(row);
  }
  return weeks;
}
const todayISO = window.ARS.isoOf(new Date());

/* ---------- compact PIN modal ---------- */
function CalPin({ onClose, onOk }) {
  const [pin, setPin] = useS(""); const [err, setErr] = useS(false);
  const go = () => { if (pin === window.ARS.ADMIN_PIN) onOk(); else { setErr(true); setPin(""); } };
  return (
    <div onClick={(e) => e.target === e.currentTarget && onClose()} style={{ position: "fixed", inset: 0, zIndex: 200, background: "rgba(14,38,73,.55)", backdropFilter: "blur(4px)", display: "grid", placeItems: "center", padding: 16 }}>
      <div className="card rise" style={{ width: "100%", maxWidth: 360, padding: 28, textAlign: "center", boxShadow: "var(--shadow-lg)" }}>
        <div style={{ width: 52, height: 52, borderRadius: 13, background: "var(--navy-soft)", color: "var(--navy)", display: "grid", placeItems: "center", margin: "0 auto 12px" }}><Icon name="lock" size={24} /></div>
        <h3 style={{ fontSize: 20, color: "var(--navy)" }}>Owner access</h3>
        <p style={{ color: "var(--ink-2)", fontSize: 13.5, marginTop: 6 }}>Enter your PIN to edit availability.</p>
        <input autoFocus type="password" inputMode="numeric" value={pin} placeholder="••••" onChange={(e) => { setPin(e.target.value); setErr(false); }} onKeyDown={(e) => e.key === "Enter" && go()}
          style={{ width: 150, textAlign: "center", letterSpacing: ".4em", fontSize: 22, fontWeight: 800, padding: 11, borderRadius: 12, border: `2px solid ${err ? "#c0413a" : "var(--line)"}`, margin: "14px auto 0", display: "block", outline: "none" }} />
        {err && <div style={{ color: "#c0413a", fontWeight: 700, fontSize: 13, marginTop: 8 }}>Incorrect PIN</div>}
        <div style={{ fontSize: 12, color: "var(--ink-2)", marginTop: 9 }}>Demo PIN: <b>1990</b></div>
        <div style={{ display: "flex", gap: 10, marginTop: 16 }}>
          <button className="btn btn-ghost" style={{ flex: 1, justifyContent: "center" }} onClick={onClose}>Cancel</button>
          <button className="btn btn-navy" style={{ flex: 1, justifyContent: "center" }} onClick={go}>Unlock</button>
        </div>
      </div>
    </div>
  );
}

/* ---------- add-appointment form (owner) ---------- */
function AddAppt({ iso, taken, onAdd, onCancel }) {
  const firstOpen = W.find((w) => !taken.has(w.id)) || W[0];
  const [win, setWin] = useS(firstOpen.id);
  const [title, setTitle] = useS("");
  const [note, setNote] = useS("");
  return (
    <div className="card" style={{ padding: 16, background: "var(--navy-soft)", border: "none" }}>
      <div style={{ fontWeight: 800, color: "var(--navy)", marginBottom: 10 }}>New appointment</div>
      <input value={title} onChange={(e) => setTitle(e.target.value)} placeholder="Name / label (e.g. Mike — restring)"
        style={{ width: "100%", padding: "10px 12px", borderRadius: 10, border: "2px solid var(--line)", marginBottom: 9, outline: "none", font: "inherit" }} />
      <div style={{ display: "grid", gridTemplateColumns: "repeat(2,1fr)", gap: 7, marginBottom: 9 }}>
        {W.map((w) => {
          const t = taken.has(w.id); const on = win === w.id;
          return <button key={w.id} disabled={t} onClick={() => setWin(w.id)} style={{ padding: "9px 8px", borderRadius: 9, fontWeight: 700, fontSize: 13,
            border: `2px solid ${on ? "var(--green)" : "var(--line)"}`, background: on ? "var(--green-soft)" : "#fff", color: t ? "#b9bfc8" : "var(--navy)", cursor: t ? "not-allowed" : "pointer" }}>
            {w.label}{t ? " ·full" : ""}</button>;
        })}
      </div>
      <input value={note} onChange={(e) => setNote(e.target.value)} placeholder="Note (optional)"
        style={{ width: "100%", padding: "10px 12px", borderRadius: 10, border: "2px solid var(--line)", marginBottom: 11, outline: "none", font: "inherit" }} />
      <div style={{ display: "flex", gap: 8 }}>
        <button className="btn btn-ghost btn-sm" style={{ flex: 1, justifyContent: "center" }} onClick={onCancel}>Cancel</button>
        <button className="btn btn-green btn-sm" style={{ flex: 1, justifyContent: "center", opacity: taken.has(win) ? .5 : 1 }}
          disabled={taken.has(win)} onClick={() => onAdd({ window: win, title: title.trim() || "Appointment", note: note.trim() })}>Add</button>
      </div>
    </div>
  );
}

/* ---------- day detail drawer ---------- */
function DayPanel({ iso, dateObj, items, blocked, admin, onClose, onAdd, onDelete, onToggleBlock, onBook }) {
  const [adding, setAdding] = useS(false);
  const taken = new Set(items.map((i) => i.window));
  const isPast = iso < todayISO;
  const label = dateObj.toLocaleDateString("en-US", { weekday: "long", month: "long", day: "numeric", year: "numeric" });
  return (
    <div onClick={(e) => e.target === e.currentTarget && onClose()} style={{ position: "fixed", inset: 0, zIndex: 160, background: "rgba(14,38,73,.5)", backdropFilter: "blur(3px)" }}>
      <div className="rise" style={{ position: "absolute", top: 0, right: 0, bottom: 0, width: "min(440px,100%)", background: "var(--paper)", boxShadow: "var(--shadow-lg)", display: "flex", flexDirection: "column" }}>
        <div style={{ padding: "20px 22px", background: "var(--navy-deep)", color: "#fff", display: "flex", justifyContent: "space-between", alignItems: "flex-start" }}>
          <div><div style={{ fontSize: 12.5, color: "var(--ball)", fontWeight: 800, letterSpacing: ".08em", textTransform: "uppercase" }}>{blocked ? "Day off" : isPast ? "Past" : `${W.length - taken.size} of ${W.length} open`}</div>
            <div style={{ fontWeight: 800, fontSize: 19, marginTop: 3 }}>{label}</div></div>
          <button onClick={onClose} style={{ color: "#fff" }}><Icon name="x" size={23} /></button>
        </div>

        <div style={{ flex: 1, overflowY: "auto", padding: 20, display: "grid", gap: 11, alignContent: "start" }}>
          {blocked && <div className="card" style={{ padding: 16, textAlign: "center", color: "var(--ink-2)" }}><BallMark size={42} style={{ margin: "0 auto 10px", filter: "grayscale(1)" }} />Marked as a day off — not accepting bookings.</div>}

          {!blocked && W.map((w) => {
            const appt = items.find((i) => i.window === w.id);
            return (
              <div key={w.id} className="card" style={{ padding: "13px 15px", display: "flex", alignItems: "center", gap: 12,
                borderLeft: `5px solid ${appt ? "var(--navy)" : "var(--green)"}` }}>
                <div style={{ minWidth: 78 }}><div style={{ fontWeight: 800, color: "var(--navy)", fontSize: 14.5 }}>{w.label}</div><div style={{ fontSize: 12, color: "var(--ink-2)" }}>{w.time}</div></div>
                <div style={{ flex: 1, minWidth: 0 }}>
                  {appt ? (
                    admin ? <div><div style={{ fontWeight: 700 }}>{appt.name}</div><div style={{ fontSize: 12.5, color: "var(--ink-2)" }}>{appt.detail}{appt.note ? ` · ${appt.note}` : ""}</div></div>
                      : <span style={{ fontWeight: 700, color: "var(--ink-2)" }}>Booked</span>
                  ) : <span style={{ color: "var(--green-deep)", fontWeight: 700 }}>{isPast ? "—" : "Open"}</span>}
                </div>
                {appt && <span style={{ fontSize: 10, fontWeight: 800, letterSpacing: ".05em", textTransform: "uppercase", color: "#fff", background: appt.type === "booking" ? "var(--green)" : "var(--navy)", padding: "3px 8px", borderRadius: 100 }}>{appt.type === "booking" ? "Booking" : "Personal"}</span>}
                {admin && appt && <button onClick={() => onDelete(appt)} title="Remove" style={{ color: "#c0413a", padding: 4 }}><Icon name="trash" size={17} /></button>}
                {!appt && !isPast && !admin && <button className="btn btn-ball btn-sm" onClick={onBook} style={{ padding: "7px 13px" }}>Book</button>}
              </div>
            );
          })}

          {admin && !isPast && !blocked && (adding
            ? <AddAppt iso={iso} taken={taken} onAdd={(a) => { onAdd(a); setAdding(false); }} onCancel={() => setAdding(false)} />
            : taken.size < W.length && <button className="btn btn-navy" onClick={() => setAdding(true)} style={{ justifyContent: "center" }}><Icon name="plus" size={17} stroke={3} /> Add appointment</button>)}
        </div>

        {admin && !isPast && (
          <div style={{ padding: "14px 20px", borderTop: "1px solid var(--line)", display: "flex", gap: 10 }}>
            <button className="btn btn-ghost" style={{ flex: 1, justifyContent: "center" }} onClick={onToggleBlock}>
              {blocked ? "Reopen day" : "Mark as day off"}</button>
          </div>
        )}
        {!admin && !isPast && !blocked && taken.size < W.length && (
          <div style={{ padding: "14px 20px", borderTop: "1px solid var(--line)" }}>
            <button className="btn btn-green" style={{ width: "100%", justifyContent: "center" }} onClick={onBook}><Icon name="calendar" size={18} /> Book this day</button>
          </div>
        )}
      </div>
    </div>
  );
}

/* ---------- day cell ---------- */
function DayCell({ dateObj, inMonth, items, blocked, onClick }) {
  const iso = window.ARS.isoOf(dateObj);
  const isToday = iso === todayISO;
  const isPast = iso < todayISO;
  const taken = new Set(items.map((i) => i.window));
  const open = W.length - taken.size;
  let status = { txt: `${open} open`, bg: "var(--green-soft)", fg: "var(--green-deep)" };
  if (blocked) status = { txt: "Day off", bg: "#eceef1", fg: "#7c8696" };
  else if (open === 0) status = { txt: "Full", bg: "#fbe6e4", fg: "#c0413a" };
  else if (open <= 2) status = { txt: `${open} open`, bg: "#fdf4dd", fg: "#9a7b12" };
  return (
    <button onClick={() => onClick(iso, dateObj)} disabled={!inMonth}
      style={{ textAlign: "left", minHeight: 96, padding: "8px 9px", borderRadius: 12, position: "relative", display: "flex", flexDirection: "column", gap: 6,
        background: inMonth ? (isToday ? "#fff" : "var(--white)") : "transparent", border: `1.5px solid ${isToday ? "var(--navy)" : "var(--line)"}`,
        opacity: inMonth ? (isPast ? .5 : 1) : .25, cursor: inMonth ? "pointer" : "default", boxShadow: isToday ? "var(--shadow)" : "none" }}>
      <div style={{ display: "flex", justifyContent: "space-between", alignItems: "center" }}>
        <span className="display" style={{ fontSize: 18, color: isToday ? "var(--navy)" : "var(--ink)" }}>{dateObj.getDate()}</span>
        {inMonth && !isPast && <span style={{ display: "flex", gap: 3 }}>{W.map((w) => (
          <span key={w.id} style={{ width: 6, height: 6, borderRadius: "50%", background: blocked ? "#cfd4da" : (taken.has(w.id) ? "var(--navy)" : "var(--green)") }} />
        ))}</span>}
      </div>
      {inMonth && !isPast && <span className="ars-cell-status" style={{ alignSelf: "flex-start", fontSize: 11, fontWeight: 800, padding: "2px 8px", borderRadius: 100, background: status.bg, color: status.fg }}>{status.txt}</span>}
      <div className="ars-cell-chips" style={{ display: "flex", flexDirection: "column", gap: 3, marginTop: "auto" }}>
        {!blocked && items.slice(0, 2).map((it) => (
          <span key={it.id} style={{ fontSize: 11, fontWeight: 600, color: "var(--navy)", background: "var(--navy-soft)", padding: "2px 7px", borderRadius: 6, overflow: "hidden", textOverflow: "ellipsis", whiteSpace: "nowrap" }}>
            {window.ARS.windowLabel(it.window).slice(0, 3)} · {it.name.split(" ")[0]}</span>
        ))}
        {items.length > 2 && <span style={{ fontSize: 10.5, color: "var(--ink-2)", fontWeight: 700 }}>+{items.length - 2} more</span>}
      </div>
    </button>
  );
}

function CalApp() {
  const now = new Date();
  const [cursor, setCursor] = useS({ y: now.getFullYear(), m: now.getMonth() });
  const [bookings, setBookings] = useS(() => window.ARS.loadBookings());
  const [appts, setAppts] = useS(() => window.ARS.loadAppointments());
  const [blocked, setBlocked] = useS(() => window.ARS.loadBlocked());
  const [admin, setAdmin] = useS(false);
  const [showPin, setShowPin] = useS(false);
  const [sel, setSel] = useS(null); // {iso, dateObj}
  const [toast, showToast] = useToast();

  useE(() => { window.ARS.saveAppointments(appts); }, [appts]);
  useE(() => { window.ARS.saveBlocked(blocked); }, [blocked]);
  useE(() => { window.ARS.saveBookings(bookings); }, [bookings]);

  const weeks = useM(() => monthMatrix(cursor.y, cursor.m), [cursor]);
  const itemsFor = (iso) => window.ARS.apptsForDate(bookings, appts, iso);
  const move = (delta) => setCursor((c) => { const d = new Date(c.y, c.m + delta, 1); return { y: d.getFullYear(), m: d.getMonth() }; });

  const addAppt = (iso, a) => setAppts((p) => [...p, { id: window.ARS.uid("ap"), dateISO: iso, window: a.window, title: a.title, note: a.note, detail: "Personal appointment" }]);
  const delItem = (item) => {
    if (item.type === "booking") setBookings((p) => p.filter((b) => b.id !== item.id));
    else setAppts((p) => p.filter((a) => a.id !== item.id));
  };
  const toggleBlock = (iso) => setBlocked((p) => p.includes(iso) ? p.filter((x) => x !== iso) : [...p, iso]);

  const selItems = sel ? itemsFor(sel.iso) : [];
  const monthAppts = weeks.flat().filter((d) => d.getMonth() === cursor.m).reduce((n, d) => n + itemsFor(window.ARS.isoOf(d)).length, 0);

  return (
    <div>
      {/* admin bar */}
      {admin && (
        <div style={{ position: "sticky", top: 0, zIndex: 120, height: 46, background: "var(--ink)", color: "#fff", display: "flex", alignItems: "center", justifyContent: "space-between", padding: "0 18px", fontSize: 13.5 }}>
          <div style={{ display: "flex", alignItems: "center", gap: 9, fontWeight: 700 }}><span style={{ width: 9, height: 9, borderRadius: "50%", background: "var(--ball)", boxShadow: "0 0 0 4px rgba(216,230,59,.2)" }} /> Owner mode — tap any day to edit</div>
          <button onClick={() => setAdmin(false)} className="btn btn-sm" style={{ background: "var(--ball)", color: "var(--navy-deep)" }}>Exit</button>
        </div>
      )}

      {/* header */}
      <header style={{ borderBottom: "1px solid var(--line)", background: "#fff", position: "sticky", top: admin ? 46 : 0, zIndex: 90 }}>
        <div className="wrap" style={{ display: "flex", alignItems: "center", justifyContent: "space-between", height: 70, gap: 12 }}>
          <a href="#home" style={{ display: "flex", alignItems: "center", gap: 11 }}>
            <img src={LOGO} alt="ARS" style={{ width: 42, height: 42 }} />
            <span style={{ fontWeight: 800, fontSize: 16.5, color: "var(--navy)" }}>ARS<span style={{ color: "var(--green)" }}> Mobile</span></span>
          </a>
          <div style={{ display: "flex", alignItems: "center", gap: 10 }}>
            <a href="#home" className="ars-hide-sm" style={{ fontWeight: 600, fontSize: 14.5, color: "var(--ink)" }}>← Back to site</a>
            <a href="#book" className="btn btn-green btn-sm" style={{ padding: "11px 18px" }}><Icon name="calendar" size={16} /> Book now</a>
          </div>
        </div>
      </header>

      <main className="wrap" style={{ paddingTop: 30, paddingBottom: 70 }}>
        <div style={{ display: "flex", flexWrap: "wrap", gap: 16, alignItems: "flex-end", justifyContent: "space-between", marginBottom: 22 }}>
          <div>
            <div className="eyebrow" style={{ color: "var(--green)", marginBottom: 8 }}>Live availability</div>
            <h1 className="display" style={{ fontSize: "clamp(30px,5vw,46px)", color: "var(--ink)", whiteSpace: "nowrap" }}>{MONTHS[cursor.m]} {cursor.y}</h1>
          </div>
          <div style={{ display: "flex", gap: 8, alignItems: "center" }}>
            <button className="btn btn-ghost btn-sm" onClick={() => setCursor({ y: now.getFullYear(), m: now.getMonth() })}>Today</button>
            <button className="btn btn-ghost" style={{ padding: 11 }} onClick={() => move(-1)} aria-label="Previous month"><Icon name="chevron" size={18} style={{ transform: "rotate(180deg)" }} /></button>
            <button className="btn btn-ghost" style={{ padding: 11 }} onClick={() => move(1)} aria-label="Next month"><Icon name="chevron" size={18} /></button>
          </div>
        </div>

        {/* legend */}
        <div style={{ display: "flex", flexWrap: "wrap", gap: 16, marginBottom: 16, fontSize: 13, color: "var(--ink-2)", fontWeight: 600 }}>
          {[["var(--green)", "Open"], ["var(--navy)", "Booked"], ["#cfd4da", "Day off"]].map(([c, l]) => (
            <span key={l} style={{ display: "inline-flex", gap: 7, alignItems: "center" }}><span style={{ width: 10, height: 10, borderRadius: "50%", background: c }} />{l}</span>
          ))}
          <span style={{ marginLeft: "auto", color: "var(--navy)", fontWeight: 700 }}>{monthAppts} appointment{monthAppts !== 1 ? "s" : ""} this month</span>
        </div>

        {/* weekday header */}
        <div style={{ display: "grid", gridTemplateColumns: "repeat(7,1fr)", gap: 8, marginBottom: 8 }}>
          {DOW.map((d) => <div key={d} style={{ textAlign: "center", fontWeight: 800, fontSize: 12, letterSpacing: ".06em", textTransform: "uppercase", color: "var(--ink-2)" }}><span className="ars-dow-full">{d}</span><span className="ars-dow-sm">{d[0]}</span></div>)}
        </div>

        {/* grid */}
        <div style={{ display: "grid", gap: 8 }}>
          {weeks.map((week, wi) => (
            <div key={wi} style={{ display: "grid", gridTemplateColumns: "repeat(7,1fr)", gap: 8 }}>
              {week.map((d, di) => {
                const iso = window.ARS.isoOf(d);
                return <DayCell key={di} dateObj={d} inMonth={d.getMonth() === cursor.m} items={itemsFor(iso)} blocked={blocked.includes(iso)} onClick={(iso, dateObj) => setSel({ iso, dateObj })} />;
              })}
            </div>
          ))}
        </div>

        {/* owner login hint */}
        {!admin && <p style={{ textAlign: "center", color: "var(--ink-2)", fontSize: 13.5, marginTop: 24 }}>
          Owner? <button onClick={() => setShowPin(true)} style={{ color: "var(--green-deep)", fontWeight: 800, textDecoration: "underline" }}>Sign in to manage availability</button></p>}
      </main>

      {/* floating owner login */}
      {!admin && <button onClick={() => setShowPin(true)} title="Owner login" style={{ position: "fixed", bottom: 20, right: 20, zIndex: 80, width: 46, height: 46, borderRadius: "50%", background: "var(--navy)", color: "#fff", display: "grid", placeItems: "center", boxShadow: "var(--shadow-lg)", opacity: .6 }}><Icon name="lock" size={20} /></button>}

      {sel && <DayPanel iso={sel.iso} dateObj={sel.dateObj} items={selItems} blocked={blocked.includes(sel.iso)} admin={admin}
        onClose={() => setSel(null)} onAdd={(a) => { addAppt(sel.iso, a); showToast("Appointment added"); }}
        onDelete={(it) => { delItem(it); showToast("Removed"); }} onToggleBlock={() => { toggleBlock(sel.iso); }}
        onBook={() => { window.location.hash = "#book"; }} />}
      {showPin && <CalPin onClose={() => setShowPin(false)} onOk={() => { setShowPin(false); setAdmin(true); showToast("Owner mode on"); }} />}
      {toast}

      <style>{`
        .ars-dow-sm{display:none;}
        @media (max-width:640px){
          .ars-dow-full{display:none;} .ars-dow-sm{display:inline;}
          .ars-cell-chips{display:none !important;}
          .ars-cell-status{font-size:9.5px !important; padding:1px 5px !important;}
        }
        @media (max-width:420px){ .ars-hide-sm{display:none;} }
      `}</style>
    </div>
  );
}

ReactDOM.createRoot(document.getElementById("cal-root")).render(<CalApp />);
