/* ============================================================
   Today — the front door. Pulse KPIs + ranked outreach queue.
   ============================================================ */

const PRIORITY_META = {
  replied: { label: "Replied", color: "var(--green)", icon: "reply" },
  overdue: { label: "Overdue", color: "var(--red)", icon: "clock" },
  due:     { label: "Due today", color: "var(--accent)", icon: "flag" },
  cold:    { label: "Going cold", color: "var(--amber)", icon: "flame" },
  new:     { label: "New", color: "var(--text-2)", icon: "plus" },
};

function Sparkline({ data, w = 132, h = 36, color = "var(--accent)" }) {
  const max = Math.max(...data), min = Math.min(...data);
  const range = max - min || 1;
  const pts = data.map((v, i) => [(i / (data.length - 1)) * w, h - 4 - ((v - min) / range) * (h - 10)]);
  const d = pts.map((p, i) => (i === 0 ? "M" : "L") + p[0].toFixed(1) + " " + p[1].toFixed(1)).join(" ");
  const area = d + ` L${w} ${h} L0 ${h} Z`;
  const gid = "spk" + Math.round(w + h + data[0]);
  return (
    <svg width={w} height={h} style={{ display: "block" }}>
      <defs><linearGradient id={gid} x1="0" y1="0" x2="0" y2="1">
        <stop offset="0" stopColor={color} stopOpacity="0.22" /><stop offset="1" stopColor={color} stopOpacity="0" />
      </linearGradient></defs>
      <path d={area} fill={`url(#${gid})`} />
      <path d={d} fill="none" stroke={color} strokeWidth="1.8" strokeLinejoin="round" strokeLinecap="round" />
      <circle cx={pts[pts.length - 1][0]} cy={pts[pts.length - 1][1]} r="2.6" fill={color} />
    </svg>
  );
}

function KpiCard({ label, value, unit, delta, deltaDir, sub, children, accent }) {
  return (
    <div className="kpi-card lift">
      <div style={{ display: "flex", alignItems: "center", justifyContent: "space-between" }}>
        <span style={{ fontSize: 11.5, fontWeight: 600, letterSpacing: "0.04em", textTransform: "uppercase", color: "var(--text-3)" }}>{label}</span>
        {delta != null && (
          <span className={"delta delta--" + (deltaDir || "up")}>
            <Icon name={deltaDir === "down" ? "chevronDown" : "trend"} size={11} />{delta}
          </span>
        )}
      </div>
      <div style={{ display: "flex", alignItems: "baseline", gap: 5, marginTop: 8 }}>
        <span className="num" style={{ fontSize: 34, fontWeight: 700, letterSpacing: "-0.03em", color: accent || "var(--text)" }}>{value}</span>
        {unit && <span style={{ fontSize: 13, color: "var(--text-3)" }}>{unit}</span>}
      </div>
      {sub && <div style={{ fontSize: 12, color: "var(--text-3)", marginTop: 4 }}>{sub}</div>}
      {children}
    </div>
  );
}

function PipelineSnapshot({ pipeline }) {
  const total = pipeline.reduce((s, p) => s + p.count, 0) || 1;
  return (
    <div className="kpi-card" style={{ gridColumn: "span 2" }}>
      <span style={{ fontSize: 11.5, fontWeight: 600, letterSpacing: "0.04em", textTransform: "uppercase", color: "var(--text-3)" }}>Pipeline by stage</span>
      <div style={{ display: "flex", height: 9, borderRadius: 999, overflow: "hidden", marginTop: 14, gap: 2 }}>
        {pipeline.map((p) => p.count > 0 && (
          <div key={p.stage} title={`${p.label}: ${p.count}`}
            style={{ flex: p.count, background: window.WTC.STAGE_META[p.stage].color, opacity: 0.85 }}></div>
        ))}
      </div>
      <div style={{ display: "flex", flexWrap: "wrap", gap: "8px 14px", marginTop: 14 }}>
        {pipeline.map((p) => (
          <span key={p.stage} style={{ display: "inline-flex", alignItems: "center", gap: 6, fontSize: 12, color: "var(--text-2)" }}>
            <span className="stagedot" style={{ background: window.WTC.STAGE_META[p.stage].color }}></span>
            {p.label} <b className="num" style={{ color: "var(--text)", fontWeight: 600 }}>{p.count}</b>
          </span>
        ))}
      </div>
    </div>
  );
}

function QueueRow({ t, onApprove, onDecline, onLog, logged }) {
  const pm = PRIORITY_META[t.priority];
  const contact = t.contacts[0];
  return (
    <div className="queue-row lift">
      <div className="qr-rank" style={{ background: pm.color + "1f", color: pm.color }}>
        <Icon name={pm.icon} size={16} />
      </div>
      <Avatar mono={t.mono} size={40} square />
      <div style={{ minWidth: 0, flex: 1 }}>
        <div style={{ display: "flex", alignItems: "center", gap: 9, marginBottom: 3 }}>
          <span style={{ fontSize: 14.5, fontWeight: 670, whiteSpace: "nowrap" }}>{t.brand}</span>
          <LaneChip lane={t.lane} small />
          <span style={{ fontSize: 11.5, fontWeight: 650, color: pm.color }}>{pm.label}</span>
        </div>
        <div style={{ fontSize: 13, color: "var(--text-2)", whiteSpace: "nowrap", overflow: "hidden", textOverflow: "ellipsis" }}>
          {t.whyNow}
        </div>
      </div>
      <div className="qr-contact">
        <div style={{ display: "flex", alignItems: "center", gap: 8 }}>
          <Avatar name={contact.name} initials={contact.initials} color={contact.color} size={26} />
          <div style={{ minWidth: 0 }}>
            <div style={{ fontSize: 12.5, fontWeight: 600, whiteSpace: "nowrap" }}>{contact.name}</div>
            <div style={{ fontSize: 11, color: "var(--text-3)", whiteSpace: "nowrap" }}>{contact.title}</div>
          </div>
        </div>
      </div>
      <div className="qr-actions">
        {logged ? (
          <span style={{ fontSize: 12, color: "var(--green)", display: "inline-flex", alignItems: "center", gap: 5 }}>
            <Icon name="check" size={14} /> Logged
          </span>
        ) : (
          <React.Fragment>
            <button className="btn btn--ghost btn--icon btn--sm" title="Log touch" onClick={() => onLog(t.id)}><Icon name="checkDouble" size={15} /></button>
            <button className="btn btn--sm" onClick={() => onDecline(t.id)}>Not today</button>
            <button className="btn btn--primary btn--sm" onClick={() => onApprove(t)}><Icon name="sparkles" size={14} /> Approve</button>
          </React.Fragment>
        )}
      </div>
    </div>
  );
}

function RecentWinsCard() {
  const wins = window.WTC.kpis.wins;
  const [i, setI] = React.useState(0);
  const [paused, setPaused] = React.useState(false);
  React.useEffect(() => {
    if (paused) return;
    const id = setInterval(() => setI((x) => (x + 1) % wins.length), 3600);
    return () => clearInterval(id);
  }, [paused, wins.length]);
  const w = wins[i];
  return (
    <div className="kpi-card win-rotator" onMouseEnter={() => setPaused(true)} onMouseLeave={() => setPaused(false)}>
      <div style={{ display: "flex", alignItems: "center", justifyContent: "space-between" }}>
        <span style={{ fontSize: 11.5, fontWeight: 600, letterSpacing: "0.04em", textTransform: "uppercase", color: "var(--text-3)" }}>Recent wins</span>
        <span className="delta delta--up"><Icon name="trend" size={11} /> {wins.length}</span>
      </div>
      <div key={i} className="win-rotate-body">
        <div style={{ display: "flex", alignItems: "center", gap: 10 }}>
          <Avatar mono={w.mono} size={32} square />
          <div style={{ minWidth: 0 }}>
            <div style={{ fontSize: 15, fontWeight: 680, whiteSpace: "nowrap" }}>{w.brand}</div>
            <div style={{ fontSize: 11.5, color: "var(--text-3)", whiteSpace: "nowrap", overflow: "hidden", textOverflow: "ellipsis" }}>{w.when}</div>
          </div>
          <span className="num" style={{ marginLeft: "auto", fontSize: 18, fontWeight: 700, color: "var(--green)" }}>{fmtMoney(w.value)}</span>
        </div>
        <div style={{ fontSize: 12, color: "var(--text-2)", marginTop: 8, lineHeight: 1.45 }}>{w.note}</div>
      </div>
      <div className="win-dots">
        {wins.map((_, k) => (
          <button key={k} className="win-dot" data-active={k === i || undefined} onClick={() => setI(k)} aria-label={"Win " + (k + 1)}></button>
        ))}
      </div>
    </div>
  );
}

function Today({ lane, onApprove, timeframe, setTimeframe }) {
  const K = window.WTC.kpis;
  const [declined, setDeclined] = React.useState({});
  const [logged, setLogged] = React.useState({});
  const [approved, setApproved] = React.useState({});
  const [qView, setQView] = React.useState("Queue");
  const [running, setRunning] = React.useState(false);
  const queue = window.WTC.todayQueue.filter((t) => (lane === "all" || t.lane === lane) && !declined[t.id]);
  const baseTotal = window.WTC.todayQueue.filter((t) => lane === "all" || t.lane === lane).length;
  const clearedIds = new Set([...Object.keys(approved), ...Object.keys(logged), ...Object.keys(declined)]);
  const cleared = clearedIds.size;
  const approve = (t) => { setApproved((a) => ({ ...a, [t.id]: 1 })); onApprove(t); };
  const logTouch = (id) => setLogged((l) => ({ ...l, [id]: true }));
  const decline = (id) => setDeclined((d) => ({ ...d, [id]: true }));

  return (
    <div className="surface-scroll">
      <DailyBriefing K={K} total={baseTotal} cleared={cleared} queue={queue} timeframe={timeframe} setTimeframe={setTimeframe} onRun={() => setRunning(true)} />

      {/* pulse */}
      <div className="kpi-grid">
        <KpiCard label="Win rate" value={K.winPct} unit="%" delta={K.winDelta} deltaDir="up" sub="won vs lost, this period" accent="var(--green)" />
        <KpiCard label="Active targets" value={K.active} delta={K.activeDelta} deltaDir="up" sub="in pipeline now" />
        <KpiCard label="Contacted" value={K.contacted} delta={K.contactedDelta} deltaDir="up" sub="in this timeframe" />
        <KpiCard label="Due today" value={K.dueToday} sub="ready to send" accent="var(--accent)">
          <div style={{ marginTop: "auto" }}></div>
        </KpiCard>
        <PipelineSnapshot pipeline={K.pipeline} />
        <KpiCard label="Activity" value={K.spark.reduce((a, b) => a + b, 0)} unit="touches">
          <div style={{ marginTop: 10 }}><Sparkline data={K.spark} w={150} /></div>
        </KpiCard>
        <RecentWinsCard />
      </div>

      {/* plan */}
      <div className="queue-head">
        <h2 style={{ fontSize: 15, fontWeight: 670, margin: 0 }}>{qView === "Queue" ? "Today's plan" : "Pipeline"}</h2>
        <div style={{ display: "flex", alignItems: "center", gap: 12 }}>
          <span style={{ fontSize: 12.5, color: "var(--text-3)" }}>{qView === "Queue" ? "Grouped by what each target needs" : "Drag cards between stages"}</span>
          <Segmented value={qView} onChange={setQView} options={["Queue", "Pipeline"]} />
        </div>
      </div>
      {qView === "Pipeline"
        ? <TodayBoard lane={lane} onApprove={onApprove} />
        : <GroupedQueue queue={queue} onApprove={approve} onDecline={decline} onLog={logTouch} logged={logged} approved={approved} />}

      {running && <RunMode queue={queue} onApprove={approve} onLog={logTouch} onDecline={decline} onClose={() => setRunning(false)} />}
    </div>
  );
}

const PLAN_GROUPS = [
  { id: "replied", label: "Replies to clear", icon: "reply", color: "var(--green)" },
  { id: "overdue", label: "Overdue", icon: "clock", color: "var(--red)" },
  { id: "due", label: "Due today", icon: "flag", color: "var(--accent)" },
  { id: "cold", label: "Going cold", icon: "flame", color: "var(--amber)" },
  { id: "new", label: "New outreach", icon: "plus", color: "var(--text-2)" },
];

function GroupedQueue({ queue, onApprove, onDecline, onLog, logged, approved }) {
  if (queue.length === 0) return <EmptyState icon="check" title="Day cleared" sub="You've worked through every target. Claude will resurface the next touches tomorrow." />;
  return (
    <div className="plan-groups">
      {PLAN_GROUPS.map((g) => {
        const items = queue.filter((t) => t.priority === g.id);
        if (!items.length) return null;
        return (
          <div key={g.id} className="plan-group">
            <div className="plan-group-head"><Icon name={g.icon} size={14} style={{ color: g.color }} /> {g.label} <span className="num plan-group-count">{items.length}</span></div>
            <div className="queue">
              {items.map((t) => (
                <QueueRow key={t.id} t={t} onApprove={onApprove} onDecline={onDecline} onLog={onLog} logged={logged[t.id] || approved[t.id]} />
              ))}
            </div>
          </div>
        );
      })}
    </div>
  );
}

const STREAK = 14;
function DailyBriefing({ K, total, cleared, queue, timeframe, setTimeframe, onRun }) {
  const pct = total ? Math.round((cleared / total) * 100) : 0;
  const R = 26, C = 2 * Math.PI * R;
  const counts = {};
  PLAN_GROUPS.forEach((g) => { counts[g.id] = queue.filter((t) => t.priority === g.id).length; });
  const replies = counts.replied || 0, sends = (counts.new || 0), follow = (counts.due || 0) + (counts.overdue || 0) + (counts.cold || 0);
  return (
    <div className="today-hero">
      <div style={{ minWidth: 0, flex: 1 }}>
        <div style={{ display: "flex", alignItems: "center", gap: 10 }}>
          <h1 className="page-title">Today</h1>
          <span className="streak"><Icon name="flame" size={13} /> <span className="num">{STREAK}</span>-day streak</span>
        </div>
        <p className="hero-plan">{cleared >= total && total > 0 ? "You've cleared today's run — nice work. Claude will line up tomorrow's." : `Claude lined up ${total} moves for you today.`} {replies > 0 && <React.Fragment><b>{replies}</b> repl{replies === 1 ? "y" : "ies"} to clear</React.Fragment>}{replies > 0 && (follow + sends > 0) ? " · " : ""}{follow > 0 && <React.Fragment><b>{follow}</b> follow-up{follow === 1 ? "" : "s"}</React.Fragment>}{follow > 0 && sends > 0 ? " · " : ""}{sends > 0 && <React.Fragment><b>{sends}</b> new to send</React.Fragment>}.</p>
        <div className="plan-pills">
          {PLAN_GROUPS.map((g) => counts[g.id] > 0 && (
            <span key={g.id} className="plan-pill"><span className="stagedot" style={{ background: g.color }}></span>{g.label}<b className="num">{counts[g.id]}</b></span>
          ))}
        </div>
      </div>
      <div className="hero-right">
        <div className="ring-wrap" title={cleared + " of " + total + " cleared"}>
          <svg width="64" height="64" viewBox="0 0 64 64">
            <circle cx="32" cy="32" r={R} fill="none" stroke="rgba(255,255,255,0.09)" strokeWidth="6" />
            <circle cx="32" cy="32" r={R} fill="none" stroke="var(--green)" strokeWidth="6" strokeLinecap="round"
              strokeDasharray={C} strokeDashoffset={C * (1 - pct / 100)} transform="rotate(-90 32 32)" style={{ transition: "stroke-dashoffset 0.5s ease" }} />
          </svg>
          <div className="ring-label"><span className="num">{cleared}</span><span className="ring-sub">/{total}</span></div>
        </div>
        <button className="btn btn--primary" style={{ height: 40 }} onClick={onRun} disabled={queue.length === 0}>
          <Icon name="send" size={16} /> {cleared > 0 ? "Resume run" : "Start today's run"}
        </button>
        <Segmented value={timeframe} onChange={setTimeframe} options={["7 days", "30 days", "Quarter"]} />
      </div>
    </div>
  );
}

// ---- Run the day: guided one-at-a-time focus mode ----
function RunMode({ queue, onApprove, onLog, onDecline, onClose }) {
  const [i, setI] = React.useState(0);
  const total = queue.length;
  const t = queue[i];
  const next = () => setI((x) => x + 1);
  const done = i >= total || !t;
  const pm = t && (window.PRIORITY_META[t.priority] || { label: t.priority, color: "var(--text-2)", icon: "flag" });
  const contact = t && t.contacts[0];
  return (
    <div className="modal-scrim" onClick={onClose}>
      <div className="run-modal" onClick={(e) => e.stopPropagation()}>
        <div className="run-head">
          <span style={{ fontSize: 12.5, fontWeight: 650, color: "var(--text-2)" }}>Today's run</span>
          <div className="run-progress"><div style={{ width: (done ? 100 : (i / total) * 100) + "%" }}></div></div>
          <span className="num" style={{ fontSize: 12, color: "var(--text-3)" }}>{Math.min(i + (done ? 0 : 1), total)} / {total}</span>
          <button className="btn btn--ghost btn--icon btn--sm" onClick={onClose}><Icon name="x" size={16} /></button>
        </div>
        {done ? (
          <div className="run-done">
            <div className="run-done-ring"><Icon name="check" size={30} style={{ color: "var(--green)" }} /></div>
            <div style={{ fontSize: 18, fontWeight: 720 }}>Run complete</div>
            <p style={{ fontSize: 13.5, color: "var(--text-2)", textAlign: "center", maxWidth: 320, lineHeight: 1.5 }}>You cleared today's queue. That's a <b style={{ color: "var(--text)" }}>{STREAK + 1}-day streak</b> — consistency is the whole game.</p>
            <button className="btn btn--primary" onClick={onClose}><Icon name="check" size={15} /> Done</button>
          </div>
        ) : (
          <div className="run-body">
            <div className="run-card">
              <div style={{ display: "flex", alignItems: "center", gap: 10, marginBottom: 14 }}>
                <span className="qr-rank" style={{ background: pm.color + "1f", color: pm.color }}><Icon name={pm.icon} size={16} /></span>
                <Avatar mono={t.mono} size={42} square />
                <div style={{ minWidth: 0, flex: 1 }}>
                  <div style={{ display: "flex", alignItems: "center", gap: 9 }}><span style={{ fontSize: 17, fontWeight: 700 }}>{t.brand}</span><LaneChip lane={t.lane} small /></div>
                  <div style={{ fontSize: 12, color: pm.color, fontWeight: 600, marginTop: 2 }}>{pm.label}</div>
                </div>
              </div>
              <div className="run-why"><span className="run-why-label">Why now</span>{t.whyNow}</div>
              <div className="run-contact">
                <Avatar name={contact.name} initials={contact.initials} color={contact.color} size={28} />
                <div><div style={{ fontSize: 13, fontWeight: 600 }}>{contact.name}</div><div style={{ fontSize: 11.5, color: "var(--text-3)" }}>{contact.title} · {contact.email}</div></div>
                <span className="num" style={{ marginLeft: "auto", fontSize: 11.5, color: "var(--text-3)" }}>{t.cadence.label}</span>
              </div>
            </div>
            <div className="run-actions">
              <button className="btn btn--ghost" onClick={() => { onDecline(t.id); next(); }}>Skip</button>
              <button className="btn" onClick={() => { onLog(t.id); next(); }}><Icon name="checkDouble" size={15} /> Log touch</button>
              <button className="btn btn--primary" onClick={() => { onApprove(t); next(); }}><Icon name="sparkles" size={15} /> Approve & draft</button>
            </div>
          </div>
        )}
      </div>
    </div>
  );
}

function Segmented({ value, onChange, options }) {
  return (
    <div className="segmented">
      {options.map((o) => (
        <button key={o} data-active={value === o || undefined} onClick={() => onChange(o)}>{o}</button>
      ))}
    </div>
  );
}

// ---- Pipeline board (kanban by stage) ----
const BOARD_STAGES = ["new", "contacted", "in_convo", "pitched", "won", "lost"];
function TodayBoard({ lane, onApprove, onOpen }) {
  const SM = window.WTC.STAGE_META;
  const [ov, setOv] = React.useState({});       // targetId -> stage override
  const [drag, setDrag] = React.useState(null);
  const [dragOver, setDragOver] = React.useState(null);
  const stageOf = (t) => ov[t.id] || t.stage;
  const targets = window.WTC.targets.filter((t) => lane === "all" || t.lane === lane);
  const drop = (stage) => { if (drag) setOv((o) => ({ ...o, [drag]: stage })); setDrag(null); setDragOver(null); };
  return (
    <div className="board">
      {BOARD_STAGES.map((stage) => {
        const cards = targets.filter((t) => stageOf(t) === stage);
        return (
          <div key={stage} className={"board-col" + (dragOver === stage ? " is-over" : "")}
            onDragOver={(e) => { e.preventDefault(); setDragOver(stage); }} onDragLeave={() => setDragOver((s) => s === stage ? null : s)} onDrop={() => drop(stage)}>
            <div className="board-col-head">
              <span style={{ display: "inline-flex", alignItems: "center", gap: 7 }}><span className="stagedot" style={{ background: SM[stage].color }}></span>{SM[stage].label}</span>
              <span className="num board-count">{cards.length}</span>
            </div>
            <div className="board-cards">
              {cards.map((t) => {
                const c = t.contacts[0];
                return (
                  <div key={t.id} className="board-card lift" draggable onDragStart={() => setDrag(t.id)} onDragEnd={() => { setDrag(null); setDragOver(null); }}
                    onClick={() => (onOpen ? onOpen(t.id) : onApprove(t))}>
                    <div style={{ display: "flex", alignItems: "center", gap: 8, marginBottom: 7 }}>
                      <Avatar mono={t.mono} size={26} square />
                      <span style={{ fontWeight: 660, fontSize: 13, whiteSpace: "nowrap", overflow: "hidden", textOverflow: "ellipsis" }}>{t.brand}</span>
                      <span style={{ flex: 1 }}></span>
                      <LaneChip lane={t.lane} small />
                    </div>
                    <div style={{ fontSize: 11.5, color: "var(--text-3)", display: "flex", alignItems: "center", gap: 6, marginBottom: t.value ? 7 : 0 }}>
                      <Avatar name={c.name} initials={c.initials} color={c.color} size={16} /> {c.name}
                    </div>
                    {t.value > 0 && <div style={{ display: "flex", alignItems: "center", justifyContent: "space-between" }}>
                      <span className="num" style={{ fontSize: 12.5, fontWeight: 650, color: stage === "won" ? "var(--green)" : "var(--text-2)" }}>{fmtMoney(t.value)}</span>
                      {window.WTC.enrollments[c.id] && <span style={{ fontSize: 10.5, color: "var(--accent)", display: "inline-flex", alignItems: "center", gap: 3 }}><Icon name="sequence" size={11} /> in flow</span>}
                    </div>}
                  </div>
                );
              })}
              {cards.length === 0 && <div className="board-empty">—</div>}
            </div>
          </div>
        );
      })}
    </div>
  );
}

Object.assign(window, { Today, Segmented, Sparkline, PRIORITY_META, TodayBoard, KpiCard, PipelineSnapshot, RecentWinsCard });
