const { useState, useEffect } = React;

/* CRM workspace shell — shared sidebar + topbar + persona + toasts + scoped
 * crm.css injection. Every CRM screen renders <CrmShell current="…">{content}</CrmShell>.
 * Screen content reads persona / toast via window.CrmContext.
 *
 * crm.css is injected only while a CRM screen is mounted (it carries a global
 * reset + generic class names that would collide with the marketing screens). */

window.CrmContext = window.CrmContext || React.createContext(null);

/* Error boundary — a render crash in any CRM screen shows a recoverable message
 * (and logs the error) instead of white-screening the whole workspace. */
class CrmErrorBoundary extends React.Component {
  constructor(p) { super(p); this.state = { err: null }; }
  static getDerivedStateFromError(err) { return { err }; }
  componentDidCatch(err, info) { console.error("[CRM] render error:", err, info); }
  render() {
    if (this.state.err) {
      return (
        <div className="crm-gate"><div className="crm-gate-card">
          <h2>Something went wrong</h2>
          <p>{String((this.state.err && this.state.err.message) || this.state.err)}</p>
          <button className="crm-gate-btn" onClick={() => { this.setState({ err: null }); try { location.reload(); } catch (_) {} }}>Reload</button>
        </div></div>
      );
    }
    return this.props.children;
  }
}
window.CrmErrorBoundary = CrmErrorBoundary;

/* ── shared content icons (reused by the screens) ───────────────────────── */
const SX = (p) => ({ fill: "none", stroke: "currentColor", strokeLinecap: "round", strokeLinejoin: "round", ...p });
window.CrmIco = {
  Plus:  (p) => <svg width={p && p.s || 14} height={p && p.s || 14} viewBox="0 0 16 16" {...SX({ strokeWidth: 1.6 })}><path d="M8 3v10M3 8h10"/></svg>,
  X:     () => <svg width="11" height="11" viewBox="0 0 16 16" {...SX({ strokeWidth: 1.5 })}><path d="M4 4l8 8M12 4l-8 8"/></svg>,
  Arrow: () => <svg width="11" height="11" viewBox="0 0 16 16" {...SX({ strokeWidth: 1.6 })}><path d="M3 8h9M8 4l4 4-4 4"/></svg>,
  Lock:  () => <svg width="11" height="11" viewBox="0 0 16 16" {...SX({ strokeWidth: 1.5 })}><rect x="3.5" y="7" width="9" height="6.5" rx="1.2"/><path d="M5.5 7V5a2.5 2.5 0 015 0v2"/></svg>,
  Team:  () => <svg width="11" height="11" viewBox="0 0 16 16" {...SX({ strokeWidth: 1.4 })}><circle cx="6" cy="6" r="2.2"/><path d="M2 13a4 4 0 018 0M11 5.5a2 2 0 010 3.4M14 13a4 4 0 00-3-3.8"/></svg>,
  Pin:   () => <svg width="11" height="11" viewBox="0 0 16 16" {...SX({ strokeWidth: 1.4 })}><path d="M8 14s5-4.5 5-9A5 5 0 003 5c0 4.5 5 9 5 9z"/><circle cx="8" cy="5" r="1.8"/></svg>,
  Chev:  () => <svg width="11" height="11" viewBox="0 0 16 16" {...SX({ strokeWidth: 1.4 })}><path d="M4 6l4 4 4-4"/></svg>,
};

/* sidebar nav icons */
const N = {
  dash:  () => <svg viewBox="0 0 16 16" {...SX({ strokeWidth: 1.4 })}><rect x="2" y="2" width="5" height="5" rx="1"/><rect x="9" y="2" width="5" height="5" rx="1"/><rect x="2" y="9" width="5" height="5" rx="1"/><rect x="9" y="9" width="5" height="5" rx="1"/></svg>,
  today: () => <svg viewBox="0 0 16 16" {...SX({ strokeWidth: 1.4 })}><rect x="2.5" y="3" width="11" height="11" rx="1.5"/><path d="M2.5 6.5h11M5.5 1.5v3M10.5 1.5v3"/><path d="M6 10l1.5 1.5L10.5 8.5"/></svg>,
  deals: () => <svg viewBox="0 0 16 16" {...SX({ strokeWidth: 1.4 })}><rect x="2" y="2.5" width="3.4" height="11" rx="1"/><rect x="6.3" y="2.5" width="3.4" height="8" rx="1"/><rect x="10.6" y="2.5" width="3.4" height="6" rx="1"/></svg>,
  bldg:  () => <svg viewBox="0 0 16 16" {...SX({ strokeWidth: 1.4 })}><path d="M3 14V3.5L8 2l5 1.5V14"/><path d="M2 14h12"/><path d="M6 6h0M10 6h0M6 9h0M10 9h0M6.5 14v-2.5h3V14"/></svg>,
  acct:  () => <svg viewBox="0 0 16 16" {...SX({ strokeWidth: 1.4 })}><rect x="2" y="5" width="12" height="9" rx="1.5"/><path d="M5.5 5V3.5A1.5 1.5 0 017 2h2a1.5 1.5 0 011.5 1.5V5M2 9h12"/></svg>,
  sig:   () => <svg viewBox="0 0 16 16" {...SX({ strokeWidth: 1.4 })}><circle cx="8" cy="8" r="1.8"/><path d="M4.5 4.5a5 5 0 000 7M11.5 4.5a5 5 0 010 7M2.5 2.5a8 8 0 000 11M13.5 2.5a8 8 0 010 11"/></svg>,
  prosp: () => <svg viewBox="0 0 16 16" {...SX({ strokeWidth: 1.4 })}><path d="M8 14s5-4.5 5-9A5 5 0 003 5c0 4.5 5 9 5 9z"/><circle cx="8" cy="5" r="1.8"/></svg>,
};

/* k → built route (others toast "coming soon" until built) */
const CRM_NAV = [
  { k: "today",     label: "Today",     ico: N.today, badge: "7",   hot: true,  route: "crm_today" },
  { k: "deals",     label: "Deals",     ico: N.deals, badge: "24",              route: "crm_deals" },
  { k: "buildings", label: "Buildings", ico: N.bldg,  badge: "36",  route: "crm_building" },
  { k: "accounts",  label: "Accounts",  ico: N.acct,  badge: "112", route: "crm_account" },
  { k: "signals",   label: "Signals",   ico: N.sig,   badge: "18",  hot: true, route: "crm_signals" },
];

function CrmShell({ go, user, current, children }) {
  const [persona, setPersona] = useState(() => localStorage.getItem("aiciq.crm.persona") || "broker");
  const [toasts, setToasts] = useState([]);
  const [counts, setCounts] = useState(null);

  // Auth gate: the CRM is private. Don't show the mock "Maya" workspace to a
  // logged-out tab (e.g. a map/extension deep-link that opened a fresh tab).
  // Wait for the session to be known (`ready`), then either show the workspace
  // or a sign-in prompt — never fabricated CRM data.
  const ciq = window.ContactIQ ? window.ContactIQ.useContactIQ() : { ready: true, isAuthed: true };

  // ALL hooks must run unconditionally on every render — before any early
  // return below. Otherwise when `ready` flips false→true the hook count
  // changes between renders and React throws #310 (crashes the CRM view).

  // Real nav badge counts (no fabricated numbers; badge hidden when zero).
  useEffect(() => {
    const c = window.ContactIQ && window.ContactIQ.client;
    if (!c) return;
    let alive = true;
    c.rpc("crm_dashboard_stats", {}).then(({ data, error }) => {
      if (alive && !error && data && data[0]) {
        const s = data[0];
        setCounts({ today: Number(s.tasks_due) || 0, deals: Number(s.open_deals) || 0, buildings: Number(s.buildings_watched) || 0, accounts: Number(s.accounts_watched) || 0, signals: Number(s.signals_new) || 0 });
      }
    }).catch(() => {});
    return () => { alive = false; };
  }, []);

  useEffect(() => {
    let link = document.getElementById("crm-css"), created = false;
    if (!link) {
      link = document.createElement("link");
      link.id = "crm-css"; link.rel = "stylesheet"; link.href = "styles/crm.css?v=2";
      document.head.appendChild(link); created = true;
    }
    return () => { if (created && link.parentNode) link.parentNode.removeChild(link); };
  }, []);

  useEffect(() => {
    const prev = document.body.getAttribute("data-persona");
    document.body.setAttribute("data-persona", persona);
    return () => { prev ? document.body.setAttribute("data-persona", prev) : document.body.removeAttribute("data-persona"); };
  }, [persona]);

  // Auth gate (AFTER all hooks): the CRM is private — wait for the session, then
  // show the workspace or a sign-in prompt; never fabricated CRM data.
  if (window.ContactIQ && !ciq.ready) {
    return <div className="crm-gate"><div className="crm-gate-card"><div className="crm-gate-spin"/><p>Loading your workspace…</p></div></div>;
  }
  if (window.ContactIQ && !ciq.isAuthed) {
    return (
      <div className="crm-gate">
        <div className="crm-gate-card">
          <span className="crm-gate-mark"><svg width="20" height="20" viewBox="0 0 16 16" fill="none" stroke="#2563eb" strokeWidth="1.5" strokeLinecap="round" strokeLinejoin="round"><path d="M3 14V4l5-2 5 2v10"/><path d="M3 14h10"/></svg></span>
          <h2>Sign in to your CRM</h2>
          <p>Your AI.CONTACTIQ workspace is private. Sign in to see your deals, watched buildings, and signals.</p>
          <button className="crm-gate-btn" onClick={() => go("login")}>Sign in</button>
        </div>
      </div>
    );
  }

  const toast = (msg) => {
    const id = Math.random().toString(36).slice(2);
    setToasts((t) => [...t, { id, msg }]);
    setTimeout(() => setToasts((t) => t.filter((x) => x.id !== id)), 2600);
  };
  const pickPersona = (p) => { setPersona(p); localStorage.setItem("aiciq.crm.persona", p); toast((p === "lender" ? "Lender" : "Broker") + " view · pipelines and dossier re-weighted"); };
  const navClick = (it) => { it.route ? go(it.route) : toast("Screen coming soon"); };
  const signOut = async () => { if (window.ContactIQ) { try { await window.ContactIQ.signOut(); } catch (_) {} } go("landing"); };

  const uname = (user && user.name) || "Jordan Mercer";
  const ucompany = (user && user.company) || "Cushman & Wakefield";
  const initials = uname.split(/\s+/).map((p) => p[0]).slice(0, 2).join("").toUpperCase();

  return (
    <window.CrmContext.Provider value={{ persona, setPersona: pickPersona, toast, go }}>
      <div className="app-shell">
        <aside className="app-side">
          <div className="side-logo">
            <span className="mark">
              <svg width="13" height="13" viewBox="0 0 16 16" fill="none" stroke="#fff" strokeWidth="1.5" strokeLinecap="round" strokeLinejoin="round"><path d="M3 14V4l5-2 5 2v10"/><path d="M3 14h10M6.5 7h0M9.5 7h0M6.5 10h0M9.5 10h0"/></svg>
            </span>
            <span className="wordmark">AI<span className="dot">.</span>CONTACTIQ</span>
          </div>

          <nav className="side-nav">
            <a className="nav-item" onClick={() => go("dashboard")}>
              <span className="nav-ico"><N.dash/></span><span className="nav-label">Dashboard</span>
            </a>
            <div className="side-section">CRM · Deals</div>
            {CRM_NAV.map((it) => {
              const n = counts ? counts[it.k] : null;
              return (
                <a key={it.k} className={"nav-item" + (current === it.k ? " active" : "")} onClick={() => navClick(it)}>
                  <span className="nav-ico">{it.ico()}</span>
                  <span className="nav-label">{it.label}</span>
                  {n > 0 && <span className={"nav-badge" + (it.hot ? " hot" : "")}>{n}</span>}
                </a>
              );
            })}
            <a className="nav-item" onClick={() => go("map")}>
              <span className="nav-ico"><N.prosp/></span>
              <span className="nav-label">Prospect</span>
              <span className="nav-badge" style={{ background: "transparent", color: "var(--fg-3)", fontFamily: "var(--font-sans)", fontSize: "9px", letterSpacing: ".04em", textTransform: "uppercase" }}>Map</span>
            </a>
          </nav>

          <div className="side-foot">
            <div className="user-chip">
              <span className="avatar" style={{ background: "#2563eb18", color: "#2563eb", borderColor: "#2563eb30" }}>{initials}</span>
              <span className="ux"><span className="uname">{uname}</span><span className="urole">{ucompany}</span></span>
              <button className="signout" title="Sign out" onClick={signOut}>
                <svg width="14" height="14" viewBox="0 0 16 16" {...SX({ strokeWidth: 1.4 })}><path d="M6 14H3V2h3M10 11l3-3-3-3M13 8H6"/></svg>
              </button>
            </div>
          </div>
        </aside>

        <main className="app-main">
          <header className="app-top">
            <div className="top-search">
              <svg width="14" height="14" viewBox="0 0 16 16" fill="none" stroke="currentColor" strokeWidth="1.4"><circle cx="7" cy="7" r="5"/><path d="M11 11l3 3"/></svg>
              <input type="text" placeholder="Search buildings, orgs, people, deals…"/>
              <span className="kbd">⌘K</span>
            </div>
            <div className="top-spacer"></div>
            <div className="persona-seg" title="Switch persona — re-weights pipelines and dossier">
              <button className={persona === "broker" ? "on" : ""} onClick={() => pickPersona("broker")}><span className="pdot"></span>Broker</button>
              <button className={persona === "lender" ? "on" : ""} onClick={() => pickPersona("lender")}><span className="pdot"></span>Lender</button>
            </div>
            <div className="top-actions">
              <button className="icon-btn" title="Notifications"><svg width="15" height="15" viewBox="0 0 16 16" {...SX({ strokeWidth: 1.4 })}><path d="M8 2a4 4 0 00-4 4c0 4-1.5 5-1.5 5h11S12 10 12 6a4 4 0 00-4-4zM6.5 13.5a1.5 1.5 0 003 0"/></svg><span className="dot-badge"></span></button>
            </div>
          </header>

          <div className="app-content"><CrmErrorBoundary>{children}</CrmErrorBoundary></div>
        </main>
      </div>

      {toasts.length > 0 && (
        <div className="toast-wrap">
          {toasts.map((t) => (
            <div className="toast show" key={t.id}>
              <svg width="14" height="14" viewBox="0 0 16 16" {...SX({ strokeWidth: 2 })}><path d="M3 8l3 3 7-7"/></svg>{t.msg}
            </div>
          ))}
        </div>
      )}
    </window.CrmContext.Provider>
  );
}

window.CrmShell = CrmShell;
