// mailroom-replies.jsx — Replies triage queue (the daily driver). One decision
// per card: Approve & Send / Redraft / Skip. Thread expand + keyboard triage
// (J/K move · Enter approve · S skip · R redraft). Exports: ViewReplies.

const REPLIES = [
  { id: 1, cat: "BOOKING", conf: 96, name: "Priya Anand", company: "LedgerLoop", email: "priya@ledgerloop.com",
    campaign: "RevOps leaders · NA", time: "9:10a",
    inbound: "Booked 15 min for Friday — looking forward to it. Send the calendar invite to this address?",
    draft: "Hi Priya — done, invite's on its way for Friday 11:00a ET. I'll keep it to 15 and come with two concrete ideas for LedgerLoop's outbound. Talk soon!" },
  { id: 2, cat: "POSITIVE", conf: 92, name: "Dana Whitfield", company: "Northwind SaaS", email: "dana@northwind.io",
    campaign: "Q3 · Series-A SaaS founders", time: "9:42a",
    inbound: "This is timely — we're ripping out our $400/mo stack right now. Can you do Thursday afternoon?",
    draft: "Hi Dana — perfect timing. Thursday works; does 2:00p or 3:30p ET suit you better? I'll show exactly how we land in primary without the $400 stack. Here's my link to grab whichever: " },
  { id: 3, cat: "OBJECTION", conf: 81, name: "Aisha Khan", company: "Brightpath", email: "aisha@brightpath.io",
    campaign: "Q3 · Series-A SaaS founders", time: "Yest 4:20p",
    inbound: "Interesting, but we already use Apollo. What would you do differently — and what's pricing for a 12-seat team?",
    draft: "Hi Aisha — totally fair, Apollo's great for data. We're the opposite end: deliverability infra so your sends actually land. For 12 seats it's $X/mo flat, no per-lead fees. Worth a 15-min look at the inbox-placement difference?" },
  { id: 4, cat: "NEGATIVE", conf: 88, name: "Marcus Lee", company: "Flowstate", email: "marcus@flowstate.app",
    campaign: "Q3 · Series-A SaaS founders", time: "Yest 1:05p",
    inbound: "Not interested, please don't email me again.",
    draft: "Understood, Marcus — I've removed you and you won't hear from us again. All the best with Flowstate." },
  { id: 5, cat: "UNSUBSCRIBE", conf: 99, name: "Sofia Reyes", company: "Cohort", email: "sofia@cohort.cc",
    campaign: "Agency owners · warm reactivation", time: "Yest 11:40a",
    inbound: "unsubscribe", draft: null },
  { id: 6, cat: "NOISE", conf: 74, name: "Tom Becker", company: "Parcelhub", email: "tom@parcelhub.com",
    campaign: "RevOps leaders · NA", time: "Mon 8:55a",
    inbound: "I'm OOO until June 14 with limited access to email. For urgent matters contact ops@parcelhub.com.",
    draft: null },
];
const CATS = {
  POSITIVE:    { emoji: "🔥", tone: "good", hot: true },
  BOOKING:     { emoji: "🔥📅", tone: "accent", hot: true },
  OBJECTION:   { emoji: "⚠️", tone: "warn", hot: false },
  NEGATIVE:    { emoji: "", tone: "bad", hot: false },
  UNSUBSCRIBE: { emoji: "", tone: "neutral", hot: false },
  NOISE:       { emoji: "", tone: "neutral", hot: false },
};
const FILTERS = ["all", "POSITIVE", "BOOKING", "OBJECTION", "NEGATIVE", "UNSUBSCRIBE", "NOISE"];

// synth prior thread (what we sent before they replied)
function priorThread(r) {
  const first = r.name.split(" ")[0];
  return [
    { side: "out", label: "Step 1 · opener", time: "Jun 9", body: `Hi ${first}, saw ${r.company} is scaling the GTM team — usually the moment deliverability starts quietly eating reply rate. We run cold-email infra so sends land in primary. Worth a look?` },
    { side: "out", label: "Step 2 · bump", time: "Jun 12", body: `Following up, ${first} — happy to send a 2-min teardown of where ${r.company}'s domains sit today (spam vs primary). No pitch, just data.` },
  ];
}

function ViewReplies({ bookingLinkSet = false }) {
  const t = useT();
  const [filter, setFilter] = React.useState("all");
  const [done, setDone] = React.useState({});
  const [activeId, setActiveId] = React.useState(REPLIES[0].id);
  const [redraftId, setRedraftId] = React.useState(null);
  const list = REPLIES.filter((r) => (filter === "all" || r.cat === filter) && !done[r.id]);
  const remaining = REPLIES.filter((r) => !done[r.id]).length;

  // keep active within current list
  React.useEffect(() => {
    if (!list.find((r) => r.id === activeId)) setActiveId(list[0] ? list[0].id : null);
  }, [list, activeId]);

  const advance = (fromId) => {
    const idx = list.findIndex((r) => r.id === fromId);
    const next = list[idx + 1] || list[idx - 1];
    setActiveId(next ? next.id : null);
  };
  const approve = (r) => { mrToast(`Reply sent to ${r.name}`, { tone: "good", icon: "send" }); advance(r.id); setDone((d) => ({ ...d, [r.id]: true })); };
  const skip = (r) => { mrToast("Skipped — stays in queue", { icon: "clock" }); advance(r.id); setDone((d) => ({ ...d, [r.id]: true })); };
  const ack = (r, msg, tone, icon) => { mrToast(msg, { tone, icon }); advance(r.id); setDone((d) => ({ ...d, [r.id]: true })); };
  const redraft = (r) => { setRedraftId(r.id); setTimeout(() => { setRedraftId(null); mrToast("Draft rewritten by AI", { icon: "sparkle" }); }, 850); };

  // keyboard triage
  React.useEffect(() => {
    const onKey = (e) => {
      if (/input|textarea/i.test(e.target.tagName)) return;
      const idx = list.findIndex((r) => r.id === activeId);
      const cur = list[idx];
      if (e.key === "j" || e.key === "ArrowDown") { e.preventDefault(); setActiveId((list[idx + 1] || list[idx] || {}).id); }
      else if (e.key === "k" || e.key === "ArrowUp") { e.preventDefault(); setActiveId((list[idx - 1] || list[idx] || {}).id); }
      else if (e.key === "Enter" && cur && cur.draft !== null) { e.preventDefault(); approve(cur); }
      else if ((e.key === "s" || e.key === "Backspace") && cur) { e.preventDefault(); cur.draft !== null ? skip(cur) : ack(cur, "Acknowledged", undefined, "check"); }
      else if (e.key === "r" && cur && cur.draft !== null) { e.preventDefault(); redraft(cur); }
    };
    window.addEventListener("keydown", onKey);
    return () => window.removeEventListener("keydown", onKey);
  }, [list, activeId]);

  return (
    <>
      <PageHeader title="Replies" sub={`${remaining} need a decision · today`}>
        <Btn kind="soft" icon="refresh" onClick={() => mrToast("Synced from Smartlead — no new replies", { icon: "refresh" })}>Sync</Btn>
        <Btn kind="soft" icon="filter" onClick={() => mrToast("Sorted by confidence", { icon: "filter" })}>Sort: confidence</Btn>
      </PageHeader>

      {/* filter chips + kbd hint */}
      <div style={{ display: "flex", alignItems: "center", gap: 7, padding: `10px ${t.pad}px`, borderBottom: `1px solid ${t.border}`,
        flex: "0 0 auto", overflowX: "auto", background: t.bg }}>
        {FILTERS.map((f) => {
          const on = filter === f;
          const n = f === "all" ? remaining : REPLIES.filter((r) => r.cat === f && !done[r.id]).length;
          const c = f === "all" ? null : CATS[f];
          return (
            <button key={f} onClick={() => setFilter(f)} style={{
              display: "flex", alignItems: "center", gap: 6, padding: "0 12px", height: 32, borderRadius: 999,
              border: `1px solid ${on ? t.accentBorder : t.border}`, background: on ? t.accentTint : t.card,
              color: on ? t.accentText : t.textSec, cursor: "pointer", fontFamily: t.font, fontSize: 12.5,
              fontWeight: on ? 650 : 500, whiteSpace: "nowrap", flex: "0 0 auto" }}>
              {c && c.emoji && <span style={{ fontSize: 12 }}>{c.emoji}</span>}
              {f === "all" ? "Today" : f.charAt(0) + f.slice(1).toLowerCase()}
              <span style={{ fontFamily: t.mono, fontSize: 11, opacity: 0.75 }}>{n}</span>
            </button>
          );
        })}
        <div style={{ flex: 1 }} />
        <div style={{ display: "flex", alignItems: "center", gap: 6, flex: "0 0 auto", color: t.textMuted, fontSize: 11 }}>
          {[["J K", "move"], ["↵", "send"], ["S", "skip"], ["R", "redraft"]].map(([k, l]) => (
            <span key={k} style={{ display: "inline-flex", alignItems: "center", gap: 4 }}>
              <kbd style={{ fontFamily: t.mono, fontSize: 10.5, fontWeight: 700, color: t.textSec, background: t.card,
                border: `1px solid ${t.borderStrong}`, borderRadius: 4, padding: "1px 5px" }}>{k}</kbd>{l}
            </span>
          ))}
        </div>
      </div>

      {/* triage queue */}
      <div style={{ flex: 1, overflowY: "auto", padding: t.pad, background: t.sunken }}>
        <div style={{ maxWidth: 720, margin: "0 auto", display: "flex", flexDirection: "column", gap: t.gap }}>
          {list.length === 0 && (
            <div style={{ textAlign: "center", padding: "60px 20px", color: t.textMuted }}>
              <Icon name="checkCircle" size={32} color={t.good} style={{ margin: "0 auto 14px" }} />
              <div style={{ fontFamily: t.head, fontSize: 18, fontWeight: 700, color: t.text }}>{filter === "all" ? "Queue clear" : "Nothing in this filter"}</div>
              <div style={{ fontSize: 13.5, marginTop: 6 }}>{filter === "all" ? "Every reply has been handled. Nice." : "No replies match this category right now."}</div>
              {filter !== "all" && <Btn kind="soft" style={{ marginTop: 16 }} onClick={() => setFilter("all")}>Back to all</Btn>}
            </div>
          )}
          {list.map((r) => (
            <ReplyCard key={r.id} r={r} bookingLinkSet={bookingLinkSet} active={r.id === activeId} redrafting={redraftId === r.id}
              onFocus={() => setActiveId(r.id)} onApprove={() => approve(r)} onSkip={() => skip(r)}
              onAck={(msg, tone, icon) => ack(r, msg, tone, icon)} onRedraft={() => redraft(r)} />
          ))}
        </div>
      </div>
    </>
  );
}

function ReplyCard({ r, bookingLinkSet, active, redrafting, onFocus, onApprove, onSkip, onAck, onRedraft }) {
  const t = useT();
  const c = CATS[r.cat];
  const [draft, setDraft] = React.useState(r.draft || "");
  const [thread, setThread] = React.useState(false);
  const warnBooking = (r.cat === "POSITIVE" || r.cat === "BOOKING") && !bookingLinkSet;
  const insertLink = () => {
    if (bookingLinkSet) { setDraft((d) => d.trimEnd() + " cal.com/mohit/15min"); mrToast("Booking link inserted", { tone: "good", icon: "calendar" }); }
    else mrToast("No booking link — add one in Settings", { tone: "warn", icon: "alert" });
  };

  return (
    <div onMouseDown={onFocus} style={{ background: t.card, borderRadius: t.radiusLg, overflow: "hidden", boxShadow: t.shadow,
      border: `1px solid ${active ? t.accent : c.hot ? t.accentBorder : t.border}`,
      outline: active ? `2px solid ${t.accentTint}` : "none", transition: "border-color .12s, outline-color .12s" }}>
      {/* header */}
      <div style={{ display: "flex", alignItems: "center", gap: 10, padding: "13px 16px", borderBottom: `1px solid ${t.border}` }}>
        <Chip tone={c.tone} style={{ fontFamily: t.mono, fontSize: 11, padding: "3px 8px", flex: "0 0 auto" }}>
          {c.emoji && <span>{c.emoji}</span>} {r.cat}
        </Chip>
        <div style={{ minWidth: 0, flex: 1 }}>
          <div style={{ display: "flex", alignItems: "baseline", gap: 8, minWidth: 0 }}>
            <span style={{ fontSize: 14, fontWeight: 650, color: t.text, whiteSpace: "nowrap", flex: "0 0 auto" }}>{r.name}</span>
            <span style={{ fontSize: 12.5, color: t.textMuted, overflow: "hidden", textOverflow: "ellipsis", whiteSpace: "nowrap" }}>{r.company}</span>
          </div>
          <Mono style={{ fontSize: 11.5, color: t.textMuted, display: "block", overflow: "hidden", textOverflow: "ellipsis", whiteSpace: "nowrap" }}>{r.email}</Mono>
        </div>
        <div style={{ textAlign: "right", flex: "0 0 auto" }}>
          <div style={{ display: "flex", alignItems: "center", gap: 5, justifyContent: "flex-end" }}>
            <span style={{ fontSize: 10.5, color: t.textMuted }}>confidence</span>
            <Mono style={{ fontSize: 12.5, fontWeight: 700, color: r.conf >= 90 ? t.good : r.conf >= 78 ? t.warn : t.textSec }}>{r.conf}%</Mono>
          </div>
          <Mono style={{ fontSize: 11, color: t.textMuted }}>{r.time}</Mono>
        </div>
      </div>

      <div style={{ padding: 16 }}>
        {/* thread toggle */}
        <button onClick={() => setThread(!thread)} style={{ display: "flex", alignItems: "center", gap: 6, border: "none", background: "transparent",
          cursor: "pointer", color: t.textMuted, fontSize: 11.5, fontFamily: t.font, fontWeight: 600, padding: 0, marginBottom: 10 }}>
          <Icon name={thread ? "chevD" : "chevR"} size={13} color={t.textMuted} />
          {thread ? "Hide thread" : "Show thread"} <span style={{ fontFamily: t.mono, opacity: 0.7 }}>· 2 prior</span>
        </button>

        {thread && (
          <div style={{ display: "flex", flexDirection: "column", gap: 8, marginBottom: 12, paddingLeft: 12, borderLeft: `2px solid ${t.border}` }}>
            {priorThread(r).map((m, i) => (
              <div key={i} style={{ padding: "10px 12px", borderRadius: t.radiusSm, background: t.card, border: `1px solid ${t.border}` }}>
                <div style={{ display: "flex", alignItems: "center", gap: 7, marginBottom: 5 }}>
                  <Chip tone="accent" style={{ fontSize: 10 }}>you</Chip>
                  <span style={{ fontSize: 11, color: t.textMuted }}>{m.label}</span>
                  <Mono style={{ fontSize: 10.5, color: t.textMuted, marginLeft: "auto" }}>{m.time}</Mono>
                </div>
                <div style={{ fontSize: 12, color: t.textSec, lineHeight: 1.5 }}>{m.body}</div>
              </div>
            ))}
          </div>
        )}

        {/* quoted inbound */}
        <div style={{ display: "flex", gap: 10, padding: "12px 14px", borderRadius: t.radiusSm, background: t.sunken,
          border: `1px solid ${t.border}`, borderLeft: `3px solid ${t.borderStrong}` }}>
          <Icon name="replies" size={15} color={t.textMuted} style={{ marginTop: 1, flex: "0 0 auto" }} />
          <div style={{ minWidth: 0 }}>
            <div style={{ fontSize: 11, color: t.textMuted, marginBottom: 3 }}><b style={{ color: t.textSec }}>{r.name}</b> replied · {r.time}</div>
            <div style={{ fontSize: 13, color: t.textSec, lineHeight: 1.55 }}>{r.inbound}</div>
          </div>
        </div>

        {/* booking warning */}
        {warnBooking && (
          <div style={{ display: "flex", alignItems: "center", gap: 8, marginTop: 12, padding: "9px 12px", borderRadius: t.radiusSm,
            background: t.markerTint, border: `1px solid ${t.markerBorder}` }}>
            <Icon name="alert" size={15} color={t.markerInk} />
            <span style={{ fontSize: 12.5, color: t.markerInk, fontWeight: 600 }}>No booking link configured</span>
            <span style={{ fontSize: 12.5, color: t.textSec }}>— add one in Settings so the draft can include it.</span>
          </div>
        )}

        {/* AI draft */}
        {r.draft !== null ? (
          <div style={{ marginTop: 14 }}>
            <div style={{ display: "flex", alignItems: "center", gap: 7, marginBottom: 8 }}>
              <Icon name="sparkle" size={14} color={t.accent} />
              <Label style={{ color: t.accentText }}>AI draft reply</Label>
              <span style={{ fontSize: 11, color: t.textMuted, fontFamily: t.mono }}>· editable · via OpenRouter</span>
            </div>
            <div style={{ position: "relative", border: `1px solid ${t.borderStrong}`, borderRadius: t.radiusSm, background: t.raise }}>
              <textarea value={redrafting ? "" : draft} onChange={(e) => setDraft(e.target.value)} rows={4}
                placeholder={redrafting ? "" : "Write a reply…"}
                style={{ width: "100%", border: "none", outline: "none", resize: "vertical", background: "transparent",
                  padding: "11px 13px", font: "inherit", fontSize: 13.5, color: t.text, lineHeight: 1.6, display: "block" }} />
              {redrafting && (
                <div style={{ position: "absolute", inset: 0, display: "flex", alignItems: "center", gap: 8,
                  padding: "0 14px", color: t.accent, fontSize: 13 }}>
                  <Icon name="sparkle" size={15} color={t.accent} style={{ animation: "mrPulse 1s ease-in-out infinite" }} />
                  rewriting draft…
                </div>
              )}
            </div>
          </div>
        ) : (
          <div style={{ display: "flex", alignItems: "center", gap: 9, marginTop: 14, padding: "11px 14px", borderRadius: t.radiusSm,
            background: t.sunken, border: `1px dashed ${t.borderStrong}` }}>
            <Icon name={r.cat === "UNSUBSCRIBE" ? "ban" : "clock"} size={15} color={t.textMuted} />
            <span style={{ fontSize: 12.5, color: t.textSec }}>
              {r.cat === "UNSUBSCRIBE"
                ? "Auto-suppressed — no reply needed. Added to suppression list."
                : "Out-of-office — sequence auto-paused for this lead until June 14. No reply needed."}
            </span>
          </div>
        )}

        {/* actions */}
        <div style={{ display: "flex", alignItems: "center", gap: 9, marginTop: 16 }}>
          {r.draft !== null ? (
            <>
              <Btn kind="primary" iconR="send" onClick={onApprove}>Approve & Send</Btn>
              <Btn kind="soft" icon="sparkle" onClick={onRedraft}>Redraft</Btn>
              <Btn kind="soft" icon="calendar" onClick={insertLink}>Insert link</Btn>
              <div style={{ flex: 1 }} />
              <Btn kind="ghost" onClick={onSkip}>Skip</Btn>
            </>
          ) : (
            <>
              <Btn kind="soft" icon="check" onClick={() => onAck("Acknowledged", undefined, "check")}>Acknowledge</Btn>
              {r.cat === "UNSUBSCRIBE" && <Btn kind="danger" icon="ban" onClick={() => onAck("Added to suppression", "warn", "ban")}>Confirm suppress</Btn>}
              <div style={{ flex: 1 }} />
              <span style={{ fontSize: 11.5, color: t.textMuted, display: "flex", alignItems: "center", gap: 6 }}>
                <Icon name="campaigns" size={12} color={t.textMuted} /> {r.campaign}
              </span>
            </>
          )}
        </div>
      </div>
    </div>
  );
}
window.ViewReplies = ViewReplies;
