// payer.jsx — Payer Insights section [06]
// Four charts: Revenue Concentration, Patient Burden by Payer,
// Reimbursement Velocity, and Procedure × Payer Matrix.

// ─────────────────────── Helpers ───────────────────────
const planTypeColor = (pt) => {
  const D = window.ROI_DATA.payer_insights;
  return D?.payer_colors?.[pt] || "#CCCCCC";
};

const planTypeLabel = (pt) => {
  const D = window.ROI_DATA.payer_insights;
  return D?.plan_type_labels?.[pt] || pt;
};

// Compact payer name for chart labels (drops parens detail)
const compactName = (name) => {
  if (!name) return "";
  return name.length > 28 ? name.slice(0, 26) + "…" : name;
};

// ─────────────────────── Chart 1: Revenue Concentration ───────────────────────
const PayerConcentration = () => {
  const D = window.ROI_DATA.payer_insights;
  const isMobile = useIsMobile();
  const ref = React.useRef(null);
  const seen = useInView(ref, 0);
  const p = useProgress(650, seen);

  // Top 10 by total_revenue
  const top10 = [...D.mix].sort((a, b) => b.total_revenue - a.total_revenue).slice(0, 10);
  const totalRev = top10.reduce((s, r) => s + r.total_revenue, 0);
  const maxRev = top10[0].total_revenue;

  // Plan-type roll-up for legend
  const byType = {};
  D.mix.forEach(r => {
    byType[r.plan_type] = (byType[r.plan_type] || 0) + r.total_revenue;
  });
  const grandTotal = Object.values(byType).reduce((s, v) => s + v, 0);
  const typeOrder = Object.entries(byType).sort((a, b) => b[1] - a[1]);

  return (
    <div ref={ref}>
      {/* Plan-type breakdown bar */}
      <div style={{
        display: "flex", height: 36, marginBottom: 24, border: "1px solid #000",
        overflow: "hidden", background: "#F1F1F1",
      }}>
        {typeOrder.map(([type, rev], i) => {
          const pct = (rev / grandTotal) * 100;
          return (
            <div key={type} style={{
              width: `${pct * p}%`, background: planTypeColor(type),
              display: "flex", alignItems: "center", padding: "0 10px",
              transition: `width 1200ms cubic-bezier(0.2,0.7,0.2,1) ${i * 80}ms`,
              minWidth: pct > 4 ? 0 : 0,
              overflow: "hidden", whiteSpace: "nowrap",
            }}>
              {pct > 8 && (
                <Mono size={10} color="rgba(0,0,0,0.7)">{planTypeLabel(type)} · {pct.toFixed(0)}%</Mono>
              )}
            </div>
          );
        })}
      </div>

      {/* Top 10 horizontal bar chart */}
      <div style={{ display: "flex", flexDirection: "column", gap: 8 }}>
        {top10.map((row, i) => {
          const w = (row.total_revenue / maxRev) * 100 * p;
          const pctOfTotal = (row.total_revenue / grandTotal) * 100;
          return (
            <div key={row.payer} style={{
              display: "grid",
              gridTemplateColumns: isMobile ? "1fr 84px" : "220px 1fr 110px",
              gridTemplateAreas: isMobile ? `"name num" "bar bar"` : undefined,
              alignItems: "center", gap: isMobile ? "4px 12px" : 16,
              padding: isMobile ? "6px 0" : 0,
              borderBottom: isMobile ? "1px solid rgba(0,0,0,0.06)" : "none",
            }}>
              <div style={{ gridArea: isMobile ? "name" : "auto", overflow: "hidden", textOverflow: "ellipsis", whiteSpace: "nowrap" }}>
                <span style={{ fontSize: 13, fontWeight: 500 }}>{compactName(row.payer)}</span>
                <Mono size={9} color="#999" style={{ display: "block", marginTop: 2 }}>
                  {planTypeLabel(row.plan_type).toUpperCase()}
                </Mono>
              </div>
              <div style={{ gridArea: isMobile ? "bar" : "auto", position: "relative", height: isMobile ? 20 : 32, background: "#F1F1F1", border: "1px solid #E1E1E1" }}>
                <div style={{
                  width: `${w}%`, height: "100%",
                  background: planTypeColor(row.plan_type),
                  transition: `width 1200ms cubic-bezier(0.2,0.7,0.2,1) ${i * 70 + 200}ms`,
                }} />
              </div>
              <div style={{ gridArea: isMobile ? "num" : "auto", textAlign: "right" }}>
                <span style={{ fontFamily: "Suisse Intl", fontSize: isMobile ? 15 : 18, fontWeight: 400 }}>
                  {fmt.usdAbbr(row.total_revenue)}
                </span>
                <Mono size={9} color="#999" style={{ display: "block", marginTop: 2 }}>
                  {pctOfTotal.toFixed(1)}% OF TOTAL
                </Mono>
              </div>
            </div>
          );
        })}
      </div>
    </div>
  );
};
window.PayerConcentration = PayerConcentration;

// ─────────────────────── Chart 2: Patient Burden by Payer ───────────────────────
const PayerBurden = () => {
  const D = window.ROI_DATA.payer_insights;
  const isMobile = useIsMobile();
  const ref = React.useRef(null);
  const seen = useInView(ref, 0);
  const p = useProgress(650, seen);

  // Top 12 by total_revenue, sorted by pct_patient_share desc
  const candidates = [...D.mix].sort((a, b) => b.total_revenue - a.total_revenue).slice(0, 12);
  const top = candidates.sort((a, b) => b.pct_patient_share - a.pct_patient_share);
  const maxShare = Math.max(...top.map(r => r.pct_patient_share));
  const xMax = Math.ceil(maxShare / 5) * 5;

  return (
    <div ref={ref}>
      <div style={{ display: "flex", flexDirection: "column", gap: 8 }}>
        {top.map((row, i) => {
          const w = (row.pct_patient_share / xMax) * 100 * p;
          const warn = row.pct_patient_share >= 20;
          const burdenColor = warn ? THEME.accent : THEME.primary;
          return (
            <div key={row.payer} style={{
              display: "grid",
              gridTemplateColumns: isMobile ? "1fr 84px" : "220px 1fr 140px 110px",
              gridTemplateAreas: isMobile ? `"name share" "bar avg"` : undefined,
              alignItems: "center", gap: isMobile ? "4px 12px" : 16,
              padding: isMobile ? "6px 0" : 0,
              borderBottom: isMobile ? "1px solid rgba(0,0,0,0.06)" : "none",
            }}>
              <div style={{ gridArea: isMobile ? "name" : "auto", overflow: "hidden", textOverflow: "ellipsis", whiteSpace: "nowrap" }}>
                <span style={{ fontSize: 13, fontWeight: 500 }}>{compactName(row.payer)}</span>
                <Mono size={9} color="#999" style={{ display: "block", marginTop: 2 }}>
                  {fmt.usdAbbr(row.total_revenue)} REVENUE
                </Mono>
              </div>
              <div style={{ gridArea: isMobile ? "bar" : "auto", position: "relative", height: isMobile ? 18 : 30, background: "#F1F1F1", border: "1px solid #E1E1E1" }}>
                <div style={{
                  width: `${w}%`, height: "100%", background: burdenColor,
                  transition: `width 1200ms cubic-bezier(0.2,0.7,0.2,1) ${i * 60 + 200}ms`,
                }} />
                {/* Scale ticks */}
                {[0, 25, 50, 75, 100].map(v => v <= xMax && (
                  <div key={v} style={{
                    position: "absolute", left: `${(v / xMax) * 100}%`, top: 0, bottom: 0,
                    width: 1, background: "rgba(0,0,0,0.06)",
                  }} />
                ))}
              </div>
              <div style={{ gridArea: isMobile ? "share" : "auto", textAlign: "right" }}>
                <span style={{
                  fontFamily: "Suisse Intl", fontSize: isMobile ? 18 : 22, fontWeight: 400,
                  color: warn ? "#FF426F" : "#000",
                }}>{row.pct_patient_share.toFixed(1)}%</span>
                <Mono size={9} color="#999" style={{ display: "block", marginTop: 2 }}>
                  PATIENT SHARE
                </Mono>
              </div>
              <div style={{ gridArea: isMobile ? "avg" : "auto", textAlign: "right" }}>
                <span style={{ fontFamily: "Suisse Intl", fontSize: isMobile ? 13 : 16 }}>
                  {fmt.usd(row.avg_pat_resp_per_claim)}
                </span>
                <Mono size={9} color="#999" style={{ display: "block", marginTop: 2 }}>
                  AVG / CLAIM
                </Mono>
              </div>
            </div>
          );
        })}
      </div>
    </div>
  );
};
window.PayerBurden = PayerBurden;

// ─────────────────────── Chart 3: Reimbursement Velocity ───────────────────────
const PayerVelocity = () => {
  const D = window.ROI_DATA.payer_insights;
  const isMobile = useIsMobile();
  const ref = React.useRef(null);
  const seen = useInView(ref, 0);
  const p = useProgress(650, seen);

  // Top 12 payers by total_claims that have velocity data
  const candidates = [...D.velocity]
    .filter(r => r.median_days != null)
    .sort((a, b) => b.total_claims - a.total_claims).slice(0, 12);
  // Sort by median asc (fastest at top)
  const top = candidates.sort((a, b) => a.median_days - b.median_days);
  const maxDays = Math.max(...top.map(r => r.p90_days || r.median_days)) * 1.05;

  return (
    <div ref={ref}>
      <div style={{ display: "flex", flexDirection: "column", gap: 10 }}>
        {top.map((row, i) => {
          const pct25 = (row.p25_days / maxDays) * 100;
          const pct75 = (row.p75_days / maxDays) * 100;
          const pct90 = (row.p90_days / maxDays) * 100;
          const pctMedian = (row.median_days / maxDays) * 100;
          const slow = row.median_days >= 25;
          return (
            <div key={row.payer} style={{
              display: "grid",
              gridTemplateColumns: isMobile ? "1fr 80px" : "220px 1fr 130px",
              gridTemplateAreas: isMobile ? `"name med" "bar bar"` : undefined,
              alignItems: "center", gap: isMobile ? "4px 12px" : 16,
              padding: isMobile ? "6px 0" : 0,
              borderBottom: isMobile ? "1px solid rgba(0,0,0,0.06)" : "none",
            }}>
              <div style={{ gridArea: isMobile ? "name" : "auto", overflow: "hidden", textOverflow: "ellipsis", whiteSpace: "nowrap" }}>
                <span style={{ fontSize: 13, fontWeight: 500 }}>{compactName(row.payer)}</span>
                <Mono size={9} color="#999" style={{ display: "block", marginTop: 2 }}>
                  {row.total_claims.toLocaleString()} CLAIMS · {row.pct_paid.toFixed(0)}% PAID
                </Mono>
              </div>
              <div style={{ gridArea: isMobile ? "bar" : "auto", position: "relative", height: isMobile ? 22 : 30, background: "#FAFAFA", border: "1px solid #E1E1E1" }}>
                {/* P25-P75 box */}
                <div style={{
                  position: "absolute", left: `${pct25 * p}%`,
                  width: `${(pct75 - pct25) * p}%`,
                  top: 6, bottom: 6,
                  background: planTypeColor(row.plan_type), opacity: 0.7,
                  transition: `all 1200ms cubic-bezier(0.2,0.7,0.2,1) ${i * 60 + 200}ms`,
                }} />
                {/* P90 whisker */}
                <div style={{
                  position: "absolute", left: `${pct75 * p}%`,
                  width: `${(pct90 - pct75) * p}%`,
                  top: 14, bottom: 14,
                  background: planTypeColor(row.plan_type), opacity: 0.3,
                  transition: `all 1200ms cubic-bezier(0.2,0.7,0.2,1) ${i * 60 + 300}ms`,
                }} />
                {/* Median tick */}
                <div style={{
                  position: "absolute", left: `${pctMedian * p}%`,
                  top: 3, bottom: 3, width: 2, background: "#000",
                  transition: `all 1200ms cubic-bezier(0.2,0.7,0.2,1) ${i * 60 + 300}ms`,
                }} />
                {/* Scale ticks at 0/15/30/45/60+ days */}
                {[15, 30, 45, 60].filter(v => v <= maxDays).map(v => (
                  <div key={v} style={{
                    position: "absolute", left: `${(v / maxDays) * 100}%`,
                    top: 0, bottom: 0, width: 1, background: "rgba(0,0,0,0.05)",
                  }} />
                ))}
              </div>
              <div style={{ gridArea: isMobile ? "med" : "auto", textAlign: "right" }}>
                <span style={{
                  fontFamily: "Suisse Intl", fontSize: isMobile ? 18 : 22, fontWeight: 400,
                  color: slow ? "#FF426F" : "#000",
                }}>{row.median_days}d</span>
                <Mono size={9} color="#999" style={{ display: "block", marginTop: 2 }}>
                  MEDIAN
                </Mono>
              </div>
            </div>
          );
        })}
      </div>

      {/* Scale legend */}
      <div style={{ marginTop: 16, display: "flex", gap: 24, alignItems: "center" }}>
        <Mono size={10} color="#666">
          BOXES SPAN P25–P75 · FAINT SPLAY EXTENDS TO P90 · BLACK LINE = MEDIAN · MAX SHOWN: {Math.ceil(maxDays)} DAYS
        </Mono>
      </div>
    </div>
  );
};
window.PayerVelocity = PayerVelocity;

// ─────────────────────── Chart 4: Procedure × Payer Matrix ───────────────────────
const PayerProcMatrix = () => {
  const D = window.ROI_DATA.payer_insights;
  const isMobile = useIsMobile();
  const ref = React.useRef(null);
  const seen = useInView(ref, 0);
  const p = useProgress(650, seen);

  // Group by procedure code; for each, sort cells by total_paid desc
  const byProc = {};
  D.matrix.forEach(r => {
    if (!byProc[r.code]) byProc[r.code] = { code: r.code, description: r.description, cells: [] };
    byProc[r.code].cells.push(r);
  });
  Object.values(byProc).forEach(g => {
    g.cells.sort((a, b) => b.total_paid - a.total_paid);
  });
  const procs = Object.values(byProc).sort((a, b) => {
    const aTotal = a.cells.reduce((s, c) => s + c.total_paid, 0);
    const bTotal = b.cells.reduce((s, c) => s + c.total_paid, 0);
    return bTotal - aTotal;
  });

  // Build x-axis scale per procedure based on its max_paid
  const procScales = {};
  procs.forEach(g => {
    const maxVal = Math.max(...g.cells.map(c => c.max_paid));
    procScales[g.code] = maxVal * 1.05;
  });

  return (
    <div ref={ref} style={{ display: "flex", flexDirection: "column", gap: 32 }}>
      {procs.map((g, gi) => {
        const xMax = procScales[g.code];
        const totalPaid = g.cells.reduce((s, c) => s + c.total_paid, 0);
        return (
          <div key={g.code}>
            <div style={{
              display: "flex", alignItems: "baseline", gap: 12, marginBottom: 10,
              borderBottom: "1px solid #E1E1E1", paddingBottom: 8,
            }}>
              <Mono color={THEME.primary} size={10}>{g.code}</Mono>
              <span style={{ fontSize: 16, fontWeight: 500 }}>{g.description}</span>
              <span style={{ flex: 1 }} />
              <Mono size={10} color="#666">
                {g.cells.reduce((s, c) => s + c.encounters, 0).toLocaleString()} ENCOUNTERS · {fmt.usdAbbr(totalPaid)} TOTAL
              </Mono>
            </div>
            <div style={{ display: "flex", flexDirection: "column", gap: 4 }}>
              {g.cells.map((cell, ci) => {
                const pctMin = (cell.min_paid / xMax) * 100;
                const pctP25 = (cell.p25_paid / xMax) * 100;
                const pctMed = (cell.median_paid / xMax) * 100;
                const pctP75 = (cell.p75_paid / xMax) * 100;
                const pctMax = (cell.max_paid / xMax) * 100;
                return (
                  <div key={cell.payer} style={{
                    display: "grid",
                    gridTemplateColumns: isMobile ? "1fr 78px" : "200px 1fr 100px",
                    gridTemplateAreas: isMobile ? `"name med" "bar bar"` : undefined,
                    alignItems: "center", gap: isMobile ? "2px 10px" : 12, padding: isMobile ? "4px 0" : "2px 0",
                  }}>
                    <div style={{ gridArea: isMobile ? "name" : "auto", overflow: "hidden", textOverflow: "ellipsis", whiteSpace: "nowrap" }}>
                      <Mono size={10} color="#000">{compactName(cell.payer)}</Mono>
                    </div>
                    <div style={{ gridArea: isMobile ? "bar" : "auto", position: "relative", height: 18 }}>
                      {/* Min-Max thin line */}
                      <div style={{
                        position: "absolute", left: `${pctMin * p}%`, width: `${(pctMax - pctMin) * p}%`,
                        top: 8, height: 2, background: planTypeColor(cell.plan_type), opacity: 0.3,
                        transition: `all 900ms cubic-bezier(0.2,0.7,0.2,1) ${(gi * 60 + ci * 30)}ms`,
                      }} />
                      {/* P25-P75 box */}
                      <div style={{
                        position: "absolute", left: `${pctP25 * p}%`, width: `${(pctP75 - pctP25) * p}%`,
                        top: 3, bottom: 3, background: planTypeColor(cell.plan_type), opacity: 0.85,
                        transition: `all 900ms cubic-bezier(0.2,0.7,0.2,1) ${(gi * 60 + ci * 30 + 100)}ms`,
                      }} />
                      {/* Median tick */}
                      <div style={{
                        position: "absolute", left: `${pctMed * p}%`, width: 2,
                        top: 1, bottom: 1, background: "#000",
                        transition: `all 900ms cubic-bezier(0.2,0.7,0.2,1) ${(gi * 60 + ci * 30 + 150)}ms`,
                      }} />
                    </div>
                    <div style={{ gridArea: isMobile ? "med" : "auto", textAlign: "right" }}>
                      <Mono size={11} color="#000">{fmt.usd(cell.median_paid)}</Mono>
                      <Mono size={9} color="#999" style={{ display: "block", marginTop: 1 }}>
                        {cell.pct_reimbursed}% REIMB
                      </Mono>
                    </div>
                  </div>
                );
              })}
            </div>
          </div>
        );
      })}

      <Mono size={10} color="#666" style={{ marginTop: 8 }}>
        EACH ROW SHOWS PER-ENCOUNTER INSURANCE PAYMENT RANGE FOR ONE PAYER · THIN LINE = MIN-MAX · COLORED BOX = P25-P75 · BLACK TICK = MEDIAN
      </Mono>
    </div>
  );
};
window.PayerProcMatrix = PayerProcMatrix;
