/* charts.jsx — animated SVG charts for the product preview.
   All progress comes from useProgress (rAF + setTimeout safety), so charts always
   reach their final state even where the animation timeline is frozen. */

/* Animated stacked area: Billed vs Collected. Reveal by growing a clip width. */
function AreaChart({ inView }) {
  const W = 560, H = 220, pad = { l: 8, r: 8, t: 16, b: 24 };
  const billed = [42, 55, 48, 70, 62, 88, 74, 96, 84, 110, 102, 124];
  const collected = [30, 41, 38, 52, 49, 66, 58, 78, 70, 92, 88, 108];
  const max = 132;
  const x = (i) => pad.l + (i * (W - pad.l - pad.r)) / (billed.length - 1);
  const y = (v) => pad.t + (1 - v / max) * (H - pad.t - pad.b);
  const line = (arr) => arr.map((v, i) => `${i ? "L" : "M"}${x(i).toFixed(1)} ${y(v).toFixed(1)}`).join(" ");
  const area = (arr) => `${line(arr)} L${x(arr.length - 1)} ${H - pad.b} L${x(0)} ${H - pad.b} Z`;
  const clip = useProgress(inView, 1400);
  return (
    <svg viewBox={`0 0 ${W} ${H}`} className="chart-svg" preserveAspectRatio="none">
      <defs>
        <linearGradient id="aBill" x1="0" y1="0" x2="0" y2="1"><stop offset="0" stopColor="#2FB1F0" stopOpacity="0.32"/><stop offset="1" stopColor="#2FB1F0" stopOpacity="0"/></linearGradient>
        <linearGradient id="aColl" x1="0" y1="0" x2="0" y2="1"><stop offset="0" stopColor="#16CFBD" stopOpacity="0.40"/><stop offset="1" stopColor="#16CFBD" stopOpacity="0.02"/></linearGradient>
        <clipPath id="areaClip"><rect x="0" y="0" width={W * clip} height={H} /></clipPath>
      </defs>
      {[0.25, 0.5, 0.75].map((g) => (
        <line key={g} x1={pad.l} x2={W - pad.r} y1={pad.t + g * (H - pad.t - pad.b)} y2={pad.t + g * (H - pad.t - pad.b)} stroke="#EAF1F8" strokeWidth="1"/>
      ))}
      <g clipPath="url(#areaClip)">
        <path d={area(billed)} fill="url(#aBill)"/>
        <path d={line(billed)} fill="none" stroke="#2FB1F0" strokeWidth="2.4" strokeLinecap="round" strokeLinejoin="round"/>
        <path d={area(collected)} fill="url(#aColl)"/>
        <path d={line(collected)} fill="none" stroke="#16CFBD" strokeWidth="2.4" strokeLinecap="round" strokeLinejoin="round"/>
      </g>
      <circle cx={x(billed.length - 1)} cy={y(billed[billed.length - 1])} r="3.5" fill="#2FB1F0" opacity={clip > 0.95 ? 1 : 0}/>
      <circle cx={x(collected.length - 1)} cy={y(collected[collected.length - 1])} r="3.5" fill="#16CFBD" opacity={clip > 0.95 ? 1 : 0}/>
    </svg>
  );
}

/* Animated donut: claim status mix */
function Donut({ inView }) {
  const segs = [
    { label: "Paid", value: 64, color: "#0EA371" },
    { label: "Pending", value: 22, color: "#2FB1F0" },
    { label: "Denied", value: 9, color: "#E14668" },
    { label: "Other", value: 5, color: "#C3D0DD" },
  ];
  const total = segs.reduce((a, s) => a + s.value, 0);
  const R = 52, C = 2 * Math.PI * R;
  const p = useProgress(inView, 1300);
  let offset = 0;
  const paidPct = useCountUp(64, { start: inView, duration: 1300 });
  return (
    <div className="donut-wrap">
      <svg viewBox="0 0 140 140" className="donut">
        <circle cx="70" cy="70" r={R} fill="none" stroke="#EEF3F8" strokeWidth="15"/>
        {segs.map((s, i) => {
          const frac = (s.value / total) * p;
          const dash = `${frac * C} ${C}`;
          const el = (
            <circle key={i} cx="70" cy="70" r={R} fill="none" stroke={s.color} strokeWidth="15"
              strokeDasharray={dash} strokeDashoffset={-offset * C} strokeLinecap="butt"
              transform="rotate(-90 70 70)"/>
          );
          offset += frac;
          return el;
        })}
        <text x="70" y="66" textAnchor="middle" className="donut-big">{paidPct}%</text>
        <text x="70" y="86" textAnchor="middle" className="donut-cap">paid</text>
      </svg>
      <div className="donut-legend">
        {segs.map((s) => (
          <div key={s.label} className="leg-row">
            <span className="leg-dot" style={{ background: s.color }}></span>
            <span className="leg-label">{s.label}</span>
            <span className="leg-val">{s.value}%</span>
          </div>
        ))}
      </div>
    </div>
  );
}

/* Animated bars: top payers (width driven by useProgress, not CSS transition) */
function Bars({ inView }) {
  const data = [
    { name: "UnitedHealthcare", v: 100 },
    { name: "Aetna", v: 82 },
    { name: "Cigna", v: 64 },
    { name: "Aetna Better Health", v: 47 },
    { name: "Wellpoint", v: 33 },
  ];
  const p = useProgress(inView, 1200);
  return (
    <div className="bars">
      {data.map((d, i) => {
        // slight per-bar stagger baked into the eased progress
        const local = Math.max(0, Math.min(1, p * 1.25 - i * 0.06));
        return (
          <div key={d.name} className="bar-row">
            <span className="bar-name">{d.name}</span>
            <div className="bar-track">
              <div className="bar-fill" style={{ width: `${d.v * local}%` }}></div>
            </div>
          </div>
        );
      })}
    </div>
  );
}

/* Mini sparkline for KPI tiles (stroke reveal via useProgress) */
function Spark({ data, color = "#2FB1F0", inView }) {
  const W = 120, H = 34;
  const max = Math.max(...data), min = Math.min(...data);
  const x = (i) => (i * W) / (data.length - 1);
  const y = (v) => H - 3 - ((v - min) / (max - min || 1)) * (H - 6);
  const d = data.map((v, i) => `${i ? "L" : "M"}${x(i).toFixed(1)} ${y(v).toFixed(1)}`).join(" ");
  const ref = useRef(null);
  const [len, setLen] = useState(0);
  useEffect(() => { if (ref.current) setLen(ref.current.getTotalLength()); }, [d]);
  const p = useProgress(inView, 1100);
  return (
    <svg viewBox={`0 0 ${W} ${H}`} className="spark" preserveAspectRatio="none">
      <path ref={ref} d={d} fill="none" stroke={color} strokeWidth="2" strokeLinecap="round" strokeLinejoin="round"
        style={{ strokeDasharray: len || undefined, strokeDashoffset: len ? len * (1 - p) : 0 }}/>
    </svg>
  );
}

Object.assign(window, { AreaChart, Donut, Bars, Spark });
