'use client';
import { useId, useRef, useState } from 'react';
import type { MouseEvent as ChartMouseEvent } from 'react';

/* Light tints anchored on the primary brand colour (#0B1626). */
const PALETTE: Record<string, string> = {
  Open: '#C9D4E4', Assigned: '#A9C3E6', 'In Progress': '#7FA8D9', 'On Hold': '#B9A8E0',
  Completed: '#A8DDBB', Overdue: '#F2A9A9', Cancelled: '#DDE3EB',
  Low: '#DDE3EB', Medium: '#A9C3E6', High: '#5B7FA6', Critical: '#0B1626',
  Registered: '#C9D4E4', 'Testing Scheduled': '#A9C3E6', 'In Testing': '#7FA8D9',
  'Testing Completed': '#A8DDBB', Expired: '#F2A9A9',
  L1: '#A9C3E6', L2: '#5B7FA6', L3: '#0B1626',
};

const FALLBACKS = ['#A9C3E6', '#7FA8D9', '#B9A8E0', '#A8DDBB', '#F2C894', '#C9D4E4', '#5B7FA6'];

function colorFor(label: string, i = 0) {
  return PALETTE[label] ?? FALLBACKS[i % FALLBACKS.length];
}

export type Row = { label: string; value: number };

function polar(cx: number, cy: number, r: number, deg: number): [number, number] {
  const a = ((deg - 90) * Math.PI) / 180;
  return [cx + r * Math.cos(a), cy + r * Math.sin(a)];
}

function share(v: number, total: number): string {
  return total ? `${Math.round((v / total) * 100)}%` : '—';
}

/** Floating cursor tooltip (dark pill). Positioned by the parent's mouse-move handler. */
function Tip({ x, y, children }: { x: number; y: number; children: React.ReactNode }) {
  return (
    <div aria-hidden="true"
      className="absolute z-10 pointer-events-none px-2.5 py-1.5 rounded-lg text-xs font-semibold text-white shadow-lg whitespace-nowrap"
      style={{ left: x, top: y, transform: 'translate(-50%, -135%)', background: '#0f172a' }}>
      {children}
    </div>
  );
}

function useTip() {
  const wrapRef = useRef<HTMLDivElement>(null);
  const [pos, setPos] = useState<{ x: number; y: number } | null>(null);
  const move = (e: ChartMouseEvent) => {
    const box = wrapRef.current?.getBoundingClientRect();
    if (box) setPos({ x: e.clientX - box.left, y: e.clientY - box.top });
  };
  return { wrapRef, pos, move, hide: () => setPos(null) };
}

/** Big SVG pie — hover/tap a slice for "Label — value (share%)". No side legend. */
export function Pie({ rows }: { rows: Row[] }) {
  const total = rows.reduce((s, r) => s + r.value, 0);
  const [hot, setHot] = useState<number | null>(null);
  const { wrapRef, pos, move, hide } = useTip();
  if (!total) return <p className="text-sm text-slate-500">No data yet.</p>;
  const colors = rows.map((r, i) => colorFor(r.label, i));
  const cx = 110; const cy = 110; const R = 90;
  let acc = 0;
  const arcs = rows
    .filter((r) => r.value > 0)
    .map((s) => {
      const a0 = (acc / total) * 360;
      acc += s.value;
      return { s, a0, a1: (acc / total) * 360, ci: rows.indexOf(s) };
    });
  const hotArc = hot != null ? arcs[hot] : null;
  const leave = () => { setHot(null); hide(); };
  return (
    <div ref={wrapRef} className="relative" onMouseMove={move} onMouseLeave={leave}>
      <svg viewBox="0 0 220 220" className="w-full max-w-72 mx-auto" role="img"
        aria-label={rows.map((x) => `${x.label}: ${x.value} (${share(x.value, total)})`).join(', ')}>
        {arcs.map((a, i) => {
          const rr = hot === i ? R + 9 : R;
          const dim = hot != null && hot !== i;
          const common = {
            fill: colors[a.ci], stroke: '#fff', strokeWidth: 2.5, strokeLinejoin: 'round' as const,
            opacity: dim ? 0.45 : 1, style: { cursor: 'pointer', transition: 'opacity 0.15s ease' },
            onMouseEnter: () => setHot(i), onFocus: () => setHot(i), onBlur: leave, tabIndex: 0,
          };
          if (a.a1 - a.a0 >= 359.99) {
            return <circle key={a.s.label} cx={cx} cy={cy} r={rr} {...common} />;
          }
          const [x0, y0] = polar(cx, cy, rr, a.a0);
          const [x1, y1] = polar(cx, cy, rr, a.a1);
          return (
            <path key={a.s.label}
              d={`M ${cx} ${cy} L ${x0.toFixed(2)} ${y0.toFixed(2)} A ${rr} ${rr} 0 ${a.a1 - a.a0 > 180 ? 1 : 0} 1 ${x1.toFixed(2)} ${y1.toFixed(2)} Z`}
              {...common} />
          );
        })}
      </svg>
      {hotArc && pos && (
        <Tip x={pos.x} y={pos.y}>{hotArc.s.label} — {hotArc.s.value} ({share(hotArc.s.value, total)})</Tip>
      )}
      <p className="text-center text-sm h-6" aria-live="polite">
        {hotArc
          ? <span><b>{hotArc.s.label}</b> · {hotArc.s.value} ({share(hotArc.s.value, total)})</span>
          : <span className="text-slate-400">Hover a slice · {total} total</span>}
      </p>
    </div>
  );
}

/** Big ring donut — hover/tap a segment for "Label — value (share%)", mirrored in the center. */
export function Donut({ segments, centerLabel }: { segments: Row[]; centerLabel?: string }) {
  const total = segments.reduce((s, x) => s + x.value, 0);
  const [hot, setHot] = useState<number | null>(null);
  const { wrapRef, pos, move, hide } = useTip();
  if (!total) return <p className="text-sm text-slate-500">Nothing escalated — all clear.</p>;
  const colors = segments.map((s) => colorFor(s.label));
  const C = 76; const R = 58; const SW = 20;
  let acc = 0;
  const segs = segments.map((s, i) => {
    const start = acc;
    acc += s.value / total;
    return { s, start, frac: s.value / total, color: colors[i] };
  });
  const hotSeg = hot != null ? segs[hot] : null;
  const circ = 2 * Math.PI * R;
  const leave = () => { setHot(null); hide(); };
  return (
    <div ref={wrapRef} className="relative" onMouseMove={move} onMouseLeave={leave}>
      <svg viewBox="0 0 152 152" className="w-full max-w-64 mx-auto" role="img"
        aria-label={segments.map((s) => `${s.label}: ${s.value} (${share(s.value, total)})`).join(', ')}>
        <circle cx={C} cy={C} r={R} fill="none" stroke="#f1f5f9" strokeWidth={SW} />
        {segs.map((g, i) => (
          <circle key={g.s.label} cx={C} cy={C} r={R} fill="none"
            stroke={g.color} strokeWidth={hot === i ? SW + 6 : SW}
            strokeDasharray={`${(g.frac * circ).toFixed(2)} ${circ.toFixed(2)}`}
            strokeDashoffset={(-g.start * circ).toFixed(2)}
            transform={`rotate(-90 ${C} ${C})`} strokeLinecap="butt"
            opacity={hot != null && hot !== i ? 0.45 : 1}
            style={{ cursor: 'pointer', transition: 'opacity 0.15s ease, stroke-width 0.15s ease' }}
            onMouseEnter={() => setHot(i)} onFocus={() => setHot(i)} onBlur={leave} tabIndex={0} />
        ))}
        <text x={C} y={hotSeg ? C - 2 : C - 1} textAnchor="middle" fontSize={hotSeg ? 22 : 24} fontWeight="800" fill="currentColor">
          {hotSeg ? hotSeg.s.value : total}
        </text>
        <text x={C} y={C + 16} textAnchor="middle" fontSize="10" fill="#64748b">
          {hotSeg ? `${hotSeg.s.label} ${share(hotSeg.s.value, total)}` : (centerLabel ?? 'escalated')}
        </text>
      </svg>
      {hotSeg && pos && (
        <Tip x={pos.x} y={pos.y}>{hotSeg.s.label} — {hotSeg.s.value} ({share(hotSeg.s.value, total)})</Tip>
      )}
      <p className="text-center text-sm h-6" aria-live="polite">
        {hotSeg
          ? <span><b>{hotSeg.s.label}</b> · {hotSeg.s.value} ({share(hotSeg.s.value, total)})</span>
          : <span className="text-slate-400">Hover a segment · {total} total</span>}
      </p>
    </div>
  );
}

/** Big vertical bars with gridlines, hover tooltips and value labels. */
export function Bars({ rows }: { rows: Row[] }) {
  const total = rows.reduce((s, r) => s + r.value, 0);
  const [hot, setHot] = useState<number | null>(null);
  const { wrapRef, pos, move, hide } = useTip();
  if (!rows.length) return <p className="text-sm text-slate-500">No data yet.</p>;
  const max = Math.max(1, ...rows.map((r) => r.value));
  const W = 380; const H = 215; const padL = 32; const padB = 28; const padT = 24;
  const innerW = W - padL - 8; const innerH = H - padT - padB;
  const step = Math.max(1, Math.ceil(max / 4));
  const yMax = step * 4;
  const slot = innerW / rows.length;
  const bw = Math.min(56, slot * 0.55);
  const hotRow = hot != null ? rows[hot] : null;
  const leave = () => { setHot(null); hide(); };
  const uid = useId().replace(/[^a-zA-Z0-9]/g, '');
  return (
    <div ref={wrapRef} className="relative" role="img"
      aria-label={rows.map((r) => `${r.label}: ${r.value}`).join(', ')}
      onMouseMove={move} onMouseLeave={leave}>
      <svg viewBox={`0 0 ${W} ${H}`} className="w-full">
        {[0, 1, 2, 3, 4].map((g) => {
          const y = padT + innerH - (g / 4) * innerH;
          return (
            <g key={g}>
              <line x1={padL} y1={y} x2={W - 4} y2={y} stroke={g === 0 ? '#cbd5e1' : '#eef2f7'} strokeWidth="1" />
              <text x={padL - 5} y={y + 3.5} textAnchor="end" fontSize="9" fill="#94a3b8">{g * step}</text>
            </g>
          );
        })}
        {rows.map((r, i) => {
          const h = Math.max(r.value > 0 ? 5 : 0, (r.value / yMax) * innerH);
          const x = padL + slot * i + (slot - bw) / 2;
          const y = padT + innerH - h;
          const c = colorFor(r.label, i);
          const gid = `dbg-${uid}-${i}`;
          const dim = hot != null && hot !== i;
          return (
            <g key={`${r.label}-${i}`} opacity={dim ? 0.45 : 1}
              style={{ cursor: 'pointer', transition: 'opacity 0.15s ease' }}
              onMouseEnter={() => setHot(i)} onFocus={() => setHot(i)} onBlur={leave} tabIndex={0}>
              <defs>
                <linearGradient id={gid} x1="0" y1="0" x2="0" y2="1">
                  <stop offset="0%" stopColor={c} />
                  <stop offset="100%" stopColor={c} stopOpacity="0.55" />
                </linearGradient>
              </defs>
              <text x={x + bw / 2} y={y - 6} textAnchor="middle" fontSize="12" fontWeight="800" fill="#334155">{r.value}</text>
              <rect x={x} y={y} width={bw} height={h} rx="6" fill={`url(#${gid})`} />
            </g>
          );
        })}
      </svg>
      <div className="flex" style={{ marginLeft: `${(padL / W) * 100}%` }}>
        {rows.map((r, i) => (
          <span key={`${r.label}-${i}`} className="text-xs text-slate-500 text-center leading-tight truncate px-1"
            style={{ width: `${innerW / rows.length / W * 100}%` }} title={r.label}>{r.label}</span>
        ))}
      </div>
      {hotRow && pos && (
        <Tip x={pos.x} y={pos.y}>{hotRow.label} — {hotRow.value}{total ? ` (${share(hotRow.value, total)})` : ''}</Tip>
      )}
    </div>
  );
}

/** Gradient horizontal bars — hover a row for its share tooltip. */
export function HBars({ rows }: { rows: Row[] }) {
  const total = rows.reduce((s, r) => s + r.value, 0);
  const max = Math.max(1, ...rows.map((r) => r.value));
  const [hot, setHot] = useState<number | null>(null);
  if (!rows.length) return <p className="text-sm text-slate-500">No data yet.</p>;
  return (
    <div className="space-y-3" role="img" aria-label={rows.map((r) => `${r.label}: ${r.value}`).join(', ')}>
      {rows.map((r, i) => {
        const c = colorFor(r.label, i);
        const isHot = hot === i;
        return (
          <div key={r.label} className="relative rounded-lg px-2 -mx-2 py-1 transition"
            style={{ background: isHot ? '#f1f5f9' : undefined }}
            onMouseEnter={() => setHot(i)} onMouseLeave={() => setHot(null)}
            onFocus={() => setHot(i)} onBlur={() => setHot(null)} tabIndex={0}>
            <div className="flex items-baseline gap-2 text-sm mb-1">
              <span className="truncate text-slate-600 text-xs" title={r.label}>{r.label}</span>
              <b className="ml-auto tabular-nums text-sm">{r.value}</b>
            </div>
            <div className="h-3.5 rounded-full bg-slate-100 overflow-hidden">
              <div className="h-full rounded-full transition-all"
                style={{ width: `${Math.round((r.value / max) * 100)}%`, background: `linear-gradient(90deg, ${c}, ${c}99)` }} />
            </div>
            {isHot && (
              <div aria-hidden="true"
                className="absolute z-10 pointer-events-none px-2.5 py-1.5 rounded-lg text-xs font-semibold text-white shadow-lg whitespace-nowrap"
                style={{ right: 8, top: -6, transform: 'translateY(-100%)', background: '#0f172a' }}>
                {r.label} — {r.value} ({share(r.value, total)})
              </div>
            )}
          </div>
        );
      })}
    </div>
  );
}

export function StatCard({ label, value, sub, tint, icon }: { label: string; value: any; sub?: string; tint: string; icon?: string }) {
  return (
    <div className="card relative overflow-hidden transition hover:shadow-md">
      <div className="absolute inset-x-0 top-0 h-1" style={{ background: `linear-gradient(90deg, ${tint}, #0B1626)` }} />
      <div className="flex items-start gap-3">
        <div className="flex-1 min-w-0">
          <p className="text-xs font-semibold uppercase tracking-wider text-slate-500">{label}</p>
          <p className="text-3xl font-extrabold tabular-nums mt-1" style={{ color: tint }}>{value ?? '—'}</p>
        </div>
        {icon && (
          <span aria-hidden="true" className="inline-flex w-11 h-11 shrink-0 items-center justify-center rounded-xl text-xl"
            style={{ background: `color-mix(in srgb, ${tint} 16%, transparent)`, color: tint }}>
            {icon}
          </span>
        )}
      </div>
      {sub && <p className="text-xs text-slate-500 mt-1.5">{sub}</p>}
    </div>
  );
}

export function DashboardCharts({ action, sample }: { action: any; sample: any }) {
  const statusRows: Row[] = (action?.byStatus ?? []).map((r: any) => ({ label: r.status, value: Number(r.c) }));
  const prioOrder = ['Critical', 'High', 'Medium', 'Low'];
  const prioRows: Row[] = (action?.byPriority ?? [])
    .map((r: any) => ({ label: r.priority, value: Number(r.c) }))
    .sort((x: Row, y: Row) => prioOrder.indexOf(x.label) - prioOrder.indexOf(y.label));
  const deptRows: Row[] = (action?.byDepartment ?? []).map((r: any) => ({ label: r.name ?? '—', value: Number(r.c) }));
  const dueRows: Row[] = (action?.dueBuckets ?? []).map((r: any) => ({ label: r.bucket, value: Number(r.c) }));
  const escMap = new Map<string, number>((action?.byEscalation ?? []).map((r: any) => [String(r.level), Number(r.c)]));
  const escSegs: Row[] = [
    { label: 'L1', value: Number(escMap.get('1') ?? action?.escL1 ?? 0) },
    { label: 'L2', value: Number(escMap.get('2') ?? action?.escL2 ?? 0) },
    { label: 'L3', value: Number(escMap.get('3') ?? action?.escL3 ?? 0) },
  ];
  const sampleRows: Row[] = (sample?.byStatus ?? []).map((r: any) => ({ label: r.status, value: Number(r.c) }));
  const testRows: Row[] = (sample?.testingByDay ?? []).map((r: any) => ({
    label: String(r.date).slice(5),
    value: Number(r.c),
  }));

  return (
    <div className="grid md:grid-cols-2 gap-3">
      <div className="card space-y-3">
        <h2 className="font-medium">Deviations by status <span className="text-xs font-normal text-slate-400">({action?.total ?? 0} total)</span></h2>
        <Pie rows={statusRows} />
      </div>
      <div className="card space-y-3">
        <h2 className="font-medium">Escalations <span className="text-xs font-normal text-slate-400">L1 due-date · L2 management · L3 critical</span></h2>
        <Donut segments={escSegs} />
      </div>
      <div className="card space-y-3">
        <h2 className="font-medium">Priority mix</h2>
        <HBars rows={prioRows} />
      </div>
      <div className="card space-y-3">
        <h2 className="font-medium">Due-date pipeline <span className="text-xs font-normal text-slate-400">previous & current month</span></h2>
        <Bars rows={dueRows} />
      </div>
      <div className="card space-y-3">
        <h2 className="font-medium">QC samples by status <span className="text-xs font-normal text-slate-400">({sample?.total ?? 0} total)</span></h2>
        <Pie rows={sampleRows} />
      </div>
      <div className="card space-y-3">
        <h2 className="font-medium">Deviations by department</h2>
        <HBars rows={deptRows} />
      </div>
      <div className="card space-y-3 md:col-span-2">
        <h2 className="font-medium">Lab testing load — next 7 days</h2>
        <Bars rows={testRows} />
      </div>
    </div>
  );
}
