import { useMemo, useRef, useState, useEffect } from 'react';
import { hierarchy, treemap, treemapSquarify } from 'd3-hierarchy';

const INK = '#0A0A0A';
const PAPER = '#F4F1EA';
const STAMP = '#FFD93D';
const VOID = '#E5E1D8';

// Discrete 5-step gradient, void → ink (warm grays)
const GRAY_RAMP = [
  '#D7D2C2',
  '#A8A496',
  '#7A766A',
  '#46443D',
  INK,
];

export interface TreemapLeafIn {
  code: string;
  name: string;
  emoji: string | null;
  value: number;
  contracts: number;
}

interface Props {
  leaves: TreemapLeafIn[];
  height?: number;
}

function fmtRon(v: number): string {
  if (v >= 1_000_000_000) return `${(v / 1_000_000_000).toFixed(2)} mld`;
  if (v >= 1_000_000) return `${(v / 1_000_000).toFixed(1)} mil`;
  if (v >= 1_000) return `${(v / 1_000).toFixed(0)}K`;
  return v.toFixed(0);
}

function fmtRonFull(v: number): string {
  return new Intl.NumberFormat('ro-RO', { maximumFractionDigits: 0 }).format(v);
}

export function Treemap({ leaves, height = 720 }: Props) {
  const containerRef = useRef<HTMLDivElement>(null);
  const [width, setWidth] = useState(1200);
  const [hover, setHover] = useState<string | null>(null);
  const [tooltip, setTooltip] = useState<{ x: number; y: number; leaf: TreemapLeafIn } | null>(null);
  const [flashed, setFlashed] = useState(false);

  useEffect(() => {
    if (!containerRef.current) return;
    const ro = new ResizeObserver((entries) => {
      for (const e of entries) setWidth(Math.max(640, e.contentRect.width));
    });
    ro.observe(containerRef.current);
    setWidth(containerRef.current.clientWidth);
    return () => ro.disconnect();
  }, []);

  useEffect(() => {
    setFlashed(true);
    const t = setTimeout(() => setFlashed(false), 600);
    return () => clearTimeout(t);
  }, []);

  const layout = useMemo(() => {
    if (leaves.length === 0) return null;
    const root = hierarchy<{ name: string; children?: any[]; value?: number }>({
      name: 'root',
      children: leaves.map(l => ({ ...l })),
    } as any).sum((d: any) => d.value || 0).sort((a, b) => (b.value || 0) - (a.value || 0));

    const tm = treemap<any>()
      .tile(treemapSquarify.ratio(1.4))
      .size([width, height - 44]) // 44 = header strip height
      .padding(2)
      .round(true);

    return tm(root);
  }, [leaves, width, height]);

  if (!layout) {
    return (
      <div className="w-full bg-paper border-2 border-ink p-12 text-center">
        <div className="font-mono text-xs uppercase tracking-meta text-ink/60">Nu există date CPV.</div>
      </div>
    );
  }

  const totalVal = layout.value || 1;
  const maxLeaf = Math.max(...layout.leaves().map((l: any) => l.value || 0), 1);

  function colorFor(value: number): string {
    const ratio = value / maxLeaf;
    const idx = Math.min(GRAY_RAMP.length - 1, Math.floor(ratio * GRAY_RAMP.length));
    return GRAY_RAMP[idx];
  }
  function textFor(value: number): string {
    const ratio = value / maxLeaf;
    return ratio > 0.45 ? PAPER : INK;
  }

  return (
    <div ref={containerRef} className="relative w-full bg-paper border-2 border-ink overflow-hidden" style={{ height }}>
      {/* Header strip */}
      <div className="border-b-2 border-ink bg-paper px-4 py-2 flex items-center justify-between" style={{ height: 44 }}>
        <div className="font-mono text-[10px] uppercase tracking-meta text-ink/70">
          CATEGORII CPV · ULTIMELE 12 LUNI · {leaves.length} DIVIZII
        </div>
        <div className="font-mono text-[10px] uppercase tracking-meta text-ink/50 tabular-nums">
          {fmtRon(totalVal)} RON TOTAL
        </div>
      </div>

      <svg width={width} height={height - 44} className="block">
        <g>
          {layout.leaves().map((node: any) => {
            const d = node.data as TreemapLeafIn;
            const w = node.x1 - node.x0;
            const h = node.y1 - node.y0;
            const isHover = hover === d.code;
            const fill = isHover ? STAMP : (flashed ? STAMP : colorFor(node.value || 0));
            const fg = isHover ? INK : (flashed ? INK : textFor(node.value || 0));
            const showLabel = w > 60 && h > 28;
            const showValue = w > 60 && h > 50;
            return (
              <g
                key={d.code}
                style={{ cursor: 'pointer' }}
                onMouseEnter={(e) => {
                  setHover(d.code);
                  const rect = containerRef.current?.getBoundingClientRect();
                  setTooltip({ x: e.clientX - (rect?.left ?? 0) + 12, y: e.clientY - (rect?.top ?? 0) + 12, leaf: d });
                }}
                onMouseMove={(e) => {
                  const rect = containerRef.current?.getBoundingClientRect();
                  setTooltip(t => t ? { ...t, x: e.clientX - (rect?.left ?? 0) + 12, y: e.clientY - (rect?.top ?? 0) + 12 } : t);
                }}
                onMouseLeave={() => { setHover(null); setTooltip(null); }}
                onClick={() => {
                  window.location.href = `/categoria/${d.code}`;
                }}
              >
                <rect
                  x={node.x0}
                  y={node.y0}
                  width={w}
                  height={h}
                  fill={fill}
                  stroke={INK}
                  strokeWidth={2}
                />
                {showLabel && (
                  <text
                    x={node.x0 + 8}
                    y={node.y0 + 16}
                    fontFamily='"JetBrains Mono", monospace'
                    fontSize={10}
                    fontWeight={700}
                    fill={fg}
                    style={{ textTransform: 'uppercase', letterSpacing: '0.06em', pointerEvents: 'none' }}
                  >
                    {(d.emoji ? d.emoji + ' ' : '') + (d.name.length > Math.floor(w / 7) ? d.name.slice(0, Math.floor(w / 7) - 1) + '…' : d.name)}
                  </text>
                )}
                {showValue && (
                  <>
                    <text
                      x={node.x0 + 8}
                      y={node.y0 + h - 14}
                      fontFamily='"Bricolage Grotesque", "Plus Jakarta Sans", sans-serif'
                      fontSize={Math.min(28, Math.max(14, Math.floor(Math.min(w, h) / 5)))}
                      fontWeight={800}
                      fill={fg}
                      style={{ pointerEvents: 'none' }}
                    >
                      {fmtRon(node.value || 0)}
                    </text>
                    <text
                      x={node.x0 + 8}
                      y={node.y0 + h - 4}
                      fontFamily='"JetBrains Mono", monospace'
                      fontSize={9}
                      fill={fg}
                      fillOpacity={0.7}
                      style={{ pointerEvents: 'none', textTransform: 'uppercase', letterSpacing: '0.08em' }}
                    >
                      {d.contracts} contracte
                    </text>
                  </>
                )}
              </g>
            );
          })}
        </g>
      </svg>

      {/* Tooltip */}
      {tooltip && (
        <div
          className="pointer-events-none absolute z-20 bg-paper border-2 border-ink p-3 font-mono text-[11px] tabular-nums max-w-xs"
          style={{ left: tooltip.x, top: tooltip.y }}
        >
          <div className="font-display font-bold text-sm text-ink mb-1.5 uppercase tracking-tight leading-tight">
            {tooltip.leaf.emoji ? tooltip.leaf.emoji + ' ' : ''}{tooltip.leaf.name}
          </div>
          <div className="space-y-1">
            <div className="flex justify-between gap-3"><span className="text-ink/60 uppercase tracking-meta">CPV</span><span className="text-ink font-bold">{tooltip.leaf.code}</span></div>
            <div className="flex justify-between gap-3"><span className="text-ink/60 uppercase tracking-meta">VALOARE</span><span className="text-ink font-bold">{fmtRonFull(tooltip.leaf.value)} RON</span></div>
            <div className="flex justify-between gap-3"><span className="text-ink/60 uppercase tracking-meta">CONTRACTE</span><span className="text-ink font-bold">{tooltip.leaf.contracts.toLocaleString('ro-RO')}</span></div>
          </div>
        </div>
      )}
    </div>
  );
}
