/* global React, Glyph */
/* Chantelle — modeling modal, message form, and persistent inbox.
   Messages are stored in localStorage so they "sit in the site"
   until Chantelle opens her inbox (the header envelope) and reads them. */
const { useState: useStateM, useEffect: useEffectM, useCallback: useCallbackM } = React;

/* ---------- icons ---------- */
const Icon = {
  x:     <svg viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="1.5" strokeLinecap="round"><path d="M6 6l12 12M18 6L6 18"/></svg>,
  go:    <svg viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="1.5" strokeLinecap="round" strokeLinejoin="round"><path d="M5 12h14M13 6l6 6-6 6"/></svg>,
  back:  <svg viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="1.5" strokeLinecap="round" strokeLinejoin="round"><path d="M19 12H5M11 6l-6 6 6 6"/></svg>,
  cal:   <svg viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="1.5"><rect x="3.5" y="4.5" width="17" height="16" rx="2.5"/><path d="M3.5 9h17M8 3v3M16 3v3" strokeLinecap="round"/></svg>,
  chat:  <svg viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="1.5" strokeLinecap="round" strokeLinejoin="round"><path d="M4 5h16v11H9l-4 3.5V16H4z"/></svg>,
  check: <svg viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="1.5" strokeLinecap="round" strokeLinejoin="round"><path d="M5 12.5l4.5 4.5L19 7"/></svg>,
};

/* ---------- inbox store ---------- */
const INBOX_KEY = "chantelle_inbox_v1";
function readInbox(){ try{ return JSON.parse(localStorage.getItem(INBOX_KEY) || "[]"); }catch(e){ return []; } }
function writeInbox(list){ localStorage.setItem(INBOX_KEY, JSON.stringify(list)); window.dispatchEvent(new Event("cw-inbox")); }
function addMessage(msg){
  const list = readInbox();
  list.unshift({ id: Date.now() + "-" + Math.random().toString(36).slice(2,7), date: Date.now(), read: false, ...msg });
  writeInbox(list);
}
function markRead(id){ writeInbox(readInbox().map((m) => m.id === id ? { ...m, read: true } : m)); }
function useInbox(){
  const [list, setList] = useStateM(readInbox);
  useEffectM(() => {
    const h = () => setList(readInbox());
    window.addEventListener("cw-inbox", h); window.addEventListener("storage", h);
    return () => { window.removeEventListener("cw-inbox", h); window.removeEventListener("storage", h); };
  }, []);
  return list;
}
function fmtTime(ts){
  const d = new Date(ts), now = new Date();
  const sameDay = d.toDateString() === now.toDateString();
  if (sameDay) return d.toLocaleTimeString([], { hour: "numeric", minute: "2-digit" });
  return d.toLocaleDateString([], { month: "short", day: "numeric" });
}

/* ---------- modal shell ---------- */
function Modal({ children, onClose, wide }){
  const [closing, setClosing] = useStateM(false);
  const close = useCallbackM(() => { setClosing(true); setTimeout(onClose, 210); }, [onClose]);
  useEffectM(() => {
    const h = (e) => { if (e.key === "Escape") close(); };
    window.addEventListener("keydown", h);
    return () => window.removeEventListener("keydown", h);
  }, [close]);
  return (
    <div className={"cw-backdrop" + (closing ? " closing" : "")}
         onMouseDown={(e) => { if (e.target === e.currentTarget) close(); }}>
      <div className={"cw-modal" + (wide ? " wide" : "")} role="dialog" aria-modal="true">
        <button className="cw-modal-x" onClick={close} aria-label="Close">{Icon.x}</button>
        {typeof children === "function" ? children(close) : children}
      </div>
    </div>
  );
}

/* ---------- modeling modal (choice → book / message → sent) ---------- */
function ModelingModal({ onClose, site }){
  return <Modal onClose={onClose}>{(close) => <ModelingInner close={close} site={site} />}</Modal>;
}
function ModelingInner({ close, site }){
  const [view, setView] = useStateM("choice");
  const [form, setForm] = useStateM({ name: "", email: "", body: "" });
  const [date, setDate] = useStateM(null);
  const [time, setTime] = useStateM(null);
  const set = (k) => (e) => setForm((f) => ({ ...f, [k]: e.target.value }));
  const valid = form.name.trim() && form.email.trim() && form.body.trim();

  const av = (site && site.availability) || { slots: [], days: [true,true,true,true,true,true,true] };
  const bookValid = form.name.trim() && form.email.trim() && date && time;
  const dateLabel = date && date.toLocaleDateString([], { weekday: "long", month: "long", day: "numeric" });

  if (view === "choice") return (
    <div className="cw-modal-pad">
      <p className="cw-modal-kicker">Modeling</p>
      <h2 className="cw-modal-title">Let's work together</h2>
      <p className="cw-modal-sub">Reserve a date for a shoot, or send a note and Chantelle will get back to you personally.</p>
      <div className="cw-choices">
        <button className="cw-choice" onClick={() => setView("book")}>
          <span className="cw-ci">{Icon.cal}</span>
          <span className="cw-ct"><h4>Book a shoot</h4><p>Pick a date &amp; start the booking</p></span>
          <span className="cw-cgo">{Icon.go}</span>
        </button>
        <button className="cw-choice" onClick={() => setView("message")}>
          <span className="cw-ci">{Icon.chat}</span>
          <span className="cw-ct"><h4>Send a message</h4><p>Ask a question or share details</p></span>
          <span className="cw-cgo">{Icon.go}</span>
        </button>
      </div>
    </div>
  );

  if (view === "book") return (
    <div className="cw-modal-pad">
      <button className="cw-back" onClick={() => setView("choice")}>{Icon.back} Back</button>
      <p className="cw-modal-kicker">Modeling · Booking</p>
      <h2 className="cw-modal-title" style={{ fontSize: 38 }}>Choose a date</h2>
      <div style={{ marginTop: 20 }}>
        <Calendar selected={date} onSelect={setDate} openDays={av.days} />
      </div>
      <div className="slots">
        {av.slots.map((s) => (
          <button key={s} className={"slot" + (time === s ? " is-sel" : "")} onClick={() => setTime(s)}>{s}</button>
        ))}
      </div>
      <div className="cw-field"><label>Your name</label><input value={form.name} onChange={set("name")} placeholder="Full name" /></div>
      <div className="cw-field"><label>Email</label><input type="email" value={form.email} onChange={set("email")} placeholder="you@email.com" /></div>
      <div className="cw-field"><label>About the shoot <span style={{ textTransform: "none", letterSpacing: 0, opacity: .6 }}>(optional)</span></label><textarea value={form.body} onChange={set("body")} placeholder="Concept, location, references…" style={{ minHeight: 64 }} /></div>
      <button className="cw-submit" disabled={!bookValid} style={!bookValid ? { opacity: .4, cursor: "default" } : {}}
        onClick={() => { if (!bookValid) return; addMessage({ kind: "Booking request", name: form.name.trim(), email: form.email.trim(),
          reqISO: date.toISOString(), reqTime: time, session: "Modeling shoot",
          body: "Requested date: " + dateLabel + "\nSession: " + time + (form.body.trim() ? "\n\n" + form.body.trim() : "") }); setView("booksent"); }}>
        {bookValid ? "Request this date" : "Pick a date & time"} {Icon.go}
      </button>
    </div>
  );

  if (view === "message") return (
    <div className="cw-modal-pad">
      <button className="cw-back" onClick={() => setView("choice")}>{Icon.back} Back</button>
      <p className="cw-modal-kicker">Modeling</p>
      <h2 className="cw-modal-title">Send a message</h2>
      <div className="cw-field"><label>Your name</label><input value={form.name} onChange={set("name")} placeholder="Full name" /></div>
      <div className="cw-field"><label>Email</label><input type="email" value={form.email} onChange={set("email")} placeholder="you@email.com" /></div>
      <div className="cw-field"><label>Message</label><textarea value={form.body} onChange={set("body")} placeholder="Tell Chantelle about the project, dates, and rates…" /></div>
      <button className="cw-submit" disabled={!valid} style={!valid ? { opacity: .4, cursor: "default" } : {}}
        onClick={() => { if (!valid) return; addMessage({ kind: "Modeling enquiry", name: form.name.trim(), email: form.email.trim(), body: form.body.trim() }); setView("sent"); }}>
        Send message {Icon.go}
      </button>
    </div>
  );

  if (view === "booksent") return (
    <div className="cw-sent">
      <span className="cw-seal">{Icon.check}</span>
      <h2 className="cw-modal-title" style={{ fontSize: 38 }}>Request sent</h2>
      <p className="cw-modal-sub" style={{ margin: "14px auto 0" }}>Your request for <b style={{ color: "var(--ink)", fontWeight: 400 }}>{dateLabel}, {time}</b> is in Chantelle's inbox. She confirms within 24 hours.</p>
      <button className="cw-submit" style={{ maxWidth: 220, margin: "30px auto 0" }} onClick={close}>Done</button>
    </div>
  );

  /* sent (message) */
  return (
    <div className="cw-sent">
      <span className="cw-seal">{Icon.check}</span>
      <h2 className="cw-modal-title" style={{ fontSize: 38 }}>Message sent</h2>
      <p className="cw-modal-sub" style={{ margin: "14px auto 0" }}>It will sit in Chantelle's inbox until she reads it. She replies to every note personally.</p>
      <button className="cw-submit" style={{ maxWidth: 220, margin: "30px auto 0" }} onClick={close}>Close</button>
    </div>
  );
}

/* ---------- inbox (Chantelle's view) ---------- */
function InboxModal({ onClose }){
  return <Modal onClose={onClose} wide>{() => <InboxInner />}</Modal>;
}
function InboxInner(){
  const list = useInbox();
  const [openId, setOpenId] = useStateM(null);
  const open = list.find((m) => m.id === openId);
  const unread = list.filter((m) => !m.read).length;

  if (open) return (
    <div>
      <div className="cw-inbox-head">
        <button className="cw-back" onClick={() => setOpenId(null)}>{Icon.back} All messages</button>
        <p className="cw-msg-kind cw-mkind" style={{ marginTop: 14 }}>{open.kind}</p>
        <h2 className="cw-modal-title" style={{ fontSize: 30, marginTop: 6 }}>{open.name}</h2>
      </div>
      <div className="cw-msg-full">
        <p className="cw-mprev" style={{ maxWidth: "none", whiteSpace: "normal", overflow: "visible" }}>{open.email} · {new Date(open.date).toLocaleString([], { dateStyle: "medium", timeStyle: "short" })}</p>
        <p className="cw-mbody">{open.body}</p>
        <a className="cw-submit" style={{ maxWidth: 220, marginTop: 28 }} href={"mailto:" + open.email}>Reply {Icon.go}</a>
      </div>
    </div>
  );

  return (
    <div>
      <div className="cw-inbox-head">
        <p className="cw-modal-kicker">Private</p>
        <h2 className="cw-modal-title" style={{ fontSize: 34 }}>Inbox</h2>
        <p className="cw-modal-sub" style={{ marginTop: 8 }}>{list.length ? (unread ? unread + " unread · " : "") + list.length + " message" + (list.length === 1 ? "" : "s") : "Messages from your site land here."}</p>
      </div>
      {list.length === 0 ? (
        <div className="cw-inbox-empty">No messages yet.</div>
      ) : (
        <div className="cw-inbox-list">
          {list.map((m) => (
            <button key={m.id} className={"cw-msg" + (m.read ? " read" : "")}
              onClick={() => { markRead(m.id); setOpenId(m.id); }}>
              <span className="cw-unread" />
              <span>
                <p className="cw-mkind">{m.kind}</p>
                <p className="cw-mfrom">{m.name}</p>
                <p className="cw-mprev">{m.body}</p>
              </span>
              <span className="cw-mtime">{fmtTime(m.date)}</span>
            </button>
          ))}
        </div>
      )}
    </div>
  );
}

/* ---------- header mail button with unread badge (used in the back office) ---------- */
function MailButton({ theme = "light" }){
  const list = useInbox();
  const unread = list.filter((m) => !m.read).length;
  const [open, setOpen] = useStateM(false);
  return (
    <>
      <button className={"cw-social cw-mailbtn is-" + theme} onClick={() => setOpen(true)} aria-label="Inbox">
        {Glyph.mail}
        {unread > 0 && <span className="cw-badge">{unread}</span>}
      </button>
      {open && <InboxModal onClose={() => setOpen(false)} />}
    </>
  );
}

/* ---------- visitor message composer (one-way → lands in inbox) ---------- */
function MessageModal({ onClose }){
  return <Modal onClose={onClose}>{(close) => <MessageInner close={close} />}</Modal>;
}
function MessageInner({ close }){
  const [view, setView] = useStateM("form");
  const [form, setForm] = useStateM({ name: "", email: "", body: "" });
  const set = (k) => (e) => setForm((f) => ({ ...f, [k]: e.target.value }));
  const valid = form.name.trim() && form.email.trim() && form.body.trim();

  if (view === "sent") return (
    <div className="cw-sent">
      <span className="cw-seal">{Icon.check}</span>
      <h2 className="cw-modal-title" style={{ fontSize: 38 }}>Message sent</h2>
      <p className="cw-modal-sub" style={{ margin: "14px auto 0" }}>Thank you — Chantelle has your note and replies to every message personally.</p>
      <button className="cw-submit" style={{ maxWidth: 220, margin: "30px auto 0" }} onClick={close}>Close</button>
    </div>
  );

  return (
    <div className="cw-modal-pad">
      <p className="cw-modal-kicker">Message</p>
      <h2 className="cw-modal-title">Say hello</h2>
      <p className="cw-modal-sub">Leave a note — a question, a project, or just to say hi. Chantelle reads every message and will reply by email.</p>
      <div className="cw-field"><label>Your name</label><input value={form.name} onChange={set("name")} placeholder="Full name" /></div>
      <div className="cw-field"><label>Email</label><input type="email" value={form.email} onChange={set("email")} placeholder="you@email.com" /></div>
      <div className="cw-field"><label>Message</label><textarea value={form.body} onChange={set("body")} placeholder="Write your message…" /></div>
      <button className="cw-submit" disabled={!valid} style={!valid ? { opacity: .4, cursor: "default" } : {}}
        onClick={() => { if (!valid) return; addMessage({ kind: "Message", name: form.name.trim(), email: form.email.trim(), body: form.body.trim() }); setView("sent"); }}>
        Send message {Icon.go}
      </button>
    </div>
  );
}
/* header button for visitors — opens the composer (no inbox, one-way) */
function MessageButton({ theme = "light" }){
  const [open, setOpen] = useStateM(false);
  return (
    <>
      <button className={"cw-social is-" + theme} onClick={() => setOpen(true)} aria-label="Send a message">{Glyph.mail}</button>
      {open && <MessageModal onClose={() => setOpen(false)} />}
    </>
  );
}

Object.assign(window, { Icon, Modal, ModelingModal, InboxModal, MailButton, MessageModal, MessageButton, useInbox, addMessage });
