const { useState, useEffect } = React;

/* CRM · Today — real-or-empty. Signals default to the TERRITORY feed
 * (crm_territory_feed, populated out of the box). Capture flows wired:
 *  • + Add task        → crm_create_activity (type=task)
 *  • Watch a building  → crm_building_search → crm_watch_building
 *  • Create deal (sig) → crm_create_deal from the event
 * Stats from crm_dashboard_stats; tasks from crm_today_tasks. */

const CRM_EVT = {
  new_mortgage:  { label: "New mortgage",  style: { background: "var(--green-bg)",  color: "var(--green)" } },
  deed_transfer: { label: "Deed transfer", style: { background: "#47556914",        color: "var(--src-government)" } },
  warn_layoff:   { label: "WARN layoff",   style: { background: "var(--red-bg)",    color: "var(--red)" } },
  form_d_raise:  { label: "Form D raise",  style: { background: "var(--accent-bg)", color: "var(--accent)" } },
  ucc_lien:      { label: "UCC lien",      style: { background: "var(--amber-bg)",  color: "var(--amber)" } },
};
const prettyBBL = (ref) => (ref && ref.indexOf("BBL:") === 0) ? "BBL " + ref.slice(4) : (ref || "");
const fmtMoney = (n) => { n = Number(n) || 0; return n >= 1e6 ? "$" + (n / 1e6).toFixed(1) + "M" : n >= 1e3 ? "$" + Math.round(n / 1e3) + "K" : "$" + n; };
function eventContext(type, p) {
  if (!p || typeof p !== "object") return null;
  if (type === "new_mortgage" || type === "deed_transfer") return p.address ? "📍 " + p.address : null;
  if (type === "ucc_lien") return [p.debtor && "Debtor: " + p.debtor, p.collateral && "Collateral: " + String(p.collateral).slice(0, 80)].filter(Boolean).join("  ·  ") || null;
  if (type === "form_d_raise") return [p.entity, p.amount_sold != null && "sold " + fmtMoney(p.amount_sold)].filter(Boolean).join("  ·  ") || null;
  if (type === "warn_layoff") return [p.employees != null && p.employees + " roles", p.site, p.city].filter(Boolean).join("  ·  ") || null;
  return null;
}
const mapEventCard = (r) => ({
  id: "evt-" + r.event_id, type: r.event_type,
  src: "via " + (r.source || "—") + (r.event_date ? " · as-of " + r.event_date : ""), srcUrl: r.source_url || null,
  a: prettyBBL(r.parcel_ref) || r.counterparty || "—", bbl: r.parcel_ref ? prettyBBL(r.parcel_ref) : (r.state || ""),
  fact: r.title, ctx: eventContext(r.event_type, r.payload), parcel_ref: r.parcel_ref, amount: r.amount,
});

function TodayContent() {
  const { toast, go, persona } = React.useContext(window.CrmContext);
  const Ico = window.CrmIco;
  const [signals, setSignals] = useState([]);
  const [tasks, setTasks] = useState([]);
  const [doneTasks, setDoneTasks] = useState({});
  const [hidden, setHidden] = useState({});
  const [stats, setStats] = useState(null);
  const [loaded, setLoaded] = useState(false);
  const [adding, setAdding] = useState(false);
  const [taskText, setTaskText] = useState("");
  const [watch, setWatch] = useState(null); // null | {q, results, busy}

  const client = () => window.ContactIQ && window.ContactIQ.client;

  const loadTasks = () => {
    const c = client(); if (!c) return;
    c.rpc("crm_today_tasks", {}).then(({ data, error }) => {
      if (error || !data) return;
      const t0 = new Date(); t0.setHours(0, 0, 0, 0);
      setTasks(data.map((t) => {
        let due = ["soon", "Scheduled"];
        if (t.due_at) { const d = new Date(t.due_at), days = Math.round((d - t0) / 864e5);
          due = days < 0 ? ["overdue", "Overdue · " + (-days) + "d"] : days === 0 ? ["today", "Today"] : ["soon", d.toLocaleDateString(undefined, { weekday: "short" })]; }
        return { id: "a" + t.id, title: t.subject || "Task", due, meta: t.body || "", shared: !!t.team_id };
      }));
    }).catch(() => {});
  };
  const loadStats = () => { const c = client(); if (!c) return; c.rpc("crm_dashboard_stats", {}).then(({ data, error }) => { if (!error && data && data[0]) setStats(data[0]); }).catch(() => {}); };

  useEffect(() => {
    const c = client();
    if (!c) { setLoaded(true); return; }
    let alive = true;
    c.rpc("crm_territory_feed", { p_metros: null, p_limit: 12 })
      .then(({ data, error }) => { if (alive && !error && data) setSignals(data.map(mapEventCard)); })
      .catch(() => {}).then(() => { if (alive) setLoaded(true); });
    loadStats(); loadTasks();
    return () => { alive = false; };
  }, []);

  const num = (x) => (stats && x != null ? Number(x).toLocaleString() : "—");
  const createDeal = (e) => {
    const c = client();
    if (c) c.rpc("crm_create_deal", { p_title: e.a + " — " + (CRM_EVT[e.type] ? CRM_EVT[e.type].label : "deal"), p_deal_type: persona === "lender" ? "loan" : "lease", p_parcel_ref: e.parcel_ref, p_value_usd: e.amount || null }).catch(() => {});
    toast("Deal created — opens in your pipeline");
  };
  const dismiss = (id) => { setHidden((h) => ({ ...h, [id]: true })); toast("Signal dismissed"); };
  const toggleTask = (id) => setDoneTasks((d) => ({ ...d, [id]: !d[id] }));

  const addTask = () => {
    const subject = taskText.trim(); if (!subject) { setAdding(false); return; }
    const c = client();
    if (c) c.rpc("crm_create_activity", { p_subject: subject, p_activity_type: "task" }).then(() => { loadTasks(); }).catch(() => {});
    setTaskText(""); setAdding(false); toast("Task added");
  };

  const runSearch = (q) => {
    setWatch((w) => ({ ...w, q, busy: true }));
    const c = client(); if (!c || q.trim().length < 2) { setWatch((w) => ({ ...w, results: [], busy: false })); return; }
    c.rpc("crm_building_search", { p_q: q.trim(), p_limit: 12 }).then(({ data, error }) => {
      setWatch((w) => (w ? { ...w, results: (!error && data) ? data : [], busy: false } : w));
    }).catch(() => setWatch((w) => (w ? { ...w, results: [], busy: false } : w)));
  };
  const doWatch = (r) => {
    const c = client();
    if (c) c.rpc("crm_watch_building", { p_parcel_ref: r.parcel_ref, p_label: r.anchor, p_share: false }).then(() => { loadStats(); }).catch(() => {});
    toast("Watching building — its signals will surface here");
    setWatch(null);
  };
  const doFollowOrg = (r) => {
    const c = client();
    if (c && r.org_id) c.rpc("crm_save_org", { p_org_id: r.org_id, p_share: false }).then(() => { loadStats(); }).catch(() => {});
    toast("Following " + r.anchor + " — its filings & events will surface here");
    setWatch(null);
  };

  const visibleSignals = signals.filter((s) => !hidden[s.id]);

  return (
    <div className="page">
      <div className="page-head">
        <div className="ph-text">
          <div className="eyebrow">Today</div>
          <h1 className="page-title">Today</h1>
          <div className="page-sub">Tasks due and live signals across your territory — <span className="fact">NY · CT · NJ · FL</span></div>
        </div>
        <button className="btn btn-primary btn-lg" onClick={() => setWatch({ q: "", results: [], busy: false })}>
          <svg width="14" height="14" viewBox="0 0 16 16" fill="none" stroke="currentColor" strokeWidth="1.5" strokeLinejoin="round"><path d="M8 2l1.8 3.8 4.2.6-3 3 .7 4.2L8 11.6l-3.7 2 .7-4.2-3-3 4.2-.6z"/></svg>
          Watch a building
        </button>
      </div>

      <div className="stat-strip">
        <div className="stat-tile"><span className="st-label">Open deals</span><span className="st-val accent">{num(stats && stats.open_deals)}</span><span className="st-foot"><span className="fact">{stats ? fmtMoney(stats.weighted_pipeline) : "—"}</span> pipeline</span></div>
        <div className="stat-tile"><span className="st-label">Buildings watched</span><span className="st-val">{num(stats && stats.buildings_watched)}</span><span className="st-foot">in your metros</span></div>
        <div className="stat-tile"><span className="st-label">Companies followed</span><span className="st-val">{num(stats && stats.accounts_watched)}</span><span className="st-foot">accounts</span></div>
        <div className="stat-tile"><span className="st-label">Tasks due</span><span className="st-val">{num(stats && stats.tasks_due)}</span><span className="st-foot">open</span></div>
      </div>

      <div className="today-grid">
        {/* Tasks */}
        <section className="card">
          <div className="card-head">
            <span className="ch-title">Tasks due</span><span className="ch-spacer"></span>
            <button className="btn btn-sm" onClick={() => setAdding(true)}><Ico.Plus s={12}/>Add task</button>
          </div>
          {adding && (
            <div className="task-row" style={{ gap: "8px" }}>
              <input autoFocus value={taskText} onChange={(e) => setTaskText(e.target.value)} onKeyDown={(e) => { if (e.key === "Enter") addTask(); if (e.key === "Escape") { setAdding(false); setTaskText(""); } }}
                placeholder="New task…" style={{ flex: 1, height: "30px", border: "1px solid var(--border-2)", borderRadius: "var(--r-sm)", padding: "0 10px", font: "500 13px var(--font-sans)", outline: "none" }}/>
              <button className="btn btn-primary btn-sm" onClick={addTask}>Save</button>
            </div>
          )}
          {!tasks.length && !adding && <div className="muted" style={{ padding: "20px 14px", fontSize: "var(--fs-base)" }}>{loaded ? "No tasks due. Add one, or log tasks on a deal." : "Loading…"}</div>}
          {tasks.map((t) => (
            <div className="task-row" key={t.id}>
              <span className={"task-check" + (doneTasks[t.id] ? " done" : "")} aria-label="Complete" onClick={() => toggleTask(t.id)}>
                {doneTasks[t.id] && <svg width="10" height="10" viewBox="0 0 16 16" fill="none" stroke="currentColor" strokeWidth="2.4" strokeLinecap="round" strokeLinejoin="round"><path d="M3 8l3 3 7-7"/></svg>}
              </span>
              <div className="task-main">
                <div className="task-title">{t.title}</div>
                <div className="task-meta"><span className={"due " + t.due[0]}>{t.due[1]}</span> {t.meta}</div>
              </div>
              <span className={"scope-flag" + (t.shared ? " shared" : "")}>{t.shared ? <Ico.Team/> : <Ico.Lock/>}{t.shared ? "Team" : "Private"}</span>
            </div>
          ))}
        </section>

        {/* Signals (territory) */}
        <section>
          <div className="between" style={{ marginBottom: "11px" }}>
            <div className="flex gap8" style={{ alignItems: "baseline" }}>
              <h2 style={{ fontSize: "var(--fs-lg)", fontWeight: 600, letterSpacing: "-0.01em" }}>Live signals</h2>
              <span className="muted" style={{ fontSize: "var(--fs-sm)" }}>across your territory · newest first</span>
            </div>
            <a className="row-action" onClick={() => go("crm_signals")}>View all <Ico.Arrow/></a>
          </div>
          <div className="signal-list">
            {visibleSignals.map((sig) => {
              const evt = CRM_EVT[sig.type] || { label: sig.type, style: { background: "var(--bg-3)", color: "var(--fg-2)" } };
              return (
                <article className="signal-card" key={sig.id}>
                  <div className="sig-top">
                    <span className="evt-chip" style={evt.style}><span className="ed"></span>{evt.label}</span>
                    {sig.srcUrl ? <a className="src" href={sig.srcUrl} target="_blank" rel="noopener">{sig.src} ↗</a> : <span className="src">{sig.src}</span>}
                    <button className="sig-dismiss" title="Dismiss" onClick={() => dismiss(sig.id)}><Ico.X/></button>
                  </div>
                  <div className="sig-addr"><span className="a">{sig.a}</span>{sig.bbl && <span className="bbl">{sig.bbl}</span>}</div>
                  <div className="sig-fact">{sig.fact}</div>
                  {sig.ctx && <div className="sig-fact" style={{ color: "var(--fg-2)", fontSize: "var(--fs-sm)" }}>{sig.ctx}</div>}
                  <div className="sig-foot">
                    <button className="btn btn-primary btn-sm" onClick={() => createDeal(sig)}><Ico.Plus s={12}/>Create deal</button>
                    <button className="btn btn-sm" onClick={() => sig.parcel_ref ? go("crm_building") : toast("No building linked")}>Open building</button>
                  </div>
                </article>
              );
            })}
            {!visibleSignals.length && <div className="muted" style={{ padding: "24px 4px", fontSize: "var(--fs-base)" }}>{loaded ? "No live signals in your territory right now." : "Loading…"}</div>}
          </div>
        </section>
      </div>

      {/* Watch-a-building modal */}
      {watch && (
        <>
          <div className="scrim open" onClick={() => setWatch(null)}></div>
          <div style={{ position: "fixed", top: "12vh", left: "50%", transform: "translateX(-50%)", width: "560px", maxWidth: "94vw", background: "var(--bg)", border: "1px solid var(--border-1)", borderRadius: "var(--r-lg)", boxShadow: "var(--shadow-4)", zIndex: 60, overflow: "hidden" }}>
            <div className="card-head"><span className="ch-title">Watch a building</span><span className="ch-spacer"></span><button className="dr-close" onClick={() => setWatch(null)}><Ico.X/></button></div>
            <div style={{ padding: "14px 16px" }}>
              <input autoFocus value={watch.q} onChange={(e) => runSearch(e.target.value)} placeholder="Search by company at the building (e.g. Skanska, Coty)…"
                style={{ width: "100%", height: "36px", border: "1px solid var(--border-2)", borderRadius: "var(--r-md)", padding: "0 12px", font: "500 13px var(--font-sans)", outline: "none" }}/>
              <div style={{ marginTop: "12px", maxHeight: "44vh", overflowY: "auto" }}>
                {watch.busy && <div className="muted" style={{ padding: "12px 2px", fontSize: "var(--fs-sm)" }}>Searching…</div>}
                {!watch.busy && watch.q.trim().length >= 2 && !watch.results.length && <div className="muted" style={{ padding: "12px 2px", fontSize: "var(--fs-sm)" }}>No buildings found.</div>}
                {watch.results.map((r, i) => (
                  <div className="roster-row" key={i} style={{ borderBottom: "1px solid var(--border-1)" }}>
                    <span className="ind-ico">🏢</span>
                    <div className="roster-main">
                      <div className="roster-name">{r.anchor}</div>
                      <div className="roster-meta"><span className="roster-floors">{r.parcel_ref.replace("BBL:", "BBL ")}</span><span>{r.city}{r.state ? " · " + r.state : ""}</span><span className="emp">{r.org_count} orgs</span></div>
                    </div>
                    <div className="roster-actions">
                      <button className="btn btn-sm" onClick={() => doWatch(r)} title="Watch this building's events">Building</button>
                      {r.org_id && <button className="btn btn-primary btn-sm" onClick={() => doFollowOrg(r)} title="Follow this company's filings & events">Follow co.</button>}
                    </div>
                  </div>
                ))}
              </div>
            </div>
          </div>
        </>
      )}
    </div>
  );
}

function CrmTodayPage({ go, user }) {
  return <window.CrmShell go={go} user={user} current="today"><TodayContent/></window.CrmShell>;
}
window.CrmTodayPage = CrmTodayPage;
