// Insurance Portal — components

const { useState, useEffect, useRef, useMemo, useCallback } = React;

// ─── Ticker ────────────────────────────────────────────
function InsTicker({ value, decimals = 0, duration = 700, prefix = '', suffix = '', className }) {
  const [display, setDisplay] = useState(value);
  const fromRef = useRef(value);
  const startRef = useRef(0);
  const rafRef = useRef(0);

  useEffect(() => {
    fromRef.current = display;
    startRef.current = performance.now();
    const tick = (now) => {
      const t = Math.min(1, (now - startRef.current) / duration);
      const eased = 1 - Math.pow(1 - t, 3);
      const v = fromRef.current + (value - fromRef.current) * eased;
      setDisplay(v);
      if (t < 1) rafRef.current = requestAnimationFrame(tick);
    };
    rafRef.current = requestAnimationFrame(tick);
    return () => cancelAnimationFrame(rafRef.current);
  }, [value, duration]);

  const formatted = display.toLocaleString('en-IN', {
    minimumFractionDigits: decimals,
    maximumFractionDigits: decimals,
  });
  return <span className={className}>{prefix}{formatted}{suffix}</span>;
}

// ─── Animated bar chart ────────────────────────────────
function InsBars({ data, color, height = 80 }) {
  const max = Math.max(...data) || 1;
  return (
    <div className="ins-bars" style={{ height }}>
      {data.map((v, i) => (
        <div key={i} className="ins-bar" style={{
          height: `${(v / max) * 100}%`,
          background: `linear-gradient(to top, ${color}, ${color}88)`,
          animationDelay: `${i * 30}ms`,
        }}/>
      ))}
    </div>
  );
}

// ─── Sparkline ─────────────────────────────────────────
function InsSpark({ data, color = '#06b6d4', width = 120, height = 36, fill = true }) {
  if (!data || data.length === 0) return null;
  const min = Math.min(...data), max = Math.max(...data);
  const range = max - min || 1;
  const step = width / (data.length - 1);
  const pts = data.map((v, i) => `${i * step},${height - ((v - min) / range) * (height - 4) - 2}`);
  const linePath = `M ${pts.join(' L ')}`;
  const fillPath = `${linePath} L ${width},${height} L 0,${height} Z`;
  return (
    <svg width={width} height={height} style={{ display: 'block', overflow: 'visible' }}>
      <defs>
        <linearGradient id={`spark-${color.replace('#', '')}`} x1="0" y1="0" x2="0" y2="1">
          <stop offset="0%" stopColor={color} stopOpacity="0.4"/>
          <stop offset="100%" stopColor={color} stopOpacity="0"/>
        </linearGradient>
      </defs>
      {fill && <path d={fillPath} fill={`url(#spark-${color.replace('#', '')})`} />}
      <path d={linePath} stroke={color} strokeWidth="1.8" fill="none" strokeLinejoin="round" strokeLinecap="round"/>
      <circle cx={(data.length - 1) * step} cy={height - ((data[data.length-1] - min) / range) * (height - 4) - 2} r="3" fill={color}/>
    </svg>
  );
}

// ─── Trend line chart ───────────────────────────────────
function InsTrendChart({ data, color = '#06b6d4', height = 240 }) {
  const ref = useRef(null);
  const [dim, setDim] = useState({ w: 600, h: height });

  useEffect(() => {
    const update = () => {
      if (ref.current) setDim({ w: ref.current.clientWidth, h: height });
    };
    update();
    window.addEventListener('resize', update);
    return () => window.removeEventListener('resize', update);
  }, [height]);

  const padL = 40, padR = 20, padT = 16, padB = 30;
  const w = dim.w - padL - padR;
  const h = dim.h - padT - padB;
  const values = data.map(d => d.matchRate);
  const min = Math.min(...values) - 2, max = Math.max(...values) + 2;
  const range = max - min;
  const stepX = w / (data.length - 1);
  const pts = data.map((d, i) => ({ x: padL + i * stepX, y: padT + h - ((d.matchRate - min) / range) * h }));
  const linePath = `M ${pts.map(p => `${p.x},${p.y}`).join(' L ')}`;
  const fillPath = `${linePath} L ${padL + w},${padT + h} L ${padL},${padT + h} Z`;

  // Y-axis ticks
  const ticks = [min, (min + max) / 2, max].map(v => parseFloat(v.toFixed(1)));

  return (
    <div ref={ref} style={{ width: '100%' }}>
      <svg width={dim.w} height={dim.h} style={{ display: 'block', overflow: 'visible' }}>
        <defs>
          <linearGradient id="ins-trend-fill" x1="0" y1="0" x2="0" y2="1">
            <stop offset="0%" stopColor={color} stopOpacity="0.28"/>
            <stop offset="100%" stopColor={color} stopOpacity="0"/>
          </linearGradient>
        </defs>
        {/* Grid */}
        {ticks.map((t, i) => {
          const y = padT + h - ((t - min) / range) * h;
          return (
            <g key={i}>
              <line x1={padL} y1={y} x2={padL + w} y2={y} stroke="var(--ins-border)" strokeDasharray="3,4" strokeWidth="1"/>
              <text x={padL - 8} y={y + 4} fill="var(--ins-muted)" fontSize="10" textAnchor="end" fontFamily="JetBrains Mono">{t}%</text>
            </g>
          );
        })}
        {/* X-axis */}
        {data.filter((_, i) => i % 5 === 0).map((d, idx) => {
          const i = data.indexOf(d);
          const x = padL + i * stepX;
          return <text key={idx} x={x} y={dim.h - 10} fill="var(--ins-muted)" fontSize="10" textAnchor="middle" fontFamily="JetBrains Mono">D{d.day}</text>;
        })}
        {/* Fill */}
        <path d={fillPath} fill="url(#ins-trend-fill)"/>
        {/* Line */}
        <path d={linePath} stroke={color} strokeWidth="2.2" fill="none" strokeLinejoin="round" strokeLinecap="round" filter="drop-shadow(0 2px 8px rgba(6,182,212,0.4))"/>
        {/* Dots on every 5th point */}
        {pts.map((p, i) => i % 5 === 0 ? (
          <circle key={i} cx={p.x} cy={p.y} r="3.5" fill={color} stroke="var(--ins-surface-card)" strokeWidth="1.5"/>
        ) : null)}
      </svg>
    </div>
  );
}

// ─── Fraud level badge ──────────────────────────────────
function FraudBadge({ level, size = 'md' }) {
  const meta = window.INS_FRAUD_LEVELS[level];
  if (!meta) return null;
  const fs = size === 'sm' ? 10 : 11;
  const pad = size === 'sm' ? '3px 8px' : '5px 11px';
  return (
    <span style={{
      display: 'inline-flex', alignItems: 'center', gap: 6,
      padding: pad, background: meta.bg, color: meta.color,
      borderRadius: 999, fontSize: fs, fontWeight: 700, letterSpacing: '0.04em',
      textTransform: 'uppercase', whiteSpace: 'nowrap',
    }}>
      <span style={{ width: 6, height: 6, borderRadius: '50%', background: meta.color }}/>
      {meta.label}
    </span>
  );
}

// ─── Toast (reused pattern) ─────────────────────────────
const InsToastContext = React.createContext(null);
function InsToastProvider({ children }) {
  const [toasts, setToasts] = useState([]);
  const push = useCallback((t) => {
    const id = Math.random().toString(36).slice(2);
    setToasts(prev => [...prev, { id, ...t }]);
    if (t.duration !== 0) setTimeout(() => setToasts(prev => prev.filter(x => x.id !== id)), t.duration || 4500);
  }, []);
  const dismiss = useCallback((id) => setToasts(prev => prev.filter(x => x.id !== id)), []);
  return (
    <InsToastContext.Provider value={{ push, dismiss }}>
      {children}
      <div className="ins-toast-stack">
        {toasts.map(t => (
          <div key={t.id} className={`ins-toast ins-toast-${t.sev || 'info'}`}>
            <div className="ins-toast-icon">{t.sev === 'success' ? '✓' : t.sev === 'alert' ? '!' : 'ℹ'}</div>
            <div style={{ flex: 1 }}>
              <div style={{ fontWeight: 600, fontSize: 13 }}>{t.title}</div>
              {t.body && <div style={{ fontSize: 12, opacity: 0.75, marginTop: 2 }}>{t.body}</div>}
            </div>
            <button onClick={() => dismiss(t.id)} className="ins-toast-x">×</button>
          </div>
        ))}
      </div>
    </InsToastContext.Provider>
  );
}
function useInsToast() { return React.useContext(InsToastContext); }

// ─── Icons (reuse pattern, distinct set) ────────────────
const InsIcon = {
  Home: (p) => <svg width="18" height="18" viewBox="0 0 24 24" fill="none" {...p}><path d="m3 9 9-7 9 7v11a2 2 0 0 1-2 2h-4v-7H10v7H6a2 2 0 0 1-2-2V9z" stroke="currentColor" strokeWidth="1.8" strokeLinecap="round" strokeLinejoin="round"/></svg>,
  Search: (p) => <svg width="18" height="18" viewBox="0 0 24 24" fill="none" {...p}><circle cx="11" cy="11" r="8" stroke="currentColor" strokeWidth="1.8"/><path d="m21 21-4.35-4.35" stroke="currentColor" strokeWidth="1.8" strokeLinecap="round"/></svg>,
  Scan: (p) => <svg width="18" height="18" viewBox="0 0 24 24" fill="none" {...p}><path d="M3 7V5a2 2 0 0 1 2-2h2M17 3h2a2 2 0 0 1 2 2v2M21 17v2a2 2 0 0 1-2 2h-2M7 21H5a2 2 0 0 1-2-2v-2M7 12h10" stroke="currentColor" strokeWidth="1.8" strokeLinecap="round" strokeLinejoin="round"/></svg>,
  Shield: (p) => <svg width="18" height="18" viewBox="0 0 24 24" fill="none" {...p}><path d="M12 22s8-4 8-10V5l-8-3-8 3v7c0 6 8 10 8 10z" stroke="currentColor" strokeWidth="1.8" strokeLinecap="round" strokeLinejoin="round"/></svg>,
  Chart: (p) => <svg width="18" height="18" viewBox="0 0 24 24" fill="none" {...p}><path d="M3 3v18h18M7 14l4-4 4 4 5-5" stroke="currentColor" strokeWidth="1.8" strokeLinecap="round" strokeLinejoin="round"/></svg>,
  History: (p) => <svg width="18" height="18" viewBox="0 0 24 24" fill="none" {...p}><path d="M3 12a9 9 0 1 0 3-6.7M3 3v6h6M12 7v5l3 2" stroke="currentColor" strokeWidth="1.8" strokeLinecap="round" strokeLinejoin="round"/></svg>,
  Settings: (p) => <svg width="18" height="18" viewBox="0 0 24 24" fill="none" {...p}><circle cx="12" cy="12" r="3" stroke="currentColor" strokeWidth="1.8"/><path d="M19.4 15a1.65 1.65 0 0 0 .33 1.82l.06.06a2 2 0 0 1 0 2.83 2 2 0 0 1-2.83 0l-.06-.06a1.65 1.65 0 0 0-1.82-.33 1.65 1.65 0 0 0-1 1.51V21a2 2 0 0 1-4 0v-.09a1.65 1.65 0 0 0-1-1.51 1.65 1.65 0 0 0-1.82.33l-.06.06a2 2 0 0 1-2.83-2.83l.06-.06a1.65 1.65 0 0 0 .33-1.82 1.65 1.65 0 0 0-1.51-1H3a2 2 0 0 1 0-4h.09a1.65 1.65 0 0 0 1.51-1 1.65 1.65 0 0 0-.33-1.82l-.06-.06a2 2 0 0 1 2.83-2.83l.06.06a1.65 1.65 0 0 0 1.82.33H9a1.65 1.65 0 0 0 1-1.51V3a2 2 0 0 1 4 0v.09a1.65 1.65 0 0 0 1 1.51 1.65 1.65 0 0 0 1.82-.33l.06-.06a2 2 0 0 1 2.83 2.83l-.06.06a1.65 1.65 0 0 0-.33 1.82V9a1.65 1.65 0 0 0 1.51 1H21a2 2 0 0 1 0 4h-.09a1.65 1.65 0 0 0-1.51 1z" stroke="currentColor" strokeWidth="1.8" strokeLinecap="round" strokeLinejoin="round"/></svg>,
  Sun: (p) => <svg width="18" height="18" viewBox="0 0 24 24" fill="none" {...p}><circle cx="12" cy="12" r="4" stroke="currentColor" strokeWidth="1.8"/><path d="M12 2v2M12 20v2M4.93 4.93l1.41 1.41M17.66 17.66l1.41 1.41M2 12h2M20 12h2M4.93 19.07l1.41-1.41M17.66 6.34l1.41-1.41" stroke="currentColor" strokeWidth="1.8" strokeLinecap="round"/></svg>,
  Moon: (p) => <svg width="18" height="18" viewBox="0 0 24 24" fill="none" {...p}><path d="M21 12.79A9 9 0 1 1 11.21 3 7 7 0 0 0 21 12.79z" stroke="currentColor" strokeWidth="1.8" strokeLinejoin="round"/></svg>,
  ArrowRight: (p) => <svg width="14" height="14" viewBox="0 0 24 24" fill="none" {...p}><path d="M5 12h14m-6-6 6 6-6 6" stroke="currentColor" strokeWidth="2" strokeLinecap="round" strokeLinejoin="round"/></svg>,
  ArrowUp: (p) => <svg width="14" height="14" viewBox="0 0 24 24" fill="none" {...p}><path d="M12 19V5m-7 7 7-7 7 7" stroke="currentColor" strokeWidth="2" strokeLinecap="round" strokeLinejoin="round"/></svg>,
  ArrowDown: (p) => <svg width="14" height="14" viewBox="0 0 24 24" fill="none" {...p}><path d="M12 5v14m-7-7 7 7 7-7" stroke="currentColor" strokeWidth="2" strokeLinecap="round" strokeLinejoin="round"/></svg>,
  X: (p) => <svg width="14" height="14" viewBox="0 0 24 24" fill="none" {...p}><path d="M18 6 6 18M6 6l12 12" stroke="currentColor" strokeWidth="2" strokeLinecap="round"/></svg>,
  Download: (p) => <svg width="16" height="16" viewBox="0 0 24 24" fill="none" {...p}><path d="M21 15v4a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2v-4M7 10l5 5 5-5M12 15V3" stroke="currentColor" strokeWidth="1.8" strokeLinecap="round" strokeLinejoin="round"/></svg>,
  Filter: (p) => <svg width="14" height="14" viewBox="0 0 24 24" fill="none" {...p}><path d="M22 3H2l8 9.46V19l4 2v-8.54L22 3z" stroke="currentColor" strokeWidth="1.8" strokeLinejoin="round"/></svg>,
  Logout: (p) => <svg width="18" height="18" viewBox="0 0 24 24" fill="none" {...p}><path d="M9 21H5a2 2 0 0 1-2-2V5a2 2 0 0 1 2-2h4M16 17l5-5-5-5M21 12H9" stroke="currentColor" strokeWidth="1.8" strokeLinecap="round" strokeLinejoin="round"/></svg>,
  Check: (p) => <svg width="14" height="14" viewBox="0 0 24 24" fill="none" {...p}><path d="m20 6-11 11-5-5" stroke="currentColor" strokeWidth="2.4" strokeLinecap="round" strokeLinejoin="round"/></svg>,
  Cross: (p) => <svg width="14" height="14" viewBox="0 0 24 24" fill="none" {...p}><path d="M18 6 6 18M6 6l12 12" stroke="currentColor" strokeWidth="2.4" strokeLinecap="round"/></svg>,
  Alert: (p) => <svg width="14" height="14" viewBox="0 0 24 24" fill="none" {...p}><path d="M10.29 3.86 1.82 18a2 2 0 0 0 1.71 3h16.94a2 2 0 0 0 1.71-3L13.71 3.86a2 2 0 0 0-3.42 0zM12 9v4M12 17h.01" stroke="currentColor" strokeWidth="1.8" strokeLinecap="round" strokeLinejoin="round"/></svg>,
  ChevronRight: (p) => <svg width="16" height="16" viewBox="0 0 24 24" fill="none" {...p}><path d="m9 18 6-6-6-6" stroke="currentColor" strokeWidth="2" strokeLinecap="round" strokeLinejoin="round"/></svg>,
  ChevronLeft: (p) => <svg width="16" height="16" viewBox="0 0 24 24" fill="none" {...p}><path d="m15 18-6-6 6-6" stroke="currentColor" strokeWidth="2" strokeLinecap="round" strokeLinejoin="round"/></svg>,
};

Object.assign(window, {
  InsTicker, InsBars, InsSpark, InsTrendChart, FraudBadge,
  InsToastProvider, useInsToast, InsToastContext, InsIcon,
});
