/* ============================================================
   Unified Inbox — the spine. Three layouts: unibox | split | table
   Missive-style unibox where replies land + get triaged.
   ============================================================ */

const TRIAGE_TABS = [
  { id: "needs_attention", label: "Needs attention", icon: "flame" },
  { id: "drafts",          label: "Drafts",          icon: "draft" },
  { id: "interested",      label: "Interested",      icon: "trend" },
  { id: "awaiting",        label: "Awaiting reply",  icon: "clock" },
  { id: "not_now",         label: "Not now",         icon: "snooze" },
  { id: "pass",            label: "Pass",            icon: "x" },
];

const SNOOZE_OPTS = ["1 day", "3 days", "1 week", "30 days"];

function timeAgo(t) { return t === "today" || t === "now" ? "Today" : t; }

// ---------- Thread row ----------
function ThreadRow({ th, active, onClick, onTriage, onStar, dense }) {
  const triageMeta = window.WTC.TRIAGE_META[th.triage];
  const last = th.messages[th.messages.length - 1];
  const fromThem = last.from === "them";
  return (
    <div className="thread-row lift" data-active={active || undefined} onClick={onClick}>
      <button className="row-star" onClick={(e) => { e.stopPropagation(); onStar(th.id); }} title="Star">
        <StarIcon filled={th.starred} size={15} />
      </button>
      <Avatar mono={th.mono} size={dense ? 28 : 34} square />
      <div style={{ minWidth: 0, flex: 1 }}>
        <div style={{ display: "flex", alignItems: "center", gap: 8, marginBottom: 2 }}>
          <span style={{ fontWeight: th.unread ? 700 : 600, fontSize: 13.5, color: "var(--text)", whiteSpace: "nowrap" }}>
            {th.brand}
          </span>
          <LaneChip lane={th.lane} small />
          {th.unread && <span style={{ width: 7, height: 7, borderRadius: "50%", background: "var(--accent)", flex: "none" }}></span>}
          <span style={{ flex: 1 }}></span>
          <span style={{ fontSize: 11.5, color: "var(--text-3)", whiteSpace: "nowrap" }}>{timeAgo(th.lastTouch)}</span>
        </div>
        <div style={{ fontSize: 13, color: th.unread ? "var(--text)" : "var(--text-2)", fontWeight: th.unread ? 600 : 500, whiteSpace: "nowrap", overflow: "hidden", textOverflow: "ellipsis", marginBottom: 2 }}>
          {th.subject}
        </div>
        <div style={{ display: "flex", alignItems: "center", gap: 7 }}>
          <span style={{ fontSize: 11.5, color: triageMeta.color, fontWeight: 600, display: "inline-flex", alignItems: "center", gap: 4, whiteSpace: "nowrap" }}>
            {fromThem && th.triage === "needs_attention" && <Icon name="reply" size={12} />}
            {triageMeta.label}
          </span>
          {th.hasDraft && <span className="draft-flag"><Icon name="draft" size={10} /> Draft</span>}
          <span style={{ fontSize: 11.5, color: "var(--text-3)" }}>·</span>
          <span style={{ fontSize: 12, color: "var(--text-3)", whiteSpace: "nowrap", overflow: "hidden", textOverflow: "ellipsis" }}>
            {(fromThem ? "" : "You: ") + last.body}
          </span>
        </div>
      </div>
      <span className="num" style={{ fontSize: 11, color: "var(--text-3)", flex: "none", alignSelf: "flex-start", marginTop: 2 }}>
        {th.step}/{th.total}
      </span>
    </div>
  );
}

// ---------- Reading pane ----------
function ReadingPane({ th, target, onTriage, onSnooze, big, onOpenTarget }) {
  const [replying, setReplying] = React.useState(th.triage === "needs_attention" || th.hasDraft);
  const [snoozeOpen, setSnoozeOpen] = React.useState(false);
  const [openMsgs, setOpenMsgs] = React.useState(() => new Set([th.messages.length - 1]));
  React.useEffect(() => {
    setReplying(th.triage === "needs_attention" || th.hasDraft);
    setSnoozeOpen(false);
    setOpenMsgs(new Set([th.messages.length - 1]));
  }, [th.id]);
  const toggleMsg = (i) => setOpenMsgs((s) => {
    const n = new Set(s); n.has(i) ? n.delete(i) : n.add(i); return n;
  });

  // reply intelligence
  const hasInbound = window.replyIntel && window.replyIntel.lastInbound(th);
  const [intel, setIntel] = React.useState(null);
  const [booking, setBooking] = React.useState(false);
  React.useEffect(() => {
    setIntel(null);
    if (!hasInbound) return;
    let live = true;
    window.replyIntel.analyze(th).then((r) => { if (live) setIntel(r); });
    return () => { live = false; };
  }, [th.id]);
  const SENT = { positive: { c: "var(--green)", l: "Positive" }, cautious: { c: "var(--amber)", l: "Cautious" }, negative: { c: "var(--red)", l: "Negative" }, neutral: { c: "var(--text-2)", l: "Neutral" } };
  const doAction = (a) => {
    if (!a) return;
    if (a.kind === "book") setBooking(true);
    else if (a.kind === "pass") onTriage(th.id, "pass");
    else setReplying(true);
  };

  return (
    <div className="reading-pane" key={th.id}>
      {/* header */}
      <div className="rp-head">
        <div style={{ display: "flex", alignItems: "center", gap: 12, minWidth: 0 }}>
          <Avatar mono={th.mono} size={40} square />
          <div style={{ minWidth: 0 }}>
            <div style={{ display: "flex", alignItems: "center", gap: 9 }}>
              <span style={{ fontSize: 17, fontWeight: 680, letterSpacing: "-0.01em", cursor: onOpenTarget ? "pointer" : "default" }}
                onClick={() => onOpenTarget && onOpenTarget(th.targetId)} title={onOpenTarget ? "Open target" : undefined}>{th.brand}</span>
              <LaneChip lane={th.lane} />
              <StageDot stage={th.stage} />
              {onOpenTarget && <button className="btn btn--ghost btn--icon btn--sm" title="Open target detail" onClick={() => onOpenTarget(th.targetId)}><Icon name="arrowUpRight" size={15} /></button>}
            </div>
            <div style={{ fontSize: 12.5, color: "var(--text-2)", marginTop: 3 }}>
              {th.contact.name} · {th.contact.title} · <span className="num">{th.step}/{th.total}</span> in cadence
            </div>
          </div>
        </div>
        <div style={{ display: "flex", alignItems: "center", gap: 7, position: "relative" }}>
          <button className="btn btn--sm" style={{ color: "var(--green)" }}
            onClick={() => onTriage(th.id, "interested")}>
            <Icon name="check" size={14} /> Interested
          </button>
          <button className="btn btn--sm" onClick={() => setSnoozeOpen((s) => !s)}>
            <Icon name="snooze" size={14} /> Not now
          </button>
          <button className="btn btn--sm btn--danger" onClick={() => onTriage(th.id, "pass")}>
            <Icon name="x" size={14} /> Pass
          </button>
          {snoozeOpen && (
            <div className="menu-pop" style={{ top: 40, right: 0 }}>
              <div className="menu-label">Snooze — resurfaces as a draft</div>
              {SNOOZE_OPTS.map((o) => (
                <button key={o} className="menu-item" onClick={() => { onSnooze(th.id, o); setSnoozeOpen(false); }}>
                  <Icon name="clock" size={14} /> {o}
                </button>
              ))}
            </div>
          )}
        </div>
      </div>

      {/* cadence ribbon */}
      <div className="rp-ribbon">
        <span style={{ display: "inline-flex", alignItems: "center", gap: 6, color: "var(--text-2)" }}>
          <Icon name="sequence" size={14} style={{ color: "var(--accent)" }} />
          {target?.cadence?.label || `Step ${th.step} of ${th.total}`}
        </span>
        <span style={{ color: "var(--text-3)" }}>·</span>
        <span style={{ color: "var(--text-2)" }}>Next due <b style={{ color: "var(--text)", fontWeight: 600 }}>{target?.cadence?.nextDue}</b></span>
        {th.triage === "needs_attention" && (
          <span style={{ marginLeft: "auto", color: "var(--amber)", display: "inline-flex", alignItems: "center", gap: 5, fontWeight: 600 }}>
            <Icon name="pause" size={13} /> Cadence paused — they replied
          </span>
        )}
      </div>

      {/* conversation */}
      <div className="rp-body">
        <div style={{ fontSize: 13, fontWeight: 650, color: "var(--text-2)", marginBottom: 4 }}>{th.subject}</div>
        {th.messages.map((m, i) => {
          const mine = m.from === "me";
          const open = openMsgs.has(i);
          return (
            <div key={m.id} className={"msg" + (open ? "" : " msg--collapsed")} data-mine={mine || undefined}>
              <div className="msg-head" onClick={() => toggleMsg(i)} style={{ cursor: "pointer" }}>
                {mine
                  ? <Avatar name={window.WTC.ME.name} initials={window.WTC.ME.initials} size={26} />
                  : <Avatar name={th.contact.name} initials={th.contact.initials} color={th.contact.color} size={26} />}
                <span style={{ fontWeight: 650, fontSize: 13 }}>{mine ? "Preston" : th.contact.name}</span>
                {mine && open && <span style={{ fontSize: 10.5, color: "var(--accent)", border: "1px solid var(--accent-22)", borderRadius: 5, padding: "1px 6px" }}>preston@wethecreators.co</span>}
                {!open && <span className="msg-preview">{m.body}</span>}
                {open && <span style={{ flex: 1 }}></span>}
                <span style={{ fontSize: 11.5, color: "var(--text-3)" }}>{m.time}</span>
                <Icon name="chevronDown" size={14} style={{ color: "var(--text-3)", transform: open ? "rotate(180deg)" : "none", transition: "transform var(--t)", flex: "none" }} />
              </div>
              {open && <div className="msg-body">{m.body}</div>}
            </div>
          );
        })}
      </div>

      {/* reply intelligence */}
      {hasInbound && intel && (
        <div className="intel-card">
          <div className="intel-card-head">
            <span style={{ display: "inline-flex", alignItems: "center", gap: 7, fontSize: 11.5, fontWeight: 650, letterSpacing: "0.03em", textTransform: "uppercase", color: "var(--accent)" }}>
              <Icon name="sparkles" size={13} /> Claude read this reply
            </span>
            <span className="intel-sent" style={{ color: SENT[intel.sentiment].c, background: SENT[intel.sentiment].c + "1f" }}>{SENT[intel.sentiment].l}</span>
          </div>
          <div className="intel-summary">{intel.summary}</div>
          <div className="intel-asks">
            {intel.asks.map((a, i) => (
              <span key={i} className="intel-ask" title={a.detail}><Icon name={a.icon || "reply"} size={12} /> {a.tag}</span>
            ))}
          </div>
          <div className="intel-action">
            <span style={{ fontSize: 11.5, color: "var(--text-3)" }}>Suggested next step</span>
            <button className="btn btn--primary btn--sm" onClick={() => doAction(intel.action)}><Icon name={intel.action.icon} size={14} /> {intel.action.label}</button>
          </div>
        </div>
      )}

      {/* reply composer */}
      <div className="rp-reply">
        {replying ? (
          <Composer target={target} contact={th.contact} thread={th.messages}
            initialDraft={th.hasDraft ? th.draftBody : null}
            subject={"Re: " + th.subject.replace(/^Re:\s*/i, "")}
            onSent={() => onTriage(th.id, "awaiting")} />
        ) : (
          <button className="btn btn--primary" onClick={() => setReplying(true)} style={{ width: "100%", height: 42 }}>
            <Icon name="sparkles" size={16} /> Draft reply with Claude
          </button>
        )}
      </div>
      {booking && <BookingModal contact={th.contact} brand={th.brand} onClose={() => setBooking(false)} onBooked={() => { setBooking(false); onTriage(th.id, "interested"); }} />}
    </div>
  );
}

// ---- Google Calendar booking ----
function BookingModal({ contact, brand, onClose, onBooked }) {
  const [connected, setConnected] = React.useState(true);
  const [day, setDay] = React.useState(1);
  const [slot, setSlot] = React.useState(null);
  const [dur, setDur] = React.useState(30);
  const [booked, setBooked] = React.useState(false);
  const DAYS = ["Tue Jun 3", "Wed Jun 4", "Thu Jun 5", "Fri Jun 6"];
  const SLOTS = ["9:00 AM", "10:30 AM", "11:00 AM", "1:00 PM", "2:30 PM", "4:00 PM"];
  const book = () => { setBooked(true); setTimeout(onBooked, 1100); };
  return (
    <div className="modal-scrim" onClick={onClose}>
      <div className="modal" style={{ width: "min(480px, 100%)" }} onClick={(e) => e.stopPropagation()}>
        <div className="modal-head">
          <div style={{ display: "flex", alignItems: "center", gap: 10 }}>
            <div className="gcal-badge"><Icon name="calendar" size={16} /></div>
            <div>
              <div style={{ fontSize: 15, fontWeight: 680 }}>Book a meeting</div>
              <div style={{ fontSize: 11.5, color: "var(--text-3)", display: "flex", alignItems: "center", gap: 5 }}>
                <span className="stagedot" style={{ background: "var(--green)" }}></span>Google Calendar connected · preston@wethecreators.co
              </div>
            </div>
          </div>
          <button className="btn btn--ghost btn--icon" onClick={onClose}><Icon name="x" size={18} /></button>
        </div>
        {booked ? (
          <div className="modal-body" style={{ textAlign: "center", padding: "30px 22px 34px" }}>
            <div className="book-done"><Icon name="check" size={26} /></div>
            <div style={{ fontSize: 15, fontWeight: 680, marginTop: 14 }}>Meeting booked</div>
            <div style={{ fontSize: 13, color: "var(--text-2)", marginTop: 5 }}>{DAYS[day]} · {slot} · {dur} min with {contact.name}</div>
            <div style={{ fontSize: 12, color: "var(--text-3)", marginTop: 8 }}>Invite sent · added to Google Calendar · {brand} moved to Interested</div>
          </div>
        ) : (
          <React.Fragment>
            <div className="modal-body" style={{ display: "flex", flexDirection: "column", gap: 16 }}>
              <div className="insp-note">Intro call with <b>{contact.name}</b> — {contact.title} at {brand}. Pulls your real free/busy from Google Calendar.</div>
              <div className="brief-field"><label className="brief-label">Duration</label>
                <Segmented value={dur + " min"} onChange={(v) => setDur(parseInt(v))} options={["15 min", "30 min", "45 min"]} /></div>
              <div className="brief-field"><label className="brief-label">Day</label>
                <div className="facet-chips">{DAYS.map((d, i) => <button key={d} className="facet-chip" data-on={day === i || undefined} onClick={() => { setDay(i); setSlot(null); }}>{d}</button>)}</div></div>
              <div className="brief-field"><label className="brief-label">Open slots</label>
                <div className="slot-grid">{SLOTS.map((s) => <button key={s} className="slot" data-on={slot === s || undefined} onClick={() => setSlot(s)}>{s}</button>)}</div></div>
            </div>
            <div style={{ display: "flex", justifyContent: "flex-end", gap: 8, padding: "0 22px 20px" }}>
              <button className="btn" onClick={onClose}>Cancel</button>
              <button className="btn btn--primary" onClick={book} disabled={!slot}><Icon name="calendar" size={14} /> {slot ? `Book ${DAYS[day]}, ${slot}` : "Pick a slot"}</button>
            </div>
          </React.Fragment>
        )}
      </div>
    </div>
  );
}

// ---------- Dense table ----------
function ThreadTable({ threads, onOpen }) {
  return (
    <div className="dense-wrap">
      <table className="dense">
        <thead>
          <tr>
            <th style={{ width: 30 }}></th>
            <th>Target</th><th>Type</th><th>Subject</th>
            <th>State</th><th style={{ width: 70 }}>Step</th>
            <th>Last touch</th><th style={{ width: 90 }}></th>
          </tr>
        </thead>
        <tbody>
          {threads.map((th) => {
            const tm = window.WTC.TRIAGE_META[th.triage];
            return (
              <tr key={th.id} onClick={() => onOpen(th.id)} className="lift">
                <td><StarIcon filled={th.starred} size={14} /></td>
                <td><div style={{ display: "flex", alignItems: "center", gap: 9 }}>
                  <Avatar mono={th.mono} size={26} square />
                  <span style={{ fontWeight: 600, color: th.unread ? "var(--text)" : "var(--text-2)" }}>{th.brand}</span>
                  {th.unread && <span style={{ width: 6, height: 6, borderRadius: "50%", background: "var(--accent)" }}></span>}
                </div></td>
                <td><LaneChip lane={th.lane} small /></td>
                <td style={{ color: "var(--text-2)", maxWidth: 320, overflow: "hidden", textOverflow: "ellipsis", whiteSpace: "nowrap" }}>{th.subject}</td>
                <td><span style={{ color: tm.color, fontWeight: 600, fontSize: 12.5 }}>{tm.label}</span></td>
                <td><span className="num" style={{ color: "var(--text-2)" }}>{th.step}/{th.total}</span></td>
                <td style={{ color: "var(--text-3)" }}>{timeAgo(th.lastTouch)}</td>
                <td><button className="btn btn--sm btn--ghost" onClick={(e) => { e.stopPropagation(); onOpen(th.id); }} style={{ color: "var(--accent)" }}>Open</button></td>
              </tr>
            );
          })}
        </tbody>
      </table>
    </div>
  );
}

// sending-inbox / domain selector
function InboxSelect({ value, onChange }) {
  const [open, setOpen] = React.useState(false);
  const outbound = window.WTC.inboxes.filter((i) => i.purpose === "outbound");
  const cur = value === "all" ? null : window.WTC.inboxes.find((i) => i.id === value);
  const st = cur ? (window.INBOX_STATUS && window.INBOX_STATUS[cur.status]) : null;
  return (
    <div className="account-bar">
      <button className="account-btn" onClick={() => setOpen((o) => !o)}>
        <Icon name="mail" size={15} style={{ color: "var(--text-2)" }} />
        <span style={{ flex: 1, textAlign: "left", whiteSpace: "nowrap", overflow: "hidden", textOverflow: "ellipsis" }}>
          {cur ? cur.email : "All inboxes"}
        </span>
        {cur && <span className="stagedot" style={{ background: st ? st.color : "var(--green)" }}></span>}
        <Icon name="chevronDown" size={14} style={{ color: "var(--text-3)", transform: open ? "rotate(180deg)" : "none", transition: "transform var(--t)" }} />
      </button>
      {open && (
        <div className="menu-pop" style={{ top: 42, left: 0, right: 0, minWidth: 0 }}>
          <button className="menu-item" onClick={() => { onChange("all"); setOpen(false); }}>
            <Icon name="inbox" size={14} /> All inboxes
            <span style={{ flex: 1 }}></span>
            {value === "all" && <Icon name="check" size={14} style={{ color: "var(--accent)" }} />}
          </button>
          <div className="menu-label">Outbound domains</div>
          {outbound.map((i) => {
            const m = window.WTC.inboxes && { healthy: "var(--green)", warming: "var(--amber)", attention: "var(--red)" }[i.status];
            return (
              <button key={i.id} className="menu-item" onClick={() => { onChange(i.id); setOpen(false); }}>
                <span className="stagedot" style={{ background: m }}></span>
                <span style={{ minWidth: 0, overflow: "hidden", textOverflow: "ellipsis", whiteSpace: "nowrap" }}>{i.email}</span>
                <span style={{ flex: 1 }}></span>
                {value === i.id && <Icon name="check" size={14} style={{ color: "var(--accent)" }} />}
              </button>
            );
          })}
        </div>
      )}
    </div>
  );
}

// ---------- Inbox surface ----------
function Inbox({ threads, lane, triage, setTriage, layout, selId, setSelId, onTriage, onSnooze, onStar, targetById, search, setSearch, inboxFilter, setInboxFilter, onOpenTarget }) {
  const sel = threads.find((t) => t.id === selId) || threads[0];
  const counts = {};
  TRIAGE_TABS.forEach((t) => {
    counts[t.id] = window.WTC.threads.filter((th) =>
      (lane === "all" || th.lane === lane) &&
      (inboxFilter === "all" || th.inboxId === inboxFilter) &&
      (t.id === "drafts" ? th.hasDraft : th.triage === t.id)
    ).length;
  });

  const list = (
    <div className="inbox-list">
      <div className="inbox-list-head">
        <div className="search-mini">
          <Icon name="search" size={15} style={{ color: "var(--text-3)" }} />
          <input placeholder="Search conversations…" value={search} onChange={(e) => setSearch(e.target.value)} />
        </div>
        <button className="btn btn--ghost btn--icon btn--sm" title="Refresh"><Icon name="refresh" size={15} /></button>
      </div>
      <div className="inbox-rows">
        {threads.length === 0 ? (
          <EmptyState icon="inbox" title="Inbox zero" sub="No conversations in this view. Pick another folder or triage tab." />
        ) : threads.map((th) => (
          <ThreadRow key={th.id} th={th} active={sel && th.id === sel.id}
            dense={layout === "split"}
            onClick={() => setSelId(th.id)} onTriage={onTriage} onStar={onStar} />
        ))}
      </div>
    </div>
  );

  if (layout === "table") {
    return (
      <div className="inbox-table-layout">
        <InboxSelect value={inboxFilter} onChange={setInboxFilter} />
        <TriageBar tabs={TRIAGE_TABS} counts={counts} active={triage} onChange={setTriage} search={search} setSearch={setSearch} />
        {threads.length === 0
          ? <EmptyState icon="inbox" title="Nothing here yet" sub="No conversations match this folder + triage." />
          : <ThreadTable threads={threads} onOpen={(id) => { setSelId(id); }} />}
        {sel && <ReadingDrawer th={sel} target={targetById(sel.targetId)} onClose={() => setSelId(null)} onTriage={onTriage} onSnooze={onSnooze} />}
      </div>
    );
  }

  // unibox (with triage rail) | split
  return (
    <div className="inbox-2col" data-layout={layout}>
      <div className="inbox-left">
        <InboxSelect value={inboxFilter} onChange={setInboxFilter} />
        {layout === "unibox" && <TriageBar tabs={TRIAGE_TABS} counts={counts} active={triage} onChange={setTriage} vertical />}
        {layout === "split" && <TriageBar tabs={TRIAGE_TABS} counts={counts} active={triage} onChange={setTriage} />}
        {list}
      </div>
      <div className="inbox-right">
        {sel ? <ReadingPane th={sel} target={targetById(sel.targetId)} onTriage={onTriage} onSnooze={onSnooze} big={layout === "unibox"} onOpenTarget={onOpenTarget} />
             : <EmptyState icon="mail" title="Select a conversation" sub="Replies land here and get triaged into Interested, Not now, or Pass." />}
      </div>
    </div>
  );
}

// triage tab bar — horizontal or vertical rail
function TriageBar({ tabs, counts, active, onChange, vertical, search, setSearch }) {
  return (
    <div className={vertical ? "triage-rail" : "triage-bar"}>
      {tabs.map((t) => (
        <button key={t.id} className="triage-tab" data-active={active === t.id || undefined} onClick={() => onChange(t.id)}>
          <Icon name={t.icon} size={15} />
          <span style={{ flex: 1, textAlign: "left" }}>{t.label}</span>
          <span className="num triage-count">{counts[t.id]}</span>
        </button>
      ))}
    </div>
  );
}

function EmptyState({ icon, title, sub }) {
  return (
    <div className="empty-state">
      <div className="empty-ico"><Icon name={icon} size={26} style={{ color: "var(--text-3)" }} /></div>
      <div style={{ fontSize: 15, fontWeight: 650, color: "var(--text)" }}>{title}</div>
      <div style={{ fontSize: 13, color: "var(--text-3)", maxWidth: 280, textAlign: "center" }}>{sub}</div>
    </div>
  );
}

// reading pane as a right drawer (table layout)
function ReadingDrawer({ th, target, onClose, onTriage, onSnooze }) {
  return (
    <div className="drawer-scrim" onClick={onClose}>
      <div className="drawer" onClick={(e) => e.stopPropagation()}>
        <button className="btn btn--ghost btn--icon drawer-x" onClick={onClose}><Icon name="x" size={18} /></button>
        <ReadingPane th={th} target={target} onTriage={(id, t) => { onTriage(id, t); }} onSnooze={onSnooze} />
      </div>
    </div>
  );
}

Object.assign(window, { Inbox, EmptyState, TriageBar, BookingModal });
