/* CRM · Account — fourth batch of company dossier panels, ported 1:1 from the
 * map modal's renderDossier* functions (index.html). Mirrors the contract,
 * helpers, and styling of CrmAccountPanels.jsx: each panel fetches its own RPC
 * keyed by org_id and renders ONLY when real data is on file (returns null
 * otherwise) — no fabricated rows, no placeholders. Registered on
 * window.CrmPanels[key]; reuses the shared kit on window.CrmPanelKit. */

(function () {
  const { useState, useEffect } = React;
  const K = window.CrmPanelKit;
  const { usePanelData, rpcLoad, fnGet, money, num, fmtDate, fmtMonth, SrcBadge, Flag, Panel, RegRow, Field, AddrBlock, Note, fmtAddr } = K;
  window.CrmPanels = window.CrmPanels || {};

  // Subsection label (mirrors the map's _ds_subsec — small bold uppercase header).
  const Subsec = ({ children }) => (
    <div style={{ fontSize: "var(--fs-sm)", color: "var(--fg-3)", fontWeight: 600, textTransform: "uppercase", letterSpacing: ".05em", margin: "10px 14px 6px" }}>{children}</div>
  );

  // ───────────────────────── PANELS ─────────────────────────

  // 1. Food inspection — NYC DOHMH / NYS DOH (renderDossierFoodInspection).
  // RPC org_food_inspection → rows[0] = { source, grade, score, cuisine,
  // latest_inspection, critical_violations, noncritical_violations,
  // recent_violations:[{date, code, critical, desc}] }.
  window.CrmPanels.food = function FoodInspection({ orgId }) {
    const rows = usePanelData(rpcLoad("org_food_inspection"), orgId);
    const r = Array.isArray(rows) ? rows[0] : rows;
    if (!r) return null;
    const gradeColor = { A: "#16a34a", B: "#eab308", C: "#dc2626", P: "#6366f1", Z: "#94a3b8", N: "#94a3b8" };
    const gradeBg = { A: "#dcfce7", B: "#fef3c7", C: "#fee2e2", P: "#e0e7ff", Z: "#f1f5f9", N: "#f1f5f9" };
    const viols = (r.recent_violations && Array.isArray(r.recent_violations)) ? r.recent_violations.slice(0, 5) : [];
    return (
      <Panel title="Food inspection" badge={<SrcBadge bg="#fee2e2" color="#991b1b">DOHMH</SrcBadge>} source={r.source || "DOH"}>
        <div style={{ padding: "6px 16px 14px" }}>
          {r.grade && (
            <div style={{ display: "inline-flex", alignItems: "center", justifyContent: "center", width: 48, height: 48, borderRadius: 8, background: gradeBg[r.grade] || "#f1f5f9", color: gradeColor[r.grade] || "#475569", fontWeight: 800, fontSize: 28, marginRight: 14, verticalAlign: "middle" }}>{r.grade}</div>
          )}
          <div style={{ display: "inline-block", verticalAlign: "middle" }}>
            <Field l="Score" v={r.score != null ? r.score + " pts" : null} />
            <Field l={r.source === "NYS DOH" ? "Type" : "Cuisine"} v={r.cuisine} />
            <Field l="Last inspected" v={r.latest_inspection} />
            {r.critical_violations != null && (r.critical_violations > 0 || r.noncritical_violations > 0) && (
              <Field l="Violations" v={<span><span style={{ color: "#b91c1c", fontWeight: 600 }}>{r.critical_violations} critical</span> · {r.noncritical_violations} non-critical</span>} />
            )}
          </div>
          {viols.length > 0 && (
            <div style={{ marginTop: 10 }}>
              <Subsec>Recent violations</Subsec>
              <ul style={{ listStyle: "none", padding: 0, margin: "0 14px", fontSize: "var(--fs-base)" }}>
                {viols.map((v, i) => (
                  <li key={i} style={{ marginBottom: 4 }}>
                    <span style={{ color: "var(--fg-3)", fontFamily: "var(--font-mono)", fontSize: "var(--fs-sm)" }}>{v.date || ""}{v.code ? " · " + v.code : ""}{v.critical === "Critical" ? <span style={{ color: "#b91c1c", fontWeight: 600 }}> · Critical</span> : ""}</span>
                    <br />
                    <span style={{ color: "var(--fg-2)" }}>{v.desc || ""}</span>
                  </li>
                ))}
              </ul>
            </div>
          )}
        </div>
      </Panel>
    );
  };

  // 2. Government contracts — NYS Procurement (renderDossierGovContracts).
  // RPC org_gov_contracts → rows of { side, counterparty, contract_amount,
  // type_of_procurement, award_date, mwbe }.
  window.CrmPanels.govcontracts = function GovContracts({ orgId }) {
    const rows = usePanelData(rpcLoad("org_gov_contracts"), orgId);
    if (!rows || !rows.length) return null;
    const totalVendor = rows.filter((r) => r.side === "vendor").reduce((s, r) => s + Number(r.contract_amount || 0), 0);
    const totalBuyer = rows.filter((r) => r.side === "buyer").reduce((s, r) => s + Number(r.contract_amount || 0), 0);
    const vendorCount = rows.filter((r) => r.side === "vendor").length;
    const buyerCount = rows.filter((r) => r.side === "buyer").length;
    const mwbeRows = rows.filter((r) => r.mwbe === "Y").length;
    const summary = [];
    if (vendorCount) summary.push(<Flag key="v" bg="#dcfce7" color="#166534">{"As vendor: " + vendorCount + " contracts · " + money(totalVendor)}</Flag>);
    if (buyerCount) summary.push(<Flag key="b" bg="#e0e7ff" color="#3730a3">{"As buyer: " + buyerCount + " contracts · " + money(totalBuyer)}</Flag>);
    if (mwbeRows) summary.push(<Flag key="m" bg="#fef3c7" color="#92400e">{mwbeRows + " MWBE"}</Flag>);
    return (
      <Panel title="Government contracts" badge={<SrcBadge bg="#dcfce7" color="#166534">NYS Procurement</SrcBadge>} count={rows.length}>
        {summary.length > 0 && <div style={{ padding: "10px 16px 0", display: "flex", gap: 6, flexWrap: "wrap" }}>{summary}</div>}
        <div className="reg-panel">
          {rows.slice(0, 12).map((r, i) => (
            <RegRow key={i} badge={r.side} badgeBg={r.side === "vendor" ? "#166534" : "#3730a3"}
              title={r.counterparty || "—"}
              fact={[r.type_of_procurement, r.award_date].filter(Boolean).join(" · ")}
              right={money(r.contract_amount)} />
          ))}
        </div>
        <div style={{ padding: "0 14px 12px" }}><Note>NYS procurement contracts — vendor &amp; buyer side.</Note></div>
      </Panel>
    );
  };

  // 3. Government org info — health facility / NYC agency / public authority +
  // workforce/payroll (renderDossierGovExtras). RPC org_gov_data_extras →
  // rows[0] = { agency_info{}, authority_info{}, health_facility{},
  // payroll_summary{ source, distinct_employees, total_rows, fy_min, fy_max,
  // avg_base, top_titles:[{title, n}] } }. The map renders gov-info + workforce
  // as two sub-panels; combined here into one panel with a Workforce subsection.
  window.CrmPanels.govextras = function GovExtras({ orgId }) {
    const rows = usePanelData(rpcLoad("org_gov_data_extras"), orgId);
    if (rows === undefined) return null;
    const r = (Array.isArray(rows) ? rows[0] : rows) || {};
    // ── Gov org info fields ──
    let infoTitle = null;
    const fields = [];
    if (r.agency_info) {
      const a = r.agency_info; infoTitle = "NYC Agency";
      if (a.acronym) fields.push(<Field key="ac" l="Acronym" v={a.acronym} mono />);
      if (a.type) fields.push(<Field key="ty" l="Org type" v={a.type} />);
      if (a.principal_name) fields.push(<Field key="pr" l={a.principal_title || "Principal"} v={a.principal_name} />);
      if (a.reports_to) fields.push(<Field key="rt" l="Reports to" v={a.reports_to} />);
      if (a.url) fields.push(<Field key="ur" l="Website" v={<a href={a.url} target="_blank" rel="noreferrer">{a.url}</a>} />);
    } else if (r.authority_info) {
      const a = r.authority_info; infoTitle = "NYS Public Authority";
      if (a.type) fields.push(<Field key="ty" l="Authority type" v={<Flag bg="#f1f5f9" color="#475569">{a.type}</Flag>} />);
      if (a.address) fields.push(<Field key="ad" l="HQ address" v={a.address} />);
      if (a.website) fields.push(<Field key="we" l="Website" v={<a href={a.website} target="_blank" rel="noreferrer">{a.website}</a>} />);
    } else if (r.health_facility) {
      const h = r.health_facility; infoTitle = "Health facility";
      if (h.type) fields.push(<Field key="ty" l="Type" v={h.type + (h.description ? " — " + h.description : "")} />);
      if (h.opcert || h.cert) fields.push(<Field key="oc" l="Operating certificate" v={h.opcert || h.cert} mono />);
      if (h.ownership) fields.push(<Field key="ow" l="Ownership" v={h.ownership} />);
      if (h.operator) fields.push(<Field key="op" l="Operator" v={h.operator} />);
      if (h.county) fields.push(<Field key="co" l="County" v={h.county} />);
      if (h.beds != null) fields.push(<Field key="be" l="Beds (total)" v={String(h.beds)} />);
      if (h.alp_beds) fields.push(<Field key="ap" l="ALP beds" v={String(h.alp_beds)} />);
      if (h.alr_beds) fields.push(<Field key="ar" l="ALR beds" v={String(h.alr_beds)} />);
      if (h.classification) fields.push(<Field key="cl" l="Classification" v={h.classification} />);
    }
    // ── Workforce / payroll ──
    const p = r.payroll_summary;
    const pf = [];
    if (p) {
      if (p.distinct_employees) pf.push(<Field key="de" l="Distinct employees" v={num(p.distinct_employees)} />);
      if (p.total_rows) pf.push(<Field key="tr" l="Pay records" v={num(p.total_rows) + (p.fy_min ? " (FY " + p.fy_min + "–" + p.fy_max + ")" : "")} />);
      if (p.avg_base != null) pf.push(<Field key="ab" l="Avg base salary" v={money(p.avg_base)} />);
      if (p.top_titles && Array.isArray(p.top_titles) && p.top_titles.length) {
        pf.push(<Field key="tt" l="Top titles" v={
          <ul style={{ listStyle: "none", padding: 0, margin: 0, fontSize: "var(--fs-base)" }}>
            {p.top_titles.map((t, i) => (
              <li key={i} style={{ marginBottom: 2 }}><span style={{ color: "var(--fg-2)" }}>{t.title || ""}</span> <span style={{ color: "var(--fg-3)", fontFamily: "var(--font-mono)", fontSize: "var(--fs-sm)" }}>· {num(t.n || 0)}</span></li>
            ))}
          </ul>
        } />);
      }
    }
    if (!fields.length && !pf.length) return null;
    return (
      <Panel title="Government org info" badge={<SrcBadge bg="#dcfce7" color="#166534">{(p && p.source) || "NYC · NYS"}</SrcBadge>}>
        <div style={{ padding: "6px 16px 14px" }}>
          {fields.length > 0 && infoTitle && infoTitle !== "Government org info" && <Subsec>{infoTitle}</Subsec>}
          {fields}
          {pf.length > 0 && (
            <>
              <Subsec>Workforce{(p && p.source) ? " · " + p.source : ""}</Subsec>
              {pf}
            </>
          )}
        </div>
      </Panel>
    );
  };

  // 4. Real estate events — SEC 8-K / WARN-derived location events
  // (renderDossierReEvents). RPC org_real_estate_events →
  // { events:[{ event_type, source, event_date, address, city, state, zip,
  // space_sqft, job_count, source_url }] }.
  window.CrmPanels.reevents = function ReEvents({ orgId }) {
    const d = usePanelData(rpcLoad("org_real_estate_events"), orgId);
    const ev = (d && d.events) || [];
    if (!ev.length) return null;
    return (
      <Panel title="Real estate events" badge={<SrcBadge bg="#fde68a" color="#92400e">SEC 8-K · WARN</SrcBadge>} count={ev.length}>
        <div className="reg-panel">
          {ev.slice(0, 10).map((e, i) => {
            const addr = [e.address, e.city, e.state, e.zip].filter(Boolean).join(", ");
            const facts = [
              addr || null,
              e.space_sqft != null ? num(e.space_sqft) + " sqft" : null,
              e.job_count != null ? num(e.job_count) + " jobs" : null,
            ].filter(Boolean).join(" · ");
            return (
              <RegRow key={i} badge={e.event_type || "Event"} badgeBg="#92400e"
                title={<>{e.event_type || "Event"}{e.source_url && <> · <a href={e.source_url} target="_blank" rel="noreferrer" style={{ color: "var(--accent)" }}>link →</a></>}</>}
                fact={facts}
                right={[e.source || "", fmtDate(e.event_date)].filter(Boolean).join(" · ")} />
            );
          })}
        </div>
        <div style={{ padding: "0 14px 12px" }}><Note>Location events derived from SEC 8-K filings and WARN notices.</Note></div>
      </Panel>
    );
  };

  // 5. Franchise activity — franchisor brands + franchisee locations
  // (renderDossierFranchise). RPC org_franchise_activity →
  // { franchisor_brands:[{brand_name, sba_code, meets_ftc_franchise, start_date}],
  // franchisor_location_count, franchisee_of:[{brand_name, location_count,
  // sba_code, sample_address}], franchisee_total_locations }.
  window.CrmPanels.franchise = function Franchise({ orgId }) {
    const d = usePanelData(rpcLoad("org_franchise_activity"), orgId);
    if (!d) return null;
    const brands = d.franchisor_brands || [];
    const brandLocs = Number(d.franchisor_location_count || 0);
    const operatedBrands = d.franchisee_of || [];
    const operatedTotal = Number(d.franchisee_total_locations || 0);
    if (!brands.length && !operatedBrands.length) return null;
    return (
      <Panel title="Franchise activity" badge={<SrcBadge bg="#fef3c7" color="#92400e">SBA Franchise</SrcBadge>} count={brands.length + operatedBrands.length}>
        {brands.length > 0 && (
          <>
            <Subsec>Franchisor of {brands.length} brand{brands.length > 1 ? "s" : ""}{brandLocs ? " · " + brandLocs + " FL locations" : ""}</Subsec>
            <div className="reg-panel">
              {brands.map((b, i) => (
                <RegRow key={i} badge="SBA" badgeBg="#92400e"
                  title={b.brand_name || ""}
                  fact={[
                    b.sba_code ? "SBA " + b.sba_code : null,
                    b.meets_ftc_franchise === "Y" ? "FTC franchise" : (b.meets_ftc_franchise === "N" ? "not FTC franchise" : null),
                    b.start_date ? "approved " + fmtDate(b.start_date) : null,
                  ].filter(Boolean).join(" · ")} />
              ))}
            </div>
          </>
        )}
        {operatedBrands.length > 0 && (
          <>
            <Subsec>Operates {operatedTotal} franchise location{operatedTotal > 1 ? "s" : ""} · franchisee of {operatedBrands.length} brand{operatedBrands.length > 1 ? "s" : ""}</Subsec>
            <div className="reg-panel">
              {operatedBrands.map((o, i) => (
                <RegRow key={i} badge={o.location_count} badgeBg="#0e7c66"
                  title={o.brand_name || ""}
                  fact={[
                    o.location_count + " FL location" + (o.location_count > 1 ? "s" : ""),
                    o.sba_code ? "SBA " + o.sba_code : null,
                    o.sample_address ? "e.g. " + o.sample_address : null,
                  ].filter(Boolean).join(" · ")} />
              ))}
            </div>
          </>
        )}
        <div style={{ padding: "0 14px 12px" }}><Note>SBA Franchise Directory — franchisor brands &amp; franchisee locations.</Note></div>
      </Panel>
    );
  };

  // 6. Global ownership (LEI) — GLEIF parent/subsidiary chain
  // (renderDossierCorporateHierarchy). RPC org_corporate_hierarchy →
  // { self:{lei, legal_name, legal_form, legal_jurisdiction, hq_address_city,
  // hq_address_country}, direct_parent{}, ultimate_parent{}, direct_subsidiaries:[],
  // fund_managed_funds:[], subsidiary_count }.
  window.CrmPanels.corphier = function CorpHier({ orgId }) {
    const d = usePanelData(rpcLoad("org_corporate_hierarchy"), orgId);
    if (!d || !d.self) return null;
    const self = d.self;
    const direct = d.direct_parent;
    const ultimate = d.ultimate_parent;
    const subs = d.direct_subsidiaries || [];
    const funds = d.fund_managed_funds || [];
    const subCount = Number(d.subsidiary_count || 0);
    const entRow = (e, badge, i) => (
      <RegRow key={badge + i} badge="LEI" badgeBg="#5b21b6"
        title={e.legal_name || ""}
        fact={[
          e.lei ? "LEI " + e.lei : null,
          e.jurisdiction || null,
          [e.hq_city, e.hq_country].filter(Boolean).join(", ") || null,
        ].filter(Boolean).join(" · ")} />
    );
    return (
      <Panel title="Global ownership (LEI)" badge={<SrcBadge bg="#ede9fe" color="#5b21b6">GLEIF</SrcBadge>}>
        <div style={{ padding: "6px 16px 4px" }}>
          <Field l="Legal name" v={self.legal_name} />
          <Field l="LEI" v={self.lei} mono />
          <Field l="Legal form" v={self.legal_form} />
          <Field l="Jurisdiction" v={self.legal_jurisdiction} />
          <Field l="HQ" v={[self.hq_address_city, self.hq_address_country].filter(Boolean).join(", ") || null} />
        </div>
        {ultimate && (
          <>
            <Subsec>Ultimate parent</Subsec>
            <div className="reg-panel">{entRow(ultimate, "u", 0)}</div>
          </>
        )}
        {direct && (!ultimate || direct.lei !== ultimate.lei) && (
          <>
            <Subsec>Direct parent</Subsec>
            <div className="reg-panel">{entRow(direct, "d", 0)}</div>
          </>
        )}
        {subs.length > 0 && (
          <>
            <Subsec>Direct subsidiaries ({subCount}){subs.length < subCount ? " · showing " + subs.length : ""}</Subsec>
            <div className="reg-panel">{subs.map((c, i) => entRow(c, "s", i))}</div>
          </>
        )}
        {funds.length > 0 && (
          <>
            <Subsec>Manages {funds.length} fund{funds.length > 1 ? "s" : ""}</Subsec>
            <div className="reg-panel">{funds.map((f, i) => entRow(f, "f", i))}</div>
          </>
        )}
        <div style={{ padding: "0 14px 12px" }}><Note>GLEIF (Global LEI Foundation) corporate-ownership relationships.</Note></div>
      </Panel>
    );
  };

  // 7. Lobbying — Senate LDA (renderDossierLobbying). RPC org_lobbying_detail →
  // { as_registrant:{ total_income, clients, filings, year_from, year_to,
  // top_issues:[{issue, n}], top_clients:[{client, income, filings, latest}] },
  // as_client:{ total_spend, registrants, filings, year_from, year_to,
  // top_registrants:[{registrant, amount, filings, latest}] } }.
  window.CrmPanels.lobbying = function Lobbying({ orgId }) {
    const d = usePanelData(rpcLoad("org_lobbying_detail"), orgId);
    const reg = d && d.as_registrant;
    const cli = d && d.as_client;
    if (!reg && !cli) return null;
    const usd = (n) => {
      n = Number(n) || 0;
      if (n >= 1e6) return "$" + (n / 1e6).toFixed(n >= 1e7 ? 0 : 1) + "M";
      if (n >= 1e3) return "$" + Math.round(n / 1e3) + "K";
      return "$" + n.toLocaleString();
    };
    const yrs = (o) => (o.year_from && o.year_to) ? (o.year_from === o.year_to ? String(o.year_from) : o.year_from + "–" + o.year_to) : "";
    return (
      <Panel title="Lobbying" badge={<SrcBadge bg="#e0e7ff" color="#3730a3">Senate LDA</SrcBadge>}>
        {reg && (
          <>
            <Subsec>As registrant — this firm's lobbying</Subsec>
            <div style={{ padding: "0 16px 4px", display: "flex", gap: 6, flexWrap: "wrap" }}>
              <Flag bg="#e0e7ff" color="#3730a3">{usd(reg.total_income) + " income"}</Flag>
              {reg.clients != null && <Flag bg="#eef2ff" color="#3730a3">{reg.clients + " clients"}</Flag>}
              {reg.filings != null && <Flag bg="#f1f5f9" color="#475569">{reg.filings + " filings" + (yrs(reg) ? " · " + yrs(reg) : "")}</Flag>}
            </div>
            {(reg.top_issues || []).length > 0 && (
              <div style={{ padding: "6px 16px 0", display: "flex", gap: 4, flexWrap: "wrap" }}>
                {(reg.top_issues || []).slice(0, 10).map((iss, i) => (
                  <Flag key={i} bg="#FAEEDA" color="#633806">{iss.issue}<span style={{ opacity: 0.55 }}> {iss.n}</span></Flag>
                ))}
              </div>
            )}
            <div className="reg-panel">
              {(reg.top_clients || []).map((x, i) => (
                <RegRow key={i} title={x.client || ""}
                  fact={[usd(x.income), x.filings != null ? x.filings + "× filings" : null, x.latest].filter(Boolean).join(" · ")} />
              ))}
            </div>
          </>
        )}
        {cli && (
          <>
            <Subsec>As client — lobbying it commissioned</Subsec>
            <div style={{ padding: "0 16px 4px" }}>
              <Field l="Spend" v={usd(cli.total_spend) + " · " + cli.registrants + " firm" + (cli.registrants === 1 ? "" : "s") + " · " + cli.filings + " filings" + (yrs(cli) ? " · " + yrs(cli) : "")} />
            </div>
            <div className="reg-panel">
              {(cli.top_registrants || []).slice(0, 15).map((x, i) => (
                <RegRow key={i} title={x.registrant || ""}
                  fact={[usd(x.amount), x.filings != null ? x.filings + "× filings" : null, x.latest].filter(Boolean).join(" · ")} />
              ))}
            </div>
          </>
        )}
        <div style={{ padding: "0 14px 12px" }}><Note>U.S. Senate Lobbying Disclosure Act filings.</Note></div>
      </Panel>
    );
  };
})();
