import { useEffect, useState } from 'react';
import type maplibregl from 'maplibre-gl';

interface FlowEdge {
  supplier_siruta: string;
  supplier_name: string;
  supplier_lng: number;
  supplier_lat: number;
  contracts: number;
  total_value: number;
  last_contract: string | null;
}

interface FlowGraph {
  authority: { siruta: string; name: string; lng: number; lat: number } | null;
  flows: FlowEdge[];
}

interface Props {
  map: maplibregl.Map | null;
  selectedUat: string | null;
}

function formatRON(v: number): string {
  if (!Number.isFinite(v) || v <= 0) return '0';
  if (v >= 1_000_000_000) return `${(v / 1_000_000_000).toFixed(1)} 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 Math.round(v).toString();
}

export function FlowLayer({ map, selectedUat }: Props) {
  const [flows, setFlows] = useState<FlowGraph | null>(null);
  const [, setTick] = useState(0);

  // Fetch flows on selectedUat change
  useEffect(() => {
    if (!selectedUat) { setFlows(null); return; }
    let cancelled = false;
    fetch(`/api/harta/flows/${selectedUat}`)
      .then((r) => r.json())
      .then((d) => { if (!cancelled) setFlows(d); })
      .catch(() => {});
    return () => { cancelled = true; };
  }, [selectedUat]);

  // Re-render on map move/zoom
  useEffect(() => {
    if (!map) return;
    const tick = () => setTick((t) => t + 1);
    map.on('move', tick);
    map.on('zoom', tick);
    return () => { map.off('move', tick); map.off('zoom', tick); };
  }, [map]);

  if (!map || !flows || !flows.authority || flows.flows.length === 0) return null;

  const authPx = map.project([flows.authority.lng, flows.authority.lat]);
  const maxVal = Math.max(...flows.flows.map((f) => Number(f.total_value) || 0)) || 1;

  return (
    <svg className="harta-flow-svg">
      <defs>
        <marker id="flow-arrow" viewBox="0 0 10 10" refX="9" refY="5" markerWidth="6" markerHeight="6" orient="auto">
          <path d="M0,0 L10,5 L0,10 z" fill="rgba(37, 99, 235, 0.7)" />
        </marker>
      </defs>

      {/* Lines from authority to each supplier */}
      {flows.flows.map((f, i) => {
        const supPx = map.project([f.supplier_lng, f.supplier_lat]);
        const v = Number(f.total_value) || 0;
        const ratio = Math.sqrt(v / maxVal); // sqrt for less aggressive scaling
        const width = Math.max(1.5, ratio * 5);
        const opacity = Math.max(0.25, ratio * 0.85);

        // Curved Bezier path — control point above the midpoint to avoid overlapping straight lines
        const dx = supPx.x - authPx.x;
        const dy = supPx.y - authPx.y;
        const dist = Math.sqrt(dx * dx + dy * dy);
        const mx = (authPx.x + supPx.x) / 2;
        const my = (authPx.y + supPx.y) / 2;
        // Perpendicular offset, sign alternating so multiple flows fan out
        const perpX = -dy / dist;
        const perpY = dx / dist;
        const offset = Math.min(dist * 0.25, 80) * (i % 2 === 0 ? 1 : -1) * (1 + i * 0.05);
        const cx = mx + perpX * offset;
        const cy = my + perpY * offset;

        return (
          <g key={f.supplier_siruta}>
            <path
              d={`M ${authPx.x},${authPx.y} Q ${cx},${cy} ${supPx.x},${supPx.y}`}
              fill="none"
              stroke="rgba(37, 99, 235, 1)"
              strokeWidth={width}
              strokeOpacity={opacity}
              strokeLinecap="round"
            />
          </g>
        );
      })}

      {/* Authority center pin */}
      <g transform={`translate(${authPx.x}, ${authPx.y})`}>
        <circle r="9" fill="rgba(15, 23, 42, 0.15)" />
        <circle r="6" fill="#0F172A" stroke="white" strokeWidth="2" />
      </g>

      {/* Supplier endpoints with labels */}
      {flows.flows.map((f, i) => {
        const supPx = map.project([f.supplier_lng, f.supplier_lat]);
        const v = Number(f.total_value) || 0;
        const ratio = Math.sqrt(v / maxVal);
        const r = Math.max(3, ratio * 7);
        const showLabel = i < 5; // top 5 only to avoid clutter

        return (
          <g key={`pin-${f.supplier_siruta}`}>
            <circle
              cx={supPx.x} cy={supPx.y} r={r}
              fill="white"
              stroke="#1D4ED8"
              strokeWidth="2"
            />
            {showLabel && (
              <g>
                <rect
                  x={supPx.x + 10}
                  y={supPx.y - 9}
                  rx="4"
                  width={(f.supplier_name || '').length * 5.5 + 70}
                  height="18"
                  fill="rgba(15, 23, 42, 0.9)"
                />
                <text
                  x={supPx.x + 14}
                  y={supPx.y + 3.5}
                  fontSize="10.5"
                  fontFamily="Inter, system-ui, sans-serif"
                  fill="white"
                  fontWeight="500"
                >
                  {(f.supplier_name || '').slice(0, 28)} · {formatRON(v)}
                </text>
              </g>
            )}
          </g>
        );
      })}
    </svg>
  );
}
