// Shared project dashboard: weekly outreach line (month-bucketed), Leads/CC/Visits
// tiles, Offers/Closed bars. Used by the Projects page and the Project Report.
// window.ProjectDashboard({ projectId, projectName, clientName, type, lead, universe, lastWeek })
(function () {
  const { useState, useEffect, useMemo } = React;
  const MONTHS = ["Jan","Feb","Mar","Apr","May","Jun","Jul","Aug","Sep","Oct","Nov","Dec"];
  const PERIODS = [["week","Current Week"],["mtd","MTD"],["qtd","QTD"],["ytd","YTD"]];
  const ALLTIME = { from: "2024-01-01", to: "2027-12-31" };
  const nm = (id) => (window.VAULT_FIRM.PEOPLE_BY_ID[id] || {}).name || id || "—";
  function rangeOf(period, maxWeek) {
    if (!maxWeek) return ALLTIME;
    const to = maxWeek, d = new Date(to + "T00:00:00Z"), y = d.getUTCFullYear(), m = d.getUTCMonth();
    if (period === "week") return { from: to, to };
    if (period === "mtd") return { from: `${y}-${String(m + 1).padStart(2, "0")}-01`, to };
    if (period === "qtd") { const qm = Math.floor(m / 3) * 3; return { from: `${y}-${String(qm + 1).padStart(2, "0")}-01`, to }; }
    return { from: `${y}-01-01`, to };
  }

  function LineChart({ labels, series }) {
    const w = 760, h = 220, pad = { l: 38, r: 14, t: 14, b: 26 };
    const iw = w - pad.l - pad.r, ih = h - pad.t - pad.b;
    const raw = Math.max(1, ...series.flatMap(s => s.data));
    const top = raw <= 6 ? Math.max(1, Math.ceil(raw)) : raw;
    const x = (i) => pad.l + (labels.length <= 1 ? iw / 2 : (i / (labels.length - 1)) * iw);
    const y = (v) => pad.t + ih - (v / top) * ih;
    const ticks = top <= 6 ? Array.from({ length: top + 1 }, (_, k) => k) : [0, top / 2, top];
    return (
      <svg viewBox={`0 0 ${w} ${h}`} preserveAspectRatio="none" style={{ width: "100%", height: h, display: "block" }}>
        {ticks.map((tv, i) => (<g key={i}>
          <line x1={pad.l} x2={w - pad.r} y1={y(tv)} y2={y(tv)} stroke="var(--line-2)"/>
          <text x={pad.l - 6} y={y(tv) + 3} fontSize="10" fill="var(--muted)" textAnchor="end" fontFamily="var(--f-mono)">{Math.round(tv)}</text>
        </g>))}
        {labels.map((lab, i) => <text key={i} x={x(i)} y={h - 8} fontSize="9.5" fill="var(--muted)" textAnchor="middle" fontFamily="var(--f-mono)">{lab}</text>)}
        {series.map((s, si) => (<g key={si}>
          <polyline points={s.data.map((v, i) => `${x(i)},${y(v)}`).join(" ")} fill="none" stroke={s.color} strokeWidth="2.5" strokeLinejoin="round" strokeLinecap="round"/>
          {s.data.map((v, i) => <circle key={i} cx={x(i)} cy={y(v)} r="2.5" fill={s.color}/>)}
        </g>))}
      </svg>
    );
  }
  function BarPair({ labels, series }) {
    const w = 420, h = 220, pad = { l: 30, r: 10, t: 14, b: 26 };
    const iw = w - pad.l - pad.r, ih = h - pad.t - pad.b;
    const raw = Math.max(1, ...series.flatMap(s => s.data));
    const top = raw <= 6 ? Math.max(1, Math.ceil(raw)) : raw;
    const groupW = iw / Math.max(1, labels.length), barW = Math.min(14, (groupW - 6) / 2);
    const ticks = top <= 6 ? Array.from({ length: top + 1 }, (_, k) => k) : [0, top / 2, top];
    return (
      <svg viewBox={`0 0 ${w} ${h}`} preserveAspectRatio="none" style={{ width: "100%", height: h, display: "block" }}>
        {ticks.map((tv, i) => (<g key={i}>
          <line x1={pad.l} x2={w - pad.r} y1={pad.t + ih - (tv / top) * ih} y2={pad.t + ih - (tv / top) * ih} stroke="var(--line-2)"/>
          <text x={pad.l - 6} y={pad.t + ih - (tv / top) * ih + 3} fontSize="10" fill="var(--muted)" textAnchor="end" fontFamily="var(--f-mono)">{Math.round(tv)}</text>
        </g>))}
        {labels.map((lab, gi) => { const gx = pad.l + gi * groupW; return <g key={gi}>
          {series.map((s, si) => { const v = s.data[gi] || 0, bh = (v / top) * ih; const bx = gx + groupW / 2 - barW + si * barW;
            return <rect key={si} x={bx + 1} y={pad.t + ih - bh} width={barW - 2} height={Math.max(0, bh)} rx="2" fill={s.color}/>; })}
          <text x={gx + groupW / 2} y={h - 8} fontSize="9.5" fill="var(--muted)" textAnchor="middle" fontFamily="var(--f-mono)">{lab}</text>
        </g>; })}
      </svg>
    );
  }
  function Tile({ label, value }) {
    return <div className="card" style={{ padding: "16px 18px", flex: 1 }}>
      <div className="micro">{label}</div>
      <div className="display mono" style={{ fontSize: 30, lineHeight: 1.1, marginTop: 4 }}>{value}</div>
    </div>;
  }

  window.ProjectDashboard = function ProjectDashboard({ projectId, projectName, clientName, type, lead, universe, lastWeek, onBack }) {
    const [period, setPeriod] = useState("ytd");
    const [weekly, setWeekly] = useState([]);
    const [loading, setLoading] = useState(false);
    const range = useMemo(() => rangeOf(period, lastWeek), [period, lastWeek]);

    useEffect(() => {
      if (!projectId) { setWeekly([]); return; }
      let cancel = false; setLoading(true);
      window.VaultAPI.getProjectWeekly(projectId, range.from, range.to)
        .then(rows => { if (!cancel) { setWeekly(rows || []); setLoading(false); } })
        .catch(() => { if (!cancel) setLoading(false); });
      return () => { cancel = true; };
    }, [projectId, range.from, range.to]);

    const monthly = useMemo(() => {
      const m = {};
      weekly.forEach(w => { const k = (w.week || "").slice(0, 7); if (!k) return;
        if (!m[k]) m[k] = { calls: 0, mailings: 0, leads: 0, confCalls: 0, visits: 0, offers: 0, closed: 0 };
        ["calls","mailings","leads","confCalls","visits","offers","closed"].forEach(x => m[k][x] += w[x] || 0); });
      const keys = Object.keys(m).sort();
      return { keys, labels: keys.map(k => MONTHS[parseInt(k.slice(5, 7), 10) - 1]), data: keys.map(k => m[k]) };
    }, [weekly]);
    const tot = useMemo(() => { const t = { calls: 0, mailings: 0, leads: 0, confCalls: 0, visits: 0, offers: 0, closed: 0 };
      weekly.forEach(w => Object.keys(t).forEach(k => t[k] += w[k] || 0)); return t; }, [weekly]);

    return (
      <div>
        <div className="card" style={{ background: "var(--accent)", color: "var(--accent-ink)", padding: "18px 22px", marginBottom: 16 }}>
          <div className="row" style={{ justifyContent: "space-between", alignItems: "flex-start", flexWrap: "wrap", gap: 12 }}>
            <div>
              <div style={{ fontSize: 10.5, letterSpacing: ".06em", opacity: .8 }}>{(type || "").toUpperCase()}{clientName ? " · " + clientName : ""}</div>
              <div className="display" style={{ fontSize: 23, fontWeight: 600 }}>{projectName}</div>
              <div style={{ fontSize: 12, opacity: .85, marginTop: 4 }}>{universe} targets · lead {nm(lead)}</div>
            </div>
            <div className="row" style={{ gap: 0, borderRadius: 8, overflow: "hidden", border: "1px solid rgba(255,255,255,.3)" }}>
              {PERIODS.map(([p, l]) => (
                <button key={p} onClick={() => setPeriod(p)} style={{ padding: "5px 12px", fontSize: 12, border: 0, cursor: "pointer", background: period === p ? "rgba(255,255,255,.22)" : "transparent", color: "var(--accent-ink)" }}>{l}</button>
              ))}
            </div>
          </div>
        </div>

        <div className="card card-pad" style={{ marginBottom: 16 }}>
          <div className="row" style={{ justifyContent: "space-between", alignItems: "center", marginBottom: 8 }}>
            <span className="micro seclabel">Outreach by month {loading ? "· loading…" : ""}</span>
            <span className="row" style={{ gap: 16, fontSize: 11.5, color: "var(--ink-2)" }}>
              <span className="row" style={{ gap: 6, alignItems: "center" }}><span style={{ width: 11, height: 3, borderRadius: 2, background: "var(--accent)" }}/>Calls {tot.calls}</span>
              <span className="row" style={{ gap: 6, alignItems: "center" }}><span style={{ width: 11, height: 3, borderRadius: 2, background: "#E0A92E" }}/>Mailings {tot.mailings}</span>
            </span>
          </div>
          {monthly.keys.length === 0 ? <div className="muted small" style={{ padding: 20 }}>No outreach in this period.</div> :
            <LineChart labels={monthly.labels} series={[
              { color: "var(--accent)", data: monthly.data.map(d => d.calls) },
              { color: "#E0A92E", data: monthly.data.map(d => d.mailings) },
            ]}/>}
        </div>

        <div style={{ display: "grid", gridTemplateColumns: "1fr 1fr", gap: 16 }}>
          <div className="card card-pad">
            <div className="micro seclabel" style={{ marginBottom: 12 }}>Lead progression · period totals</div>
            <div className="row" style={{ gap: 12 }}>
              <Tile label="Leads" value={tot.leads}/>
              <Tile label="Conf Calls" value={tot.confCalls}/>
              <Tile label="Visits" value={tot.visits}/>
            </div>
          </div>
          <div className="card card-pad">
            <div className="row" style={{ justifyContent: "space-between", alignItems: "center", marginBottom: 8 }}>
              <span className="micro seclabel">Offers &amp; closed by month</span>
              <span className="row" style={{ gap: 14, fontSize: 11.5, color: "var(--ink-2)" }}>
                <span className="row" style={{ gap: 6, alignItems: "center" }}><span style={{ width: 10, height: 10, borderRadius: 2, background: "var(--accent)" }}/>Offers {tot.offers}</span>
                <span className="row" style={{ gap: 6, alignItems: "center" }}><span style={{ width: 10, height: 10, borderRadius: 2, background: "var(--ok)" }}/>Closed {tot.closed}</span>
              </span>
            </div>
            {monthly.keys.length === 0 ? <div className="muted small" style={{ padding: 20 }}>No deals in this period.</div> :
              <BarPair labels={monthly.labels} series={[
                { color: "var(--accent)", data: monthly.data.map(d => d.offers) },
                { color: "var(--ok)", data: monthly.data.map(d => d.closed) },
              ]}/>}
          </div>
        </div>
      </div>
    );
  };
})();
