/* Dashboard - funder's cockpit. KPIs, top priorities, needs-attention,
   milestones slipping, funding gaps, upcoming events. Exports: Dashboard. */

function KpiCard({ icon, label, value, sub, accent, onClick }) {
  return (
    <button className="card focusable" onClick={onClick} style={{ padding: 24, textAlign: "left", cursor: onClick ? "pointer" : "default", background: "var(--surface)", display: "block" }}>
      <div style={{ display: "flex", alignItems: "center", justifyContent: "space-between", marginBottom: 18 }}>
        <div style={{ width: 46, height: 46, borderRadius: 14, display: "grid", placeItems: "center", background: accent ? "var(--accent-soft)" : "var(--surface-3)", color: accent ? "var(--accent)" : "var(--text-muted)" }}><Icon name={icon} size={22} /></div>
        {onClick && <Icon name="arrowRight" size={16} style={{ color: "var(--text-faint)" }} />}
      </div>
      <div className="mono" style={{ fontSize: 38, fontWeight: 600, letterSpacing: "-0.03em", lineHeight: 1 }}>{value}</div>
      <div style={{ fontSize: 14, color: "var(--text-muted)", marginTop: 9 }}>{label}</div>
      {sub && <div style={{ fontSize: 12.5, color: "var(--text-faint)", marginTop: 3 }}>{sub}</div>}
    </button>
  );
}

function Panel({ title, icon, iconColor, right, children }) {
  return (
    <div className="card" style={{ padding: 24 }}>
      <div style={{ display: "flex", alignItems: "center", gap: 9, marginBottom: 18 }}>
        {icon && <Icon name={icon} size={18} style={{ color: iconColor || "var(--text-muted)" }} />}
        <div style={{ fontWeight: 650, fontSize: 16.5 }}>{title}</div>
        <div style={{ marginLeft: "auto" }}>{right}</div>
      </div>
      {children}
    </div>
  );
}

function RowItem({ left, title, sub, right, onClick }) {
  return (
    <button className="focusable" onClick={onClick} style={{ display: "flex", alignItems: "center", gap: 12, width: "100%", padding: "12px 13px", borderRadius: 13, border: "1px solid var(--border)", background: "var(--surface-2)", cursor: "pointer", textAlign: "left", marginBottom: 9 }}>
      {left}
      <div style={{ flex: 1, minWidth: 0 }}>
        <div style={{ fontSize: 14.5, fontWeight: 600, whiteSpace: "nowrap", overflow: "hidden", textOverflow: "ellipsis" }}>{title}</div>
        {sub && <div style={{ fontSize: 12.5, color: "var(--text-muted)", whiteSpace: "nowrap", overflow: "hidden", textOverflow: "ellipsis" }}>{sub}</div>}
      </div>
      {right}
    </button>
  );
}

function Dashboard({ onOpen, onNavigate, userName, recents = [] }) {
  const D = window.DATA;
  const band = window.scoreBand || (() => ({ c: "var(--accent)" }));
  const fundedPct = Math.round((D.counts.funded / D.counts.orgs) * 100);
  const ranked = D.priorityRanked();
  const needs = D.orgs.filter((o) => o.priority === "need" || (o.relationship === "Prospect" && D.orgGap(o) > 0))
    .sort((a, b) => D.orgGap(b) - D.orgGap(a)).slice(0, 4);
  const slipping = D.orgs.filter((o) => D.milestoneHealth(o.id).verdict === "behind").slice(0, 4);
  const topPriorities = ranked.slice(0, 5);
  const upcoming = [...D.events].sort((a, b) => new Date(a.date) - new Date(b.date))
    .filter((e) => new Date(e.date) >= new Date("2026-01-01")).slice(0, 4);
  const fmtMoney = D.fmtMoney;

  // recently viewed people - start from real recents, pad with notable contacts
  const recentPeople = recents.map((id) => D.byId[id]).filter((e) => e && D.kindOf(e.id) === "person");
  const padPool = [...D.people].sort((a, b) => (b.photo ? 1 : 0) - (a.photo ? 1 : 0));
  const seenP = new Set(recentPeople.map((p) => p.id));
  for (const p of padPool) { if (recentPeople.length >= 6) break; if (!seenP.has(p.id)) { recentPeople.push(p); seenP.add(p.id); } }
  const peopleStrip = recentPeople.slice(0, 6);

  // recently viewed records (mixed) for a compact list
  const recentRecords = recents.map((id) => D.byId[id]).filter(Boolean).slice(0, 5);

  const totalAwarded = D.orgs.reduce((s, o) => s + (o.funding ? o.funding.awarded : 0), 0);

  // AI prioritisation insights - surfaced from the scoring framework, link into Open Prioritisation
  const dimTop = (key, pool) => [...pool].sort((a, b) => (b.scores[key] || 0) - (a.scores[key] || 0))[0];
  const unfunded = D.orgs.filter((o) => !o.funded);
  const withGap = D.orgs.filter((o) => D.orgGap(o) > 0);
  const fundNext = D.priorityRanked().filter((o) => !o.funded)[0] || D.priorityRanked()[0];
  const insights = [
    { key: "neglect", icon: "signal", c: "var(--accent)", label: "Neglected by other funders",
      blurb: "Backed by few others - your support would go furthest here.", org: dimTop("neglect", unfunded.length ? unfunded : D.orgs) },
    { key: "impact", icon: "trendingUp", c: "var(--good)", label: "Outsized impact potential",
      blurb: "Highest modelled reach per pound across the ecosystem.", org: dimTop("impact", D.orgs) },
    { key: "readiness", icon: "funding", c: "var(--info, var(--accent))", label: "Ready to absorb funding",
      blurb: "Strong delivery capacity and an open ask on the table.", org: dimTop("readiness", withGap.length ? withGap : D.orgs) },
  ];

  return (
    <div style={{ position: "absolute", inset: 0, overflow: "auto", background: "var(--bg)" }}>
      <div style={{ width: "100%", margin: "0 auto", padding: "36px 44px 72px" }}>
        {/* greeting */}
        <div style={{ marginBottom: 26, display: "flex", alignItems: "flex-end", justifyContent: "space-between", gap: 16, flexWrap: "wrap" }}>
          <div>
            <div className="t-eyebrow" style={{ marginBottom: 8 }}>{new Date().toLocaleDateString("en-GB", { weekday: "long", day: "numeric", month: "long" })}</div>
            <div className="display" style={{ fontSize: 42 }}>Good morning, {userName.split(" ")[0]}</div>
            <div style={{ fontSize: 16.5, color: "var(--text-muted)", marginTop: 10 }}>Here's where your attention is needed across the ecosystem.</div>
          </div>
          <div style={{ display: "flex", gap: 10 }}>
            <button className="btn" onClick={() => onNavigate("map")}><Icon name="map" size={17} /> Open map</button>
            <button className="btn btn-primary" onClick={() => onNavigate("prioritise")}><Icon name="target" size={17} /> Open prioritisation</button>
          </div>
        </div>

        {/* KPIs */}
        <div style={{ display: "grid", gridTemplateColumns: "repeat(4, 1fr)", gap: 18, marginBottom: 20 }}>
          <KpiCard icon="building" label="Organisations" value={D.counts.orgs} sub={`${D.counts.funded} funded · ${fundedPct}%`} accent onClick={() => onNavigate("orgs")} />
          <KpiCard icon="funding" label="Total committed" value={fmtMoney(totalAwarded)} sub={`${fmtMoney(D.totalGap())} open gap`} onClick={() => onNavigate("prioritise")} />
          <KpiCard icon="target" label="High-need prospects" value={D.orgs.filter((o) => o.priority === "need").length} sub="flagged for review" onClick={() => onNavigate("prioritise")} />
          <KpiCard icon="folder" label="Active projects" value={D.projects.filter((p) => p.status === "Active").length} sub={`${D.counts.projects} total`} onClick={() => onNavigate("projects")} />
        </div>

        {/* recently viewed people */}
        <div className="card" style={{ padding: "18px 22px", marginBottom: 20 }}>
          <div style={{ display: "flex", alignItems: "center", gap: 9, marginBottom: 15 }}>
            <Icon name="clock" size={17} style={{ color: "var(--text-muted)" }} />
            <div style={{ fontWeight: 650, fontSize: 15.5 }}>Recently viewed people</div>
            <div style={{ marginLeft: "auto" }}><button className="btn btn-sm btn-ghost" style={{ color: "var(--accent)" }} onClick={() => onNavigate("directory")}>All people <Icon name="arrowRight" size={14} /></button></div>
          </div>
          <div style={{ display: "grid", gridTemplateColumns: "repeat(6, 1fr)", gap: 12 }}>
            {peopleStrip.map((p) => {
              const org = p.org ? D.byId[p.org] : null;
              return (
                <button key={p.id} className="focusable" onClick={() => onOpen(p.id)}
                  style={{ display: "flex", flexDirection: "column", alignItems: "center", gap: 9, padding: "16px 12px", borderRadius: 14, border: "1px solid var(--border)", background: "var(--surface-2)", cursor: "pointer", textAlign: "center" }}>
                  {p.photo ? <Portrait p={p} w={56} h={56} radius={999} /> : <Avatar name={p.name} size={56} accent={p.team} />}
                  <div style={{ minWidth: 0, width: "100%" }}>
                    <div style={{ fontSize: 13.5, fontWeight: 600, whiteSpace: "nowrap", overflow: "hidden", textOverflow: "ellipsis" }}>{p.name}</div>
                    <div style={{ fontSize: 11.5, color: "var(--text-muted)", whiteSpace: "nowrap", overflow: "hidden", textOverflow: "ellipsis" }}>{p.title}</div>
                    <div style={{ fontSize: 11, color: "var(--text-faint)", whiteSpace: "nowrap", overflow: "hidden", textOverflow: "ellipsis", marginTop: 2 }}>{org ? org.name : p.team ? "Wellspring Fund" : "Independent"}</div>
                  </div>
                </button>
              );
            })}
          </div>
        </div>

        {/* AI prioritisation insights */}
        <div style={{ marginBottom: 20 }}>
          <div style={{ display: "flex", alignItems: "center", gap: 9, marginBottom: 13 }}>
            <span style={{ width: 26, height: 26, borderRadius: 8, display: "grid", placeItems: "center", background: "var(--accent-soft)", color: "var(--accent)" }}><Icon name="spark" size={15} /></span>
            <div style={{ fontWeight: 650, fontSize: 15.5 }}>AI prioritisation insights</div>
            <span className="badge" style={{ background: "var(--accent-soft)", color: "var(--accent)", borderColor: "transparent" }}>NeuroAI</span>
            <div style={{ marginLeft: "auto" }}><button className="btn btn-sm btn-ghost" style={{ color: "var(--accent)" }} onClick={() => onNavigate("prioritise")}>Open prioritisation <Icon name="arrowRight" size={14} /></button></div>
          </div>
          <div style={{ display: "grid", gridTemplateColumns: "repeat(3, 1fr)", gap: 18 }}>
            {insights.map((ins) => {
              if (!ins.org) return null;
              const score10 = ins.org.scores[ins.key] || 0;
              return (
                <button key={ins.key} className="card focusable" onClick={() => onNavigate("prioritise")}
                  style={{ padding: 20, textAlign: "left", cursor: "pointer", background: "var(--surface)", display: "flex", flexDirection: "column", gap: 14 }}>
                  <div style={{ display: "flex", alignItems: "center", gap: 10 }}>
                    <span style={{ width: 36, height: 36, flex: "none", borderRadius: 10, display: "grid", placeItems: "center", background: "var(--surface-3)", color: ins.c }}><Icon name={ins.icon} size={18} /></span>
                    <div style={{ flex: 1, minWidth: 0 }}>
                      <div style={{ fontSize: 14, fontWeight: 650 }}>{ins.label}</div>
                      <div className="t-eyebrow" style={{ marginTop: 1 }}>Framework signal</div>
                    </div>
                    <div style={{ textAlign: "right" }}>
                      <div className="mono" style={{ fontSize: 22, fontWeight: 600, lineHeight: 1, color: ins.c }}>{score10.toFixed(1)}</div>
                      <div style={{ fontSize: 10, color: "var(--text-faint)" }}>/ 10</div>
                    </div>
                  </div>
                  <div style={{ fontSize: 12.5, color: "var(--text-muted)", lineHeight: 1.5 }}>{ins.blurb}</div>
                  {/* score bar */}
                  <div style={{ height: 6, borderRadius: 5, background: "var(--surface-3)", overflow: "hidden" }}>
                    <div style={{ width: (score10 * 10) + "%", height: "100%", background: ins.c, borderRadius: 5 }} />
                  </div>
                  {/* the org it points to */}
                  <div onClick={(ev) => { ev.stopPropagation(); onOpen(ins.org.id); }}
                    style={{ display: "flex", alignItems: "center", gap: 9, padding: "9px 11px", borderRadius: 10, border: "1px solid var(--border)", background: "var(--surface-2)" }}>
                    <span style={{ width: 8, height: 8, borderRadius: 999, background: domainColor(ins.org.domain), flex: "none" }} />
                    <div style={{ flex: 1, minWidth: 0 }}>
                      <div style={{ fontSize: 13, fontWeight: 600, whiteSpace: "nowrap", overflow: "hidden", textOverflow: "ellipsis" }}>{ins.org.name}</div>
                      <div style={{ fontSize: 11, color: "var(--text-muted)" }}>{ins.org.funded ? "Funded" : "Unfunded"} · gap {fmtMoney(D.orgGap(ins.org))}</div>
                    </div>
                    <span className="badge mono" style={{ flex: "none" }}>{ins.org.priorityScore}</span>
                  </div>
                </button>
              );
            })}
          </div>
        </div>

        <div style={{ display: "grid", gridTemplateColumns: "repeat(3, minmax(0, 1fr))", gap: 20, alignItems: "start" }}>
          {/* col A */}
          <div style={{ display: "flex", flexDirection: "column", gap: 20 }}>
            {/* top priorities */}
            <Panel title="Top priorities" icon="target" iconColor="var(--accent)" right={<button className="btn btn-sm btn-ghost" style={{ color: "var(--accent)" }} onClick={() => onNavigate("prioritise")}>Full leaderboard <Icon name="arrowRight" size={14} /></button>}>
              {topPriorities.map((o, i) => {
                const b = band(o.priorityScore);
                return (
                  <RowItem key={o.id} onClick={() => onOpen(o.id)}
                    left={<span className="mono" style={{ width: 18, textAlign: "center", fontSize: 12, fontWeight: 600, color: "var(--text-faint)" }}>{i + 1}</span>}
                    title={<span style={{ display: "inline-flex", alignItems: "center", gap: 7 }}><span style={{ width: 7, height: 7, borderRadius: 999, background: domainColor(o.domain) }} />{o.name}</span>}
                    sub={`${o.relationship} · ${o.geography}`}
                    right={<span style={{ display: "flex", alignItems: "center", gap: 9 }}>
                      <span style={{ width: 60, height: 6, borderRadius: 5, background: "var(--surface-3)", overflow: "hidden" }}><span style={{ display: "block", width: o.priorityScore + "%", height: "100%", background: b.c }} /></span>
                      <span className="mono" style={{ fontSize: 13, fontWeight: 700, color: b.c, width: 24, textAlign: "right" }}>{o.priorityScore}</span>
                    </span>} />
                );
              })}
            </Panel>

            {/* domain distribution */}
            <Panel title="Ecosystem by domain" icon="grid" right={<button className="btn btn-sm btn-ghost" style={{ color: "var(--accent)" }} onClick={() => onNavigate("initiatives")}>Initiatives <Icon name="arrowRight" size={14} /></button>}>
              <div style={{ display: "flex", flexDirection: "column", gap: 11 }}>
                {D.domains.map((d) => {
                  const list = D.orgs.filter((o) => o.domain === d.id);
                  const funded = list.filter((o) => o.funded).length;
                  const maxN = Math.max(...D.domains.map((x) => D.orgs.filter((o) => o.domain === x.id).length));
                  return (
                    <div key={d.id} style={{ display: "flex", alignItems: "center", gap: 12 }}>
                      <div style={{ width: 120, flex: "none", display: "flex", alignItems: "center", gap: 7, fontSize: 12.5, color: "var(--text-muted)" }}><span style={{ width: 8, height: 8, borderRadius: 999, background: domainColor(d.id) }} />{d.label}</div>
                      <div style={{ flex: 1, height: 9, borderRadius: 5, background: "var(--surface-3)", overflow: "hidden", display: "flex" }}>
                        <div style={{ width: `${(funded / maxN) * 100}%`, background: domainColor(d.id), borderRadius: 5 }} />
                      </div>
                      <div className="mono" style={{ width: 50, textAlign: "right", fontSize: 12, color: "var(--text-muted)" }}>{funded}/{list.length}</div>
                    </div>
                  );
                })}
              </div>
            </Panel>
          </div>

          {/* col B */}
          <div style={{ display: "flex", flexDirection: "column", gap: 20 }}>
            <Panel title="Needs attention" icon="target" iconColor="var(--rose)">
              {needs.map((o) => (
                <RowItem key={o.id} onClick={() => onOpen(o.id)}
                  left={<span style={{ width: 8, height: 8, borderRadius: 999, background: o.priority === "need" ? "var(--rose)" : "var(--warn)", flex: "none" }} />}
                  title={o.name} sub={`${o.priority === "need" ? "High need" : "Prospect"} · gap ${fmtMoney(D.orgGap(o))}`}
                  right={<Icon name="chevronRight" size={15} style={{ color: "var(--text-faint)" }} />} />
              ))}
            </Panel>

            <Panel title="Milestones slipping" icon="bolt" iconColor="var(--warn)">
              {slipping.length ? slipping.map((o) => {
                const mh = D.milestoneHealth(o.id);
                return <RowItem key={o.id} onClick={() => onOpen(o.id)}
                  left={<span style={{ width: 8, height: 8, borderRadius: 999, background: "var(--warn)", flex: "none" }} />}
                  title={o.name} sub={`${mh.behind} behind · ${mh.met}/${mh.total} met`}
                  right={<Icon name="chevronRight" size={15} style={{ color: "var(--text-faint)" }} />} />;
              }) : <div style={{ fontSize: 13, color: "var(--text-faint)" }}>All grantees on track.</div>}
            </Panel>
          </div>

          {/* col C */}
          <div style={{ display: "flex", flexDirection: "column", gap: 20 }}>
            <Panel title="Upcoming events" icon="calendar" right={<button className="btn btn-sm btn-ghost" style={{ color: "var(--accent)" }} onClick={() => onNavigate("events")}>All</button>}>
              {upcoming.length ? upcoming.map((ev) => {
                const d = new Date(ev.date);
                return <RowItem key={ev.id} onClick={() => onOpen(ev.id)}
                  left={<div style={{ width: 36, flex: "none", textAlign: "center", padding: "4px 0", borderRadius: 8, background: "var(--surface-3)" }}><div className="mono" style={{ fontSize: 14, fontWeight: 600, lineHeight: 1 }}>{d.getDate()}</div><div style={{ fontSize: 9.5, color: "var(--text-muted)", textTransform: "uppercase" }}>{d.toLocaleDateString("en-GB", { month: "short" })}</div></div>}
                  title={ev.name} sub={`${(ev.orgs || []).length} orgs · ${(ev.attendees || []).length} attendees`}
                  right={<Icon name="chevronRight" size={15} style={{ color: "var(--text-faint)" }} />} />;
              }) : <div style={{ fontSize: 13, color: "var(--text-faint)" }}>No upcoming events.</div>}
            </Panel>

            <TasksWidget onNavigate={onNavigate} onOpen={onOpen} />

            {recentRecords.length > 0 && <Panel title="Jump back in" icon="history">
              {recentRecords.map((e) => {
                const k = D.kindOf(e.id);
                return <RowItem key={e.id} onClick={() => onOpen(e.id)}
                  left={k === "person"
                    ? (e.photo ? <Portrait p={e} w={30} h={30} radius={999} /> : <Avatar name={e.name} size={30} accent={e.team} />)
                    : <span style={{ width: 30, height: 30, flex: "none", borderRadius: 8, display: "grid", placeItems: "center", background: "var(--surface-3)", color: "var(--text-muted)" }}><Icon name={(KIND_META[k] || KIND_META.org).icon} size={15} /></span>}
                  title={e.name} sub={(KIND_META[k] || KIND_META.org).label}
                  right={<Icon name="chevronRight" size={15} style={{ color: "var(--text-faint)" }} />} />;
              })}
            </Panel>}
          </div>
        </div>
      </div>
    </div>
  );
}

window.Dashboard = Dashboard;
