// charts.jsx — Data visualization primitives

const { useState: useStateC, useMemo: useMemoC } = React;

// --- Horizontal Score Bar (with benchmark marker for 일반 기준) ---
const ScoreBar = ({ label, value, base, max = 100, color, tone = "default", animate = true }) => {
  const pct = Math.max(0, Math.min(100, (value / max) * 100));
  const basePct = base != null ? (base / max) * 100 : null;
  const fillColor = tone === "alert" ? "var(--alert)"
    : tone === "watch" ? "var(--watch)"
    : tone === "good" ? "var(--good)"
    : color || undefined;
  return (
    <div className="score-bar">
      <span className="label">{label}</span>
      <div className="track">
        <div className="fill" style={{
          width: pct + "%",
          background: fillColor ? fillColor : undefined,
          transition: animate ? "width 700ms cubic-bezier(0.2, 0.6, 0.2, 1)" : "none",
        }} />
        {basePct != null && <div className="benchmark" style={{ left: basePct + "%" }} title={`일반 기준 ${base}`} />}
      </div>
      <span className="value">{value}</span>
    </div>
  );
};

// --- Radial Donut (overall skin score / package coverage) ---
const Donut = ({ value, max = 100, size = 140, stroke = 12, color = "var(--ink-1)", track = "var(--bg-subtle)", label, subtitle }) => {
  const r = (size - stroke) / 2;
  const c = 2 * Math.PI * r;
  const pct = Math.max(0, Math.min(100, (value / max) * 100));
  const dash = (pct / 100) * c;
  return (
    <div className="donut-wrap" style={{ width: size, height: size }}>
      <svg width={size} height={size} viewBox={`0 0 ${size} ${size}`}>
        <circle cx={size/2} cy={size/2} r={r} fill="none" stroke={track} strokeWidth={stroke} />
        <circle cx={size/2} cy={size/2} r={r} fill="none" stroke={color} strokeWidth={stroke}
                strokeDasharray={`${dash} ${c}`} strokeLinecap="round"
                transform={`rotate(-90 ${size/2} ${size/2})`}
                style={{ transition: "stroke-dasharray 800ms cubic-bezier(0.2, 0.7, 0.2, 1)" }} />
      </svg>
      <div className="donut-center">
        <div>
          {label && <div className="l">{label}</div>}
          <div className="v">{value}</div>
          {subtitle && <div className="l" style={{ marginTop: 2 }}>{subtitle}</div>}
        </div>
      </div>
    </div>
  );
};

// --- Sparkline ---
const Sparkline = ({ data, w = 200, h = 56, color = "var(--phase-tint)", fillOpacity = 0.12, showDots = false }) => {
  const min = Math.min(...data), max = Math.max(...data);
  const pad = 4;
  const px = (i) => pad + (i / (data.length - 1)) * (w - pad * 2);
  const py = (v) => pad + (1 - (v - min) / (max - min || 1)) * (h - pad * 2);
  const path = data.map((v, i) => `${i ? "L" : "M"} ${px(i).toFixed(1)} ${py(v).toFixed(1)}`).join(" ");
  const area = `${path} L ${px(data.length - 1)} ${h - pad} L ${px(0)} ${h - pad} Z`;
  return (
    <svg width={w} height={h} viewBox={`0 0 ${w} ${h}`}>
      <path d={area} fill={color} opacity={fillOpacity} />
      <path d={path} fill="none" stroke={color} strokeWidth="1.8" strokeLinecap="round" strokeLinejoin="round" />
      {showDots && data.map((v, i) => (
        <circle key={i} cx={px(i)} cy={py(v)} r={2} fill={color} />
      ))}
      <circle cx={px(data.length - 1)} cy={py(data[data.length - 1])} r={3} fill="#FFF" stroke={color} strokeWidth="1.8" />
    </svg>
  );
};

// --- Mini bar chart (last N days) ---
const MiniBars = ({ data, w = 200, h = 56, color = "var(--phase-tint)", gap = 3 }) => {
  const max = Math.max(...data);
  const bw = (w - gap * (data.length - 1)) / data.length;
  return (
    <svg width={w} height={h} viewBox={`0 0 ${w} ${h}`}>
      {data.map((v, i) => {
        const bh = Math.max(2, (v / max) * (h - 4));
        return <rect key={i} x={i * (bw + gap)} y={h - bh} width={bw} height={bh} rx={2} fill={i === data.length - 1 ? color : "var(--bg-subtle)"} />;
      })}
    </svg>
  );
};

// --- Radar chart (skin scores all-in-one) ---
const Radar = ({ axes, values, baseline, size = 320, max = 100, color = "var(--data-blue)" }) => {
  const cx = size / 2, cy = size / 2;
  const r = size * 0.38;
  const n = axes.length;
  const point = (i, v) => {
    const angle = -Math.PI / 2 + (i / n) * Math.PI * 2;
    const rad = (v / max) * r;
    return [cx + Math.cos(angle) * rad, cy + Math.sin(angle) * rad];
  };
  const polyData = values.map((v, i) => point(i, v));
  const polyBase = baseline ? baseline.map((v, i) => point(i, v)) : null;
  const polyStr = (arr) => arr.map((p, i) => `${i ? "L" : "M"} ${p[0].toFixed(1)} ${p[1].toFixed(1)}`).join(" ") + " Z";
  return (
    <svg width={size} height={size} viewBox={`0 0 ${size} ${size}`}>
      {/* Grid rings */}
      {[0.25, 0.5, 0.75, 1].map((f, i) => (
        <circle key={i} cx={cx} cy={cy} r={r * f} fill="none" stroke="var(--line-hair)" strokeDasharray={i === 3 ? "0" : "2 3"} />
      ))}
      {/* Axis lines */}
      {axes.map((_, i) => {
        const angle = -Math.PI / 2 + (i / n) * Math.PI * 2;
        return <line key={i} x1={cx} y1={cy} x2={cx + Math.cos(angle) * r} y2={cy + Math.sin(angle) * r} stroke="var(--line-hair)" />;
      })}
      {/* Baseline polygon */}
      {polyBase && (
        <path d={polyStr(polyBase)} fill="var(--ink-2)" fillOpacity="0.05" stroke="var(--ink-3)"
              strokeWidth="1.2" strokeDasharray="3 3" />
      )}
      {/* Actual polygon */}
      <path d={polyStr(polyData)} fill={color} fillOpacity="0.14" stroke={color} strokeWidth="1.8" strokeLinejoin="round" />
      {/* Dots */}
      {polyData.map((p, i) => (
        <circle key={i} cx={p[0]} cy={p[1]} r={3.5} fill="#FFF" stroke={color} strokeWidth="2" />
      ))}
      {/* Labels */}
      {axes.map((a, i) => {
        const angle = -Math.PI / 2 + (i / n) * Math.PI * 2;
        const lx = cx + Math.cos(angle) * (r + 18);
        const ly = cy + Math.sin(angle) * (r + 18);
        const anchor = Math.abs(Math.cos(angle)) < 0.2 ? "middle" : Math.cos(angle) > 0 ? "start" : "end";
        return (
          <text key={i} x={lx} y={ly} textAnchor={anchor} dominantBaseline="middle"
                fontSize="11" fontWeight="500" fill="var(--ink-3)" fontFamily="var(--font-kr)">{a}</text>
        );
      })}
    </svg>
  );
};

// --- Bar chart (horizontal, treatment fit) ---
const HBarChart = ({ items, max = 100, w = "100%", showLabels = true }) => (
  <div style={{ width: w, display: "flex", flexDirection: "column", gap: 10 }}>
    {items.map((it, i) => (
      <div key={i} style={{ display: "grid", gridTemplateColumns: "120px 1fr 32px", gap: 12, alignItems: "center" }}>
        <div style={{ fontSize: 12.5, color: "var(--ink-2)", fontWeight: 500 }}>
          {it.label}
          {it.sub && <div style={{ fontSize: 10.5, color: "var(--ink-4)", marginTop: 1 }}>{it.sub}</div>}
        </div>
        <div style={{ height: 10, background: "var(--bg-subtle)", borderRadius: 999, position: "relative", overflow: "hidden" }}>
          <div style={{
            position: "absolute", inset: "0 auto 0 0",
            width: `${(it.value / max) * 100}%`,
            background: it.color || "linear-gradient(90deg, var(--phase-tint), var(--data-teal))",
            borderRadius: 999,
            transition: "width 700ms cubic-bezier(0.2, 0.7, 0.2, 1)",
          }} />
        </div>
        <div className="num" style={{ fontSize: 12.5, fontWeight: 600, color: "var(--ink-1)", textAlign: "right" }}>{it.value}</div>
      </div>
    ))}
  </div>
);

// --- Line chart with grid (BI) ---
const LineChart = ({ data, w = 520, h = 180, color = "var(--phase-tint)", label, yUnit = "", baseline }) => {
  const min = 0;
  const max = Math.ceil(Math.max(...data, baseline ? Math.max(...baseline) : 0) * 1.1);
  const padL = 32, padR = 8, padT = 8, padB = 22;
  const px = (i) => padL + (i / (data.length - 1)) * (w - padL - padR);
  const py = (v) => padT + (1 - (v - min) / (max - min)) * (h - padT - padB);
  const path = data.map((v, i) => `${i ? "L" : "M"} ${px(i).toFixed(1)} ${py(v).toFixed(1)}`).join(" ");
  const area = `${path} L ${px(data.length - 1)} ${h - padB} L ${px(0)} ${h - padB} Z`;
  const yTicks = [0, 0.25, 0.5, 0.75, 1].map(f => Math.round(max * f));
  return (
    <svg width={w} height={h} viewBox={`0 0 ${w} ${h}`}>
      {/* Grid */}
      {yTicks.map((t, i) => {
        const y = padT + (1 - i / 4) * (h - padT - padB);
        return (
          <g key={i}>
            <line x1={padL} y1={y} x2={w - padR} y2={y} stroke="var(--line-hair)" strokeDasharray={i === 0 ? "0" : "2 3"} />
            <text x={padL - 6} y={y} fontSize="10" fill="var(--ink-4)" textAnchor="end" dominantBaseline="middle" fontFamily="var(--font-num)">{t}{yUnit}</text>
          </g>
        );
      })}
      {/* Baseline */}
      {baseline && (
        <path d={baseline.map((v, i) => `${i ? "L" : "M"} ${px(i).toFixed(1)} ${py(v).toFixed(1)}`).join(" ")}
              fill="none" stroke="var(--ink-3)" strokeWidth="1.2" strokeDasharray="3 3" />
      )}
      {/* Area */}
      <path d={area} fill={color} opacity="0.12" />
      <path d={path} fill="none" stroke={color} strokeWidth="2" strokeLinecap="round" strokeLinejoin="round" />
      {/* End dot */}
      <circle cx={px(data.length - 1)} cy={py(data[data.length - 1])} r={4} fill="#FFF" stroke={color} strokeWidth="2" />
    </svg>
  );
};

// --- Heatmap overlay SVG (for face analysis viz) ---
const HeatmapOverlay = ({ kind = "pores" }) => {
  // Approximate face regions
  const specs = {
    pores:   [ // nose + cheeks density
      { cx: 50, cy: 52, r: 7, fill: "rgba(255, 80, 60, 0.45)" },
      { cx: 38, cy: 56, r: 9, fill: "rgba(255, 120, 60, 0.32)" },
      { cx: 62, cy: 56, r: 9, fill: "rgba(255, 120, 60, 0.32)" },
    ],
    sebum:   [
      { cx: 50, cy: 32, r: 12, fill: "rgba(255, 200, 60, 0.45)" },
      { cx: 50, cy: 52, r: 8,  fill: "rgba(255, 200, 60, 0.55)" },
    ],
    redness: [
      { cx: 38, cy: 60, r: 10, fill: "rgba(220, 60, 70, 0.38)" },
      { cx: 62, cy: 60, r: 10, fill: "rgba(220, 60, 70, 0.38)" },
      { cx: 50, cy: 56, r: 6,  fill: "rgba(220, 60, 70, 0.42)" },
    ],
    pigment: [
      { cx: 40, cy: 48, r: 3, fill: "rgba(140, 80, 50, 0.6)" },
      { cx: 60, cy: 50, r: 2.5, fill: "rgba(140, 80, 50, 0.6)" },
      { cx: 35, cy: 64, r: 2, fill: "rgba(140, 80, 50, 0.6)" },
      { cx: 65, cy: 65, r: 2.5, fill: "rgba(140, 80, 50, 0.6)" },
      { cx: 50, cy: 70, r: 2, fill: "rgba(140, 80, 50, 0.6)" },
    ],
    wrinkle: [
      { cx: 50, cy: 30, r: 14, fill: "rgba(120, 100, 180, 0.20)" },
      { cx: 38, cy: 42, r: 5, fill: "rgba(120, 100, 180, 0.32)" },
      { cx: 62, cy: 42, r: 5, fill: "rgba(120, 100, 180, 0.32)" },
    ],
  }[kind] || [];
  return (
    <svg className="heatmap" viewBox="0 0 100 100" preserveAspectRatio="none">
      <defs>
        <filter id={`blur-${kind}`}><feGaussianBlur stdDeviation="3.2" /></filter>
      </defs>
      <g filter={`url(#blur-${kind})`}>
        {specs.map((s, i) => <circle key={i} {...s} />)}
      </g>
    </svg>
  );
};

// --- Coverage gauge (linear) ---
const CoverageGauge = ({ value = 0.6, label, color }) => (
  <div>
    <div style={{ display: "flex", justifyContent: "space-between", marginBottom: 6 }}>
      <span style={{ fontSize: 12, fontWeight: 500, color: "var(--ink-2)" }}>{label}</span>
      <span className="num" style={{ fontSize: 12, fontWeight: 600, color: "var(--ink-1)" }}>{Math.round(value * 100)}%</span>
    </div>
    <div style={{ height: 6, background: "var(--bg-subtle)", borderRadius: 999, overflow: "hidden" }}>
      <div style={{ height: "100%", width: `${value * 100}%`, background: color || "var(--phase-tint)", borderRadius: 999, transition: "width 700ms cubic-bezier(0.2, 0.6, 0.2, 1)" }} />
    </div>
  </div>
);

Object.assign(window, { ScoreBar, Donut, Sparkline, MiniBars, Radar, HBarChart, LineChart, HeatmapOverlay, CoverageGauge });
