const { useState, useEffect, useMemo, useRef } = React;

/* Dashboard — user's lookup history (the "what the extension has looked at" view) */

function DashboardPage({ go, user, populated = true }) {
  const { LOOKUPS } = window.CONTACTIQ_DATA;
  const ciq = window.ContactIQ ? window.ContactIQ.useContactIQ() : { isAuthed: false };

  const [filter, setFilter] = useState("all"); // all | building | company
  const [query, setQuery] = useState("");
  const [tag, setTag] = useState(null);
  const [selected, setSelected] = useState(new Set());
  const [editing, setEditing] = useState(null);

  // Real lookups when signed in, mocks otherwise. The `populated` tweak
  // toggles the empty state when in preview mode.
  const [remoteLookups, setRemoteLookups] = useState(null);
  const [loading, setLoading] = useState(false);

  useEffect(() => {
    if (!ciq.isAuthed) { setRemoteLookups(null); return; }
    let cancelled = false;
    setLoading(true);
    window.ContactIQ.listLookups({ limit: 500 }).then(rows => {
      if (!cancelled) { setRemoteLookups(rows); setLoading(false); }
    });
    return () => { cancelled = true; };
  }, [ciq.isAuthed]);

  const lookups = ciq.isAuthed
    ? (remoteLookups || [])
    : (populated ? LOOKUPS : []);

  // All tags in dataset
  const allTags = useMemo(() => {
    const s = new Set();
    lookups.forEach(l => l.tags?.forEach(t => s.add(t)));
    return Array.from(s);
  }, [lookups]);

  const filtered = useMemo(() => {
    return lookups.filter(l => {
      if (filter !== "all" && l.type !== filter) return false;
      if (tag && !l.tags?.includes(tag)) return false;
      if (query) {
        const q = query.toLowerCase();
        if (!l.name.toLowerCase().includes(q) && !l.sub.toLowerCase().includes(q)) return false;
      }
      return true;
    });
  }, [filter, query, tag, lookups]);

  const stats = useMemo(() => ({
    total: lookups.length,
    buildings: lookups.filter(l => l.type === "building").length,
    companies: lookups.filter(l => l.type === "company").length,
    tagged: lookups.filter(l => l.tags?.length).length,
  }), [lookups]);

  const toggleSelect = (id) => setSelected(s => {
    const n = new Set(s);
    n.has(id) ? n.delete(id) : n.add(id);
    return n;
  });

  return (
    <>
      {/* Extension connection bridge */}
      {ciq.isAuthed && <ExtensionBridgeBanner go={go}/>}

      {/* Trial banner if applicable */}
      {user.plan === "trial" && (
        <div className="trial-banner">
          <I.Sparkle style={{ color: "var(--accent)" }}/>
          <span><b>14-day trial active</b> · first charge <span className="mono">Jun 8, 2026</span> · 13 days remaining</span>
          <span className="spacer"/>
          <button className="btn sm" onClick={() => go("billing")}>Manage billing</button>
        </div>
      )}

      <div className="work-head">
        <div className="col" style={{ gap: 2 }}>
          <div className="title">Lookup history</div>
          <div className="sub">Everything the extension has surfaced for you. Searchable, taggable, exportable.</div>
        </div>
        <div className="spacer"/>
        <div className="row tight">
          <button className="btn sm" disabled={selected.size === 0}>
            <I.Tag/> Tag {selected.size > 0 && `(${selected.size})`}
          </button>
          <button className="btn sm" onClick={() => exportLookupsCsv(lookups)}>
            <I.Download/> Export CSV
          </button>
        </div>
      </div>

      <div className="work-body">
        {/* Locked upgrade row */}
        <div className="dash-upgrade">
          <button className="dash-upgrade-card" onClick={() => go("waitlist:full_report")}>
            <div className="dash-up-icon"><I.Box style={{ width: 18, height: 18 }}/></div>
            <div className="col" style={{ gap: 2, alignItems: "flex-start", flex: 1, minWidth: 0 }}>
              <span className="dash-up-title">
                <span className="dash-up-lock-icon">
                  <svg width="9" height="9" viewBox="0 0 12 12" fill="none" stroke="currentColor" strokeWidth="1.4" strokeLinecap="round" strokeLinejoin="round">
                    <rect x="2.5" y="5.5" width="7" height="5" rx="0.5"/>
                    <path d="M4 5.5 V3.5 A2 2 0 0 1 8 3.5 V5.5"/>
                  </svg>
                </span>
                Full Report
              </span>
              <span className="dim dash-up-desc">
                7-tab entity record · per-field sources · financials · news
              </span>
            </div>
            <div className="dash-up-cta">
              Join waitlist <I.ChevR/>
            </div>
          </button>

          <button className="dash-upgrade-card" onClick={() => go("waitlist:map")}>
            <div className="dash-up-icon"><I.Pin style={{ width: 18, height: 18 }}/></div>
            <div className="col" style={{ gap: 2, alignItems: "flex-start", flex: 1, minWidth: 0 }}>
              <span className="dash-up-title">
                <span className="dash-up-lock-icon">
                  <svg width="9" height="9" viewBox="0 0 12 12" fill="none" stroke="currentColor" strokeWidth="1.4" strokeLinecap="round" strokeLinejoin="round">
                    <rect x="2.5" y="5.5" width="7" height="5" rx="0.5"/>
                    <path d="M4 5.5 V3.5 A2 2 0 0 1 8 3.5 V5.5"/>
                  </svg>
                </span>
                Main Map System
              </span>
              <span className="dim dash-up-desc">
                5M-pin building map · cluster drawers · filter by source &amp; state
              </span>
            </div>
            <div className="dash-up-cta">
              Join waitlist <I.ChevR/>
            </div>
          </button>
        </div>

        {/* KPI tiles */}
        <div className="dash-kpis">
          <div className="kpi">
            <span className="lbl">Total lookups</span>
            <span className="val accent">{stats.total || "—"}</span>
            <span className="delta">last 30 days</span>
          </div>
          <div className="kpi">
            <span className="lbl">Buildings</span>
            <span className="val">{stats.buildings || "—"}</span>
            <span className="delta">{stats.buildings > 0 ? `${Math.round(stats.buildings/stats.total*100)}% of total` : "—"}</span>
          </div>
          <div className="kpi">
            <span className="lbl">Companies</span>
            <span className="val">{stats.companies || "—"}</span>
            <span className="delta">{stats.companies > 0 ? `${Math.round(stats.companies/stats.total*100)}% of total` : "—"}</span>
          </div>
          <div className="kpi">
            <span className="lbl">Tagged</span>
            <span className="val">{stats.tagged || "—"}</span>
            <span className="delta">notes &amp; tags</span>
          </div>
        </div>

        {/* Filters */}
        <div className="dash-filters">
          <input
            className="input search sm"
            style={{ width: 260 }}
            placeholder="Search address or company…"
            value={query}
            onChange={e => setQuery(e.target.value)}
          />
          <div className="seg">
            {[["all","All"],["building","Buildings"],["company","Companies"]].map(([k,l]) => (
              <button key={k} className={"seg-btn " + (filter === k ? "on" : "")} onClick={() => setFilter(k)}>{l}</button>
            ))}
          </div>
          <div className="row tight" style={{ flexWrap: "wrap" }}>
            {allTags.length > 0 && <span className="eyebrow" style={{ fontSize: 9 }}>TAGS</span>}
            {allTags.map(t => (
              <button key={t} className={"tag-chip " + (tag === t ? "on" : "")} onClick={() => setTag(tag === t ? null : t)}>
                {t}
              </button>
            ))}
          </div>
          <span className="spacer"/>
          <span className="dim mono" style={{ fontSize: 11 }}>{filtered.length} of {stats.total}</span>
        </div>

        {/* History list */}
        {lookups.length === 0 ? (
          <DashboardEmpty/>
        ) : (
          <div className="lookup-list">
            <table className="tbl">
              <thead>
                <tr>
                  <th style={{ width: 30 }}>
                    <input type="checkbox" style={{ accentColor: "var(--accent)" }}/>
                  </th>
                  <th>Lookup</th>
                  <th style={{ width: 110 }}>Type</th>
                  <th style={{ width: 140 }}>Source page</th>
                  <th style={{ width: 130 }}>Trigger</th>
                  <th style={{ width: 110 }}>Tags</th>
                  <th style={{ width: 140 }}>Time</th>
                  <th style={{ width: 130 }}>&nbsp;</th>
                </tr>
              </thead>
              <tbody>
                {filtered.map(l => (
                  <tr key={l.id} className={selected.has(l.id) ? "sel" : ""}>
                    <td>
                      <input
                        type="checkbox"
                        checked={selected.has(l.id)}
                        onChange={() => toggleSelect(l.id)}
                        style={{ accentColor: "var(--accent)" }}
                      />
                    </td>
                    <td>
                      <div className="col" style={{ gap: 1 }}>
                        <div style={{ fontWeight: 600, fontSize: 12.5 }}>{l.name}</div>
                        <div className="dim" style={{ fontSize: 11 }}>{l.sub}</div>
                        {l.details && <DetailsRow type={l.type} details={l.details}/>}
                        {l.note && (
                          <div className="lookup-note">
                            <I.Tag style={{ width: 9, height: 9, color: "var(--fg-3)" }}/>
                            {l.note}
                          </div>
                        )}
                      </div>
                    </td>
                    <td><TypePill type={l.type}/></td>
                    <td className="mono dim" style={{ fontSize: 11 }}>{l.page}</td>
                    <td>
                      <span className="trigger-pill">{triggerLabel(l.trigger)}</span>
                    </td>
                    <td>
                      <div className="row tight" style={{ flexWrap: "wrap", gap: 3 }}>
                        {l.tags?.map(t => <span key={t} className="tag">{t}</span>)}
                        {(!l.tags || l.tags.length === 0) && <span className="dim">—</span>}
                      </div>
                    </td>
                    <td className="mono dim" style={{ fontSize: 11 }}>{l.ts}</td>
                    <td>
                      <div className="row tight" style={{ justifyContent: "flex-end" }}>
                        <button
                          className="view-report-btn"
                          title="Upgrade to view the full report"
                          onClick={() => go("waitlist:full_report")}
                        >
                          <span className="view-report-lock">
                            <svg width="9" height="9" viewBox="0 0 12 12" fill="none" stroke="currentColor" strokeWidth="1.4" strokeLinecap="round" strokeLinejoin="round">
                              <rect x="2.5" y="5.5" width="7" height="5" rx="0.5"/>
                              <path d="M4 5.5 V3.5 A2 2 0 0 1 8 3.5 V5.5"/>
                            </svg>
                          </span>
                          View report
                        </button>
                        <button className="btn icon sm row-act" title="Edit tags/note" onClick={() => setEditing(l)}><I.Tag/></button>
                        <button className="btn icon sm row-act" title="More"><I.Dots/></button>
                      </div>
                    </td>
                  </tr>
                ))}
              </tbody>
            </table>
            {filtered.length === 0 && (
              <div className="empty" style={{ padding: 32 }}>
                <span className="dim">No lookups match your filters.</span>
              </div>
            )}
          </div>
        )}
      </div>

      {/* Tag/note edit modal */}
      {editing && (
        <EditTagsModal
          lookup={editing}
          onClose={() => setEditing(null)}
          onSaved={(updated) => {
            // optimistic patch
            setRemoteLookups(prev => (prev || []).map(l => l.id === updated.id ? updated : l));
          }}
        />
      )}
    </>
  );
}

/* Banner that shows whether the Chrome extension is bridged to this account.
 * When not bridged, asks for the extension ID (32 a–p chars from chrome://extensions).
 * Auto-pushes the current Supabase JWT on mount + on every focus, so the
 * extension can write to user_lookups under this user. */
function ExtensionBridgeBanner({ go }) {
  const [state, setState] = useState(window.ContactIQ.getExtensionState());
  const [extId, setExtId] = useState(window.ContactIQ.getExtensionId() || "");
  const [showManual, setShowManual] = useState(false);
  const [busy, setBusy] = useState(false);
  const [err, setErr]   = useState(null);

  // Push JWT + ping on mount, when window regains focus, and when the auto-
  // discovery message lands. We also re-broadcast the discovery request so the
  // bridge content script (if just installed) gets a chance to answer.
  useEffect(() => {
    let alive = true;
    const refresh = async () => {
      if (!window.ContactIQ.getExtensionId()) return;
      await window.ContactIQ.pushJwtToExtension();
      const s = await window.ContactIQ.pingExtension();
      if (alive) { setState(s); setExtId(window.ContactIQ.getExtensionId() || ""); }
    };
    refresh();
    const onFocus = () => refresh();
    const onAnnounce = (ev) => {
      if (ev.source !== window) return;
      if (ev.data && ev.data.type === "aiciq:ext_present") refresh();
    };
    window.addEventListener("focus", onFocus);
    window.addEventListener("message", onAnnounce);
    // Ask the bridge to announce itself (covers extension-installed-after-page-load)
    try { window.postMessage({ type: "aiciq:ext_who" }, "*"); } catch (_) {}
    const tries = [500, 1500, 4000].map(ms => setTimeout(() => {
      try { window.postMessage({ type: "aiciq:ext_who" }, "*"); } catch (_) {}
      refresh();
    }, ms));
    return () => {
      alive = false;
      window.removeEventListener("focus", onFocus);
      window.removeEventListener("message", onAnnounce);
      tries.forEach(clearTimeout);
    };
  }, []);

  const connect = async () => {
    setErr(null); setBusy(true);
    try {
      window.ContactIQ.setExtensionId(extId.trim().toLowerCase());
      await window.ContactIQ.pushJwtToExtension();
      const s = await window.ContactIQ.pingExtension();
      setState(s);
      if (s.connected) setShowManual(false);
      else setErr(s.lastError || "Extension didn't respond. Check the ID and that it's installed.");
    } catch (e) { setErr(e.message); }
    finally { setBusy(false); }
  };

  const disconnect = async () => {
    await window.ContactIQ.clearExtensionJwt();
    window.ContactIQ.clearExtensionId();
    setExtId(""); setState({ connected: false, email: null });
  };

  // Connected → green banner (the happy path; auto-discovery handles 99% of cases).
  if (state.connected) {
    return (
      <div className="trial-banner" style={{ background: "color-mix(in srgb, var(--green) 8%, transparent)", borderColor: "color-mix(in srgb, var(--green) 35%, transparent)" }}>
        <I.Check style={{ color: "var(--green)" }}/>
        <span><b>Extension connected</b> · signed in as <span className="mono">{state.email || "—"}</span></span>
        <span className="spacer"/>
        <button className="btn ghost sm" onClick={disconnect}>Disconnect</button>
      </div>
    );
  }

  // ID known but not connected yet → "connecting" / install nag
  const idKnown = !!window.ContactIQ.getExtensionId();
  if (idKnown && !showManual) {
    return (
      <div className="trial-banner">
        <I.Sparkle style={{ color: "var(--accent)" }}/>
        <span>
          <b>Linking extension…</b> If this hangs, make sure the AIContactIQ extension is loaded and you've reloaded it after the latest update.
        </span>
        <span className="spacer"/>
        <button className="btn ghost sm" onClick={() => setShowManual(true)}>Enter ID manually</button>
      </div>
    );
  }

  // No ID yet → either auto-discovery hasn't fired or the extension isn't installed.
  if (!showManual) {
    return (
      <div className="trial-banner">
        <I.Sparkle style={{ color: "var(--accent)" }}/>
        <span>
          <b>Install the Chrome extension</b> to log your lookups here. Once installed, this banner auto-links to your account — no copy/paste.
        </span>
        <span className="spacer"/>
        <a className="btn primary sm" href="#" onClick={(e) => { e.preventDefault(); go("extension"); }}>
          Install <I.ChevR/>
        </a>
        <button className="btn ghost sm" onClick={() => setShowManual(true)}>Have an ID?</button>
      </div>
    );
  }

  // Manual fallback (rare — wrong-origin dev setups, etc.)
  return (
    <div className="trial-banner" style={{ flexWrap: "wrap" }}>
      <I.Sparkle style={{ color: "var(--accent)" }}/>
      <span>
        Open <span className="mono">chrome://extensions</span>, find AIContactIQ, copy the ID, paste it below.
      </span>
      <span className="spacer"/>
      <input
        className="input sm mono"
        style={{ width: 280, fontSize: 12 }}
        placeholder="e.g. abcdefghijklmnopabcdefghijklmnop"
        value={extId}
        onChange={e => setExtId(e.target.value)}
        onKeyDown={e => { if (e.key === "Enter") connect(); }}
      />
      <button className="btn primary sm" disabled={busy || !extId} onClick={connect}>
        {busy ? "Connecting…" : "Connect"}
      </button>
      <button className="btn ghost sm" onClick={() => setShowManual(false)}>Cancel</button>
      {err && <span className="err" style={{ flexBasis: "100%", fontSize: 11 }}>{err}</span>}
    </div>
  );
}

/* Small chips that surface BBL / owner / org facts on each lookup row.
 * Reads the `details` jsonb the extension shipped at log time. */
function DetailsRow({ type, details }) {
  if (!details) return null;
  const chips = [];

  if (type === "building") {
    if (details.bbl_fmt)
      chips.push({ label: "BBL", value: details.bbl_fmt, mono: true });
    if (details.owner)
      chips.push({ label: "owner", value: details.owner });
    if (details.units && !String(details.sublabel || "").includes(" unit"))
      chips.push({ label: "units", value: details.units });
  } else if (type === "company") {
    if (details.website)
      chips.push({ label: "site", value: details.website, mono: true });
    if (details.employees)
      chips.push({ label: "emp", value: details.employees });
    if (details.portfolio_size)
      chips.push({ label: "locs", value: details.portfolio_size });
    if (details.contacts_count)
      chips.push({ label: "contacts", value: details.contacts_count });
  }

  if (chips.length === 0) return null;
  return (
    <div className="row tight" style={{ marginTop: 3, gap: 4, flexWrap: "wrap" }}>
      {chips.map((c, i) => (
        <span key={i} className="tag" style={{
          fontSize: 10, padding: "1px 6px", background: "var(--bg-2)",
          color: "var(--fg-2)", border: "1px solid var(--border-1)",
        }}>
          <span className="dim" style={{ fontSize: 9, marginRight: 4, textTransform: "uppercase", letterSpacing: "0.04em" }}>{c.label}</span>
          <span className={c.mono ? "mono" : ""} style={{ fontWeight: 500 }}>{c.value}</span>
        </span>
      ))}
    </div>
  );
}

function triggerLabel(t) {
  return {
    address_detect: "Address detect",
    sidebar:        "Sidebar",
    right_click:    "Right-click",
    popup_open:     "Popup",
    search:         "Search",
    manual:         "Manual",
  }[t] || t;
}

function exportLookupsCsv(rows) {
  if (!rows || rows.length === 0) return;
  const cols = ["ts","type","name","sub","page","trigger","tags","note","entityId"];
  const esc = v => {
    if (v == null) return "";
    const s = Array.isArray(v) ? v.join("|") : String(v);
    return /[",\n]/.test(s) ? '"' + s.replace(/"/g, '""') + '"' : s;
  };
  const csv = [cols.join(",")].concat(
    rows.map(r => cols.map(c => esc(r[c])).join(","))
  ).join("\n");
  const blob = new Blob([csv], { type: "text/csv" });
  const url = URL.createObjectURL(blob);
  const a = document.createElement("a");
  a.href = url;
  a.download = `contactiq-lookups-${new Date().toISOString().slice(0,10)}.csv`;
  document.body.appendChild(a); a.click(); a.remove();
  URL.revokeObjectURL(url);
}

function EditTagsModal({ lookup, onClose, onSaved }) {
  const [tags, setTags] = useState(lookup.tags || []);
  const [note, setNote] = useState(lookup.note || "");
  const [newTag, setNewTag] = useState("");
  const [saving, setSaving] = useState(false);

  const save = async () => {
    setSaving(true);
    try {
      if (window.ContactIQ && lookup._rawId) {
        await window.ContactIQ.updateLookupTagsNote(lookup._rawId, tags, note);
      }
      if (onSaved) onSaved({ ...lookup, tags, note });
    } finally { setSaving(false); onClose(); }
  };

  return (
    <div className="modal-overlay" onClick={onClose}>
      <div className="modal" onClick={e => e.stopPropagation()}>
        <div className="modal-head">
          <div className="col" style={{ gap: 2 }}>
            <div className="eyebrow">EDIT TAGS &amp; NOTE</div>
            <div style={{ fontWeight: 600, fontSize: 14 }}>{lookup.name}</div>
            <div className="dim" style={{ fontSize: 11 }}>{lookup.sub}</div>
          </div>
          <button className="btn icon" onClick={onClose}><I.X/></button>
        </div>
        <div className="modal-body">
          <div className="field">
            <label className="label">Tags</label>
            <div className="row tight" style={{ flexWrap: "wrap" }}>
              {tags.map(t => (
                <span key={t} className="tag" style={{ paddingRight: 4 }}>
                  {t}
                  <button onClick={() => setTags(tags.filter(x => x !== t))} style={{ marginLeft: 4, color: "var(--fg-3)", display: "inline-flex" }}><I.X style={{ width: 9, height: 9 }}/></button>
                </span>
              ))}
              <input
                className="input sm"
                style={{ width: 140 }}
                placeholder="Add tag…"
                value={newTag}
                onChange={e => setNewTag(e.target.value)}
                onKeyDown={e => {
                  if (e.key === "Enter" && newTag.trim()) {
                    setTags([...tags, newTag.trim()]);
                    setNewTag("");
                  }
                }}
              />
            </div>
          </div>
          <div className="field">
            <label className="label">Note</label>
            <textarea
              className="input"
              style={{ height: 80, padding: 9, resize: "vertical", lineHeight: 1.45 }}
              value={note}
              onChange={e => setNote(e.target.value)}
              placeholder="Why did you look this up? Decision-maker, lease status, anything."
            />
          </div>
        </div>
        <div className="modal-foot">
          <button className="btn" onClick={onClose}>Cancel</button>
          <button className="btn primary" disabled={saving} onClick={save}>
            {saving ? "Saving…" : "Save"}
          </button>
        </div>
      </div>
    </div>
  );
}

function DashboardEmpty() {
  return (
    <div className="dash-empty">
      <div className="dash-empty-icon">
        <I.History style={{ width: 36, height: 36 }}/>
      </div>
      <h3 style={{ font: "600 18px var(--font-sans)", letterSpacing: "-0.01em" }}>Nothing here yet.</h3>
      <p className="dim" style={{ maxWidth: 380, textAlign: "center", lineHeight: 1.55, fontSize: 13 }}>
        When the extension surfaces a building or company for you, it shows up here. Try opening any
        LinkedIn company page or right-clicking an address on Google Maps.
      </p>
      <div className="dash-empty-tips">
        <div className="dash-empty-tip">
          <span className="mono" style={{ color: "var(--accent)", fontWeight: 700 }}>01</span>
          Install the extension on Chrome, Firefox, Edge, or Safari.
        </div>
        <div className="dash-empty-tip">
          <span className="mono" style={{ color: "var(--accent)", fontWeight: 700 }}>02</span>
          Visit LinkedIn / ZoomInfo / CoStar — the sidebar opens automatically.
        </div>
        <div className="dash-empty-tip">
          <span className="mono" style={{ color: "var(--accent)", fontWeight: 700 }}>03</span>
          Or highlight any address and right-click → "Look up in ContactIQ".
        </div>
      </div>
      <button className="btn primary">Open install guide <I.Open/></button>
    </div>
  );
}

window.DashboardPage = DashboardPage;
