// Dashboard charts (inline SVG, themed)

const useTheme = () => {
  const get = () => {
    const c = getComputedStyle(document.documentElement);
    return {
      ink: c.getPropertyValue('--ink').trim() || '#0E1418',
      muted: c.getPropertyValue('--muted').trim() || '#5A6770',
      rule: c.getPropertyValue('--rule').trim() || '#E5E0D6',
      teal: c.getPropertyValue('--teal').trim() || '#2E5762',
      rust: c.getPropertyValue('--rust').trim() || '#B5532E',
      surface: c.getPropertyValue('--surface').trim() || '#FFFFFF',
    };
  };
  const [t, setT] = React.useState(get);
  React.useEffect(() => {
    const ob = new MutationObserver(() => setT(get()));
    ob.observe(document.body, { attributes: true, attributeFilter: ['class'] });
    return () => ob.disconnect();
  }, []);
  return t;
};

// Animation key: bumps when the stable string key changes (avoids re-trigger on every render)
const useAnimKey = (stableKey) => {
  const ref = React.useRef(0);
  const lastKey = React.useRef(stableKey);
  const [key, setKey] = React.useState(0);
  React.useEffect(() => {
    if (lastKey.current !== stableKey) {
      lastKey.current = stableKey;
      ref.current += 1;
      setKey(ref.current);
    }
  }, [stableKey]);
  return key;
};

const Sparkline = ({ data, color, width = 80, height = 24 }) => {
  if (!data || !data.length) return <svg width={width} height={height}/>;
  const stableKey = `${data.length}:${data[0]}:${data[data.length-1]}`;
  const animKey = useAnimKey(stableKey);
  const min = Math.min(...data), max = Math.max(...data);
  const x = i => (i * width) / Math.max(1, data.length - 1);
  const y = v => height - ((v - min) / Math.max(0.001, max - min)) * (height - 4) - 2;
  const path = data.map((v, i) => `${i === 0 ? "M" : "L"}${x(i)},${y(v)}`).join(" ");
  return (
    <svg width={width} height={height} viewBox={`0 0 ${width} ${height}`}>
      <path key={animKey} className="chart-line-draw" d={path} fill="none" stroke={color} strokeWidth="1.5" strokeLinejoin="round" strokeLinecap="round"/>
    </svg>
  );
};

const TrafficChart = ({ data, metric = "clicks", compare = true }) => {
  const t = useTheme();
  const W = 800, H = 280, P = 36;
  const animKey = useAnimKey(data.length + ":" + (data[0]?.date || ""));
  const [hover, setHover] = React.useState(null);
  const wrapRef = React.useRef(null);

  if (!data.length) return <svg viewBox={`0 0 ${W} ${H}`} style={{ width: "100%", height: "auto" }}/>;

  const max = Math.max(...data.map(d => d[metric])) * 1.15 || 1;
  const x = i => P + (i * (W - 2 * P)) / Math.max(1, data.length - 1);
  const y = v => H - P - (v / max) * (H - 2 * P);
  const path = data.map((d, i) => `${i === 0 ? "M" : "L"}${x(i)},${y(d[metric])}`).join(" ");
  const area = `${path} L${x(data.length - 1)},${H - P} L${x(0)},${H - P} Z`;

  const prev = data.map(d => ({ ...d, [metric]: d[metric] * (0.82 + Math.random() * 0.08) }));
  const prevPath = prev.map((d, i) => `${i === 0 ? "M" : "L"}${x(i)},${y(d[metric])}`).join(" ");

  const fmt = n => n >= 1000 ? (n / 1000).toFixed(1) + "k" : Math.round(n);
  const ticks = [0, 0.25, 0.5, 0.75, 1].map(p => max * p);

  const handleMove = (e) => {
    const svg = e.currentTarget;
    const rect = svg.getBoundingClientRect();
    const px = ((e.clientX - rect.left) / rect.width) * W;
    if (px < P || px > W - P) { setHover(null); return; }
    const ratio = (px - P) / (W - 2 * P);
    const idx = Math.round(ratio * (data.length - 1));
    const clamped = Math.max(0, Math.min(data.length - 1, idx));
    setHover({ idx: clamped, mouseX: e.clientX - rect.left, mouseY: e.clientY - rect.top });
  };

  const fmtFull = (n) => n.toLocaleString("tr-TR");

  return (
    <div ref={wrapRef} style={{ position: "relative" }}>
      <svg viewBox={`0 0 ${W} ${H}`} style={{ width: "100%", height: "auto", display: "block" }}
        onMouseMove={handleMove} onMouseLeave={() => setHover(null)}>
        <defs>
          <linearGradient id="trafGrad" x1="0" x2="0" y1="0" y2="1">
            <stop offset="0%" stopColor={t.teal} stopOpacity="0.22"/>
            <stop offset="100%" stopColor={t.teal} stopOpacity="0"/>
          </linearGradient>
        </defs>
        {ticks.map((v, i) => (
          <g key={i}>
            <line x1={P} x2={W - P} y1={y(v)} y2={y(v)} stroke={t.rule} strokeDasharray="2 4"/>
            <text x={P - 8} y={y(v) + 3} fontSize="10" fontFamily="var(--mono)" fill={t.muted} textAnchor="end">{fmt(v)}</text>
          </g>
        ))}
        <g key={animKey} className="chart-area-fade">
          <path d={area} fill="url(#trafGrad)"/>
        </g>
        {compare && (
          <path key={`prev-${animKey}`} className="chart-line-draw chart-line-draw--slow"
            d={prevPath} fill="none" stroke={t.muted} strokeWidth="1.2" strokeDasharray="3 3" opacity="0.7"/>
        )}
        <path key={`main-${animKey}`} className="chart-line-draw"
          d={path} fill="none" stroke={t.teal} strokeWidth="2"/>

        {/* hover indicators */}
        {hover && (
          <g style={{ pointerEvents: "none" }}>
            <line x1={x(hover.idx)} x2={x(hover.idx)} y1={P - 6} y2={H - P}
              stroke={t.ink} strokeWidth="1" strokeDasharray="2 3" opacity="0.4"/>
            <circle cx={x(hover.idx)} cy={y(data[hover.idx][metric])} r="5"
              fill={t.surface} stroke={t.teal} strokeWidth="2"/>
          </g>
        )}

        {/* x-axis: ~5 evenly spaced labels with collision avoidance */}
        {(() => {
          const n = data.length;
          if (n === 0) return null;
          const targetCount = Math.min(5, n);
          const idxs = [];
          if (targetCount === 1) {
            idxs.push(0);
          } else {
            for (let k = 0; k < targetCount; k++) {
              idxs.push(Math.round((k * (n - 1)) / (targetCount - 1)));
            }
          }
          // de-dup and drop labels that would visually overlap (< 60px apart)
          const minPx = (60 / W) * data.length;
          const filtered = [];
          for (const idx of idxs) {
            if (!filtered.length || idx - filtered[filtered.length - 1] >= minPx - 0.5) {
              filtered.push(idx);
            }
          }
          // ensure last point is always present (drop the second-to-last if too close)
          if (filtered[filtered.length - 1] !== n - 1) {
            if (filtered.length && (n - 1) - filtered[filtered.length - 1] < minPx) {
              filtered.pop();
            }
            filtered.push(n - 1);
          }
          return filtered.map(i => {
            const lbl = data[i]?.label || `d-${n - i}`;
            return (
              <text key={i} x={x(i)} y={H - P + 16} fontSize="10" fontFamily="var(--mono)" fill={t.muted} textAnchor="middle">
                {lbl}
              </text>
            );
          });
        })()}
      </svg>
      {hover && data[hover.idx] && (
        <div className="chart-tooltip" style={{
          left: hover.mouseX + 14,
          top: hover.mouseY - 14,
        }}>
          <div className="chart-tooltip__date">{data[hover.idx].label || `Gün ${hover.idx + 1}`}</div>
          <div className="chart-tooltip__row">
            <span className="chart-tooltip__dot" style={{ background: t.teal }}/>
            <span>Tıklama</span>
            <strong>{fmtFull(data[hover.idx].clicks || 0)}</strong>
          </div>
          <div className="chart-tooltip__row">
            <span className="chart-tooltip__dot" style={{ background: t.muted }}/>
            <span>Gösterim</span>
            <strong>{fmtFull(data[hover.idx].imp || 0)}</strong>
          </div>
        </div>
      )}
    </div>
  );
};

// Donut gauge — animates from empty ring to target on mount/data change
const Donut = ({ value, max = 100, size = 96, label, sub, color }) => {
  const t = useTheme();
  const r = size / 2 - 6;
  const c = 2 * Math.PI * r;
  const targetOff = c * (1 - value / max);
  const [renderedOff, setRenderedOff] = React.useState(c);
  React.useEffect(() => {
    setRenderedOff(c);
    const t1 = setTimeout(() => setRenderedOff(targetOff), 30);
    return () => clearTimeout(t1);
  }, [value, c, targetOff]);
  return (
    <div className="gauge" style={{ width: size, height: size }}>
      <svg width={size} height={size}>
        <circle cx={size/2} cy={size/2} r={r} fill="none" stroke={t.rule} strokeWidth="6"/>
        <circle cx={size/2} cy={size/2} r={r} fill="none" stroke={color || t.teal} strokeWidth="6"
          strokeDasharray={c} strokeDashoffset={renderedOff} strokeLinecap="round"
          style={{ transition: "stroke-dashoffset 1.1s cubic-bezier(0.65, 0.05, 0.36, 1) 0.15s" }}
          transform={`rotate(-90 ${size/2} ${size/2})`}/>
      </svg>
      <div className="gauge__v">
        <strong>{label || value}</strong>
        {sub && <small>{sub}</small>}
      </div>
    </div>
  );
};

const HBar = ({ data, max, accentIdx }) => {
  const t = useTheme();
  const W = 480, rowH = 36, P = 8;
  const H = data.length * rowH + P * 2;
  const xMax = W - 240;
  const [animated, setAnimated] = React.useState(false);
  const dataKey = data.length + ":" + (data[0]?.label || "");
  React.useEffect(() => {
    setAnimated(false);
    const id = setTimeout(() => setAnimated(true), 30);
    return () => clearTimeout(id);
  }, [dataKey]);
  return (
    <svg viewBox={`0 0 ${W} ${H}`} style={{ width: "100%", height: H }}>
      {data.map((d, i) => {
        const w = (d.value / max) * xMax;
        const isYou = i === accentIdx;
        return (
          <g key={`${dataKey}-${d.label}`} className="chart-hbar-row" style={{ animationDelay: `${i * 0.08}s` }}
            transform={`translate(0, ${P + i * rowH})`}>
            <text x="0" y="20" fontSize="12" fontFamily="var(--sans)" fontWeight="500" fill={t.ink}>{d.label}</text>
            <rect x="120" y="10" width={xMax} height="14" rx="3" fill={t.rule} opacity="0.5"/>
            <rect x="120" y="10" width={animated ? w : 0} height="14" rx="3" fill={isYou ? t.rust : t.teal}
              style={{ transition: `width 0.9s cubic-bezier(0.65, 0.05, 0.36, 1) ${0.2 + i * 0.08}s` }}/>
            <text x={W} y="20" fontSize="11" fontFamily="var(--mono)" fill={t.muted} textAnchor="end">{d.display}</text>
          </g>
        );
      })}
    </svg>
  );
};

// Vertical bar chart for monthly aggregates.
const MonthlyBars = ({ data, metric = "clicks" }) => {
  const t = useTheme();
  const W = 800, H = 260, PT = 18, PB = 36, PL = 44, PR = 12;
  const animKey = useAnimKey(data.length + ":" + (data[0]?.ym || ""));
  const [hover, setHover] = React.useState(null);
  const wrapRef = React.useRef(null);

  if (!data.length) return <svg viewBox={`0 0 ${W} ${H}`} style={{ width: "100%", height: "auto" }}/>;

  const max = Math.max(...data.map(d => d[metric])) * 1.15 || 1;
  const innerW = W - PL - PR;
  const innerH = H - PT - PB;
  const slot = innerW / data.length;
  const barW = Math.min(36, slot * 0.62);
  const y = v => PT + innerH - (v / max) * innerH;

  const fmt = n => n >= 1000000 ? (n / 1000000).toFixed(1) + "M" : n >= 1000 ? (n / 1000).toFixed(0) + "k" : Math.round(n);
  const fmtFull = n => (n || 0).toLocaleString("tr-TR");
  const ticks = [0, 0.25, 0.5, 0.75, 1].map(p => max * p);

  return (
    <div ref={wrapRef} style={{ position: "relative" }}>
      <svg viewBox={`0 0 ${W} ${H}`} style={{ width: "100%", height: "auto", display: "block" }}
        onMouseLeave={() => setHover(null)}>
        <defs>
          <linearGradient id="barGrad" x1="0" x2="0" y1="0" y2="1">
            <stop offset="0%" stopColor={t.teal} stopOpacity="1"/>
            <stop offset="100%" stopColor={t.teal} stopOpacity="0.65"/>
          </linearGradient>
        </defs>
        {ticks.map((v, i) => (
          <g key={i}>
            <line x1={PL} x2={W - PR} y1={y(v)} y2={y(v)} stroke={t.rule} strokeDasharray="2 4"/>
            <text x={PL - 8} y={y(v) + 3} fontSize="10" fontFamily="var(--mono)" fill={t.muted} textAnchor="end">{fmt(v)}</text>
          </g>
        ))}
        {data.map((d, i) => {
          const cx = PL + slot * i + slot / 2;
          const v = d[metric];
          const bh = (v / max) * innerH;
          const isHover = hover && hover.idx === i;
          const baseOpacity = d.partial ? 0.42 : 0.92;
          return (
            <g key={`${animKey}-${d.ym}`}>
              <rect
                x={cx - barW / 2}
                y={y(v)}
                width={barW}
                height={bh}
                rx={3}
                fill={d.partial ? t.muted : "url(#barGrad)"}
                opacity={isHover ? Math.min(1, baseOpacity + 0.15) : baseOpacity}
                className="chart-bar-grow"
                style={{ animationDelay: `${i * 0.05}s`, transformOrigin: `${cx}px ${PT + innerH}px` }}
              />
              <rect
                x={cx - slot / 2}
                y={PT}
                width={slot}
                height={innerH}
                fill="transparent"
                onMouseEnter={(e) => {
                  const rect = wrapRef.current.getBoundingClientRect();
                  setHover({ idx: i, mouseX: e.clientX - rect.left, mouseY: e.clientY - rect.top });
                }}
                onMouseMove={(e) => {
                  const rect = wrapRef.current.getBoundingClientRect();
                  setHover({ idx: i, mouseX: e.clientX - rect.left, mouseY: e.clientY - rect.top });
                }}
              />
              <text x={cx} y={H - PB + 14} fontSize="10" fontFamily="var(--mono)"
                fill={d.partial ? t.muted : t.muted}
                opacity={d.partial ? 0.7 : 1}
                textAnchor="middle">{d.label}{d.partial ? "*" : ""}</text>
            </g>
          );
        })}
      </svg>
      {hover && data[hover.idx] && (
        <div className="chart-tooltip" style={{ left: hover.mouseX + 14, top: hover.mouseY - 14 }}>
          <div className="chart-tooltip__date">
            {data[hover.idx].label}
            {data[hover.idx].partial && (
              <span style={{ marginLeft: 6, fontSize: 10, color: t.muted, fontWeight: 400 }}>
                kısmi · {data[hover.idx].days}/{data[hover.idx].daysInMonth} gün
              </span>
            )}
          </div>
          <div className="chart-tooltip__row">
            <span className="chart-tooltip__dot" style={{ background: t.teal }}/>
            <span>Tıklama</span>
            <strong>{fmtFull(data[hover.idx].clicks)}</strong>
          </div>
          <div className="chart-tooltip__row">
            <span className="chart-tooltip__dot" style={{ background: t.muted }}/>
            <span>Gösterim</span>
            <strong>{fmtFull(data[hover.idx].imp)}</strong>
          </div>
        </div>
      )}
    </div>
  );
};

Object.assign(window, { Sparkline, TrafficChart, Donut, HBar, MonthlyBars, useTheme });
