// Auteur : Simon-Pierre Boucher — contact@spboucher.ai
/**
 * RadarMap — carte maison « plan d'arpenteur », construite from scratch (SVG pur).
 * Aucune tuile, aucune bibliothèque : le sujet est au centre, chaque comparable
 * est positionné par azimut et distance réels (projection locale équirectangulaire),
 * sur des anneaux de distance concentriques. Signature Vrai-Prix : encre, lime,
 * étiquettes mono, grille d'arpentage, flèche nord, échelle.
 */
"use client";
import { useMemo, useState } from "react";

export interface RadarComp {
  id: string;
  lat: number;
  lng: number;
  label: string;
  price: string;
  adjusted: string;
  date: string;
  distanceM: number;
  weight: number;
}

interface Props {
  subject: { lat: number; lng: number; label: string };
  comps: RadarComp[];
  highlight?: string | null;
  onHover?: (id: string | null) => void;
}

const SIZE = 640; // viewBox
const C = SIZE / 2;
const PLOT_R = C - 46; // rayon utile

/** Anneaux « ronds » couvrant la distance max. */
function pickRings(maxM: number): number[] {
  const scales = [
    [100, 250, 500],
    [250, 500, 1000],
    [500, 1000, 2000],
    [1000, 2500, 5000],
    [2500, 5000, 10000],
    [5000, 10000, 20000],
    [10000, 25000, 50000],
  ];
  for (const s of scales) if (maxM <= s[2]) return s;
  return scales[scales.length - 1];
}

const fmtDist = (m: number) =>
  m < 1000 ? `${m} m` : `${m / 1000} km`.replace(".", ",");

export default function RadarMap({ subject, comps, highlight, onHover }: Props) {
  const [hover, setHover] = useState<string | null>(null);
  const active = highlight ?? hover;

  const { pts, rings, scale } = useMemo(() => {
    const cos = Math.cos((subject.lat * Math.PI) / 180);
    const raw = comps.map((c) => ({
      ...c,
      x: (c.lng - subject.lng) * 111320 * cos,
      y: (c.lat - subject.lat) * 110574,
    }));
    const maxM = Math.max(120, ...raw.map((p) => Math.hypot(p.x, p.y)));
    const ringsM = pickRings(maxM);
    const outer = ringsM[ringsM.length - 1];
    const k = PLOT_R / outer;
    return {
      pts: raw.map((p) => ({ ...p, px: C + p.x * k, py: C - p.y * k })),
      rings: ringsM,
      scale: k,
    };
  }, [subject, comps]);

  const hovered = pts.find((p) => p.id === active) ?? null;

  return (
    <div className="relative">
      <svg
        viewBox={`0 0 ${SIZE} ${SIZE}`}
        role="img"
        aria-label={`Plan des comparables autour de ${subject.label}`}
        className="block w-full bg-[var(--surface)]"
      >
        <defs>
          <filter id="grain">
            <feTurbulence type="fractalNoise" baseFrequency="0.9" numOctaves="2" result="n" />
            <feColorMatrix in="n" values="0 0 0 0 0  0 0 0 0 0  0 0 0 0 0  0 0 0 0.03 0" />
            <feComposite operator="over" in2="SourceGraphic" />
          </filter>
        </defs>

        {/* fond papier + grain */}
        <rect width={SIZE} height={SIZE} fill="var(--surface)" />
        <rect width={SIZE} height={SIZE} fill="#f5f3ee" opacity="0.6" filter="url(#grain)" />

        {/* grille d'arpentage */}
        {Array.from({ length: 15 }, (_, i) => (i + 1) * (SIZE / 16)).map((g) => (
          <g key={g} stroke="rgba(20,24,20,0.05)" strokeWidth="1">
            <line x1={g} y1="0" x2={g} y2={SIZE} />
            <line x1="0" y1={g} x2={SIZE} y2={g} />
          </g>
        ))}

        {/* anneaux de distance */}
        {rings.map((m, i) => (
          <g key={m}>
            <circle
              cx={C}
              cy={C}
              r={m * scale}
              fill="none"
              stroke={i === rings.length - 1 ? "rgba(20,24,20,0.85)" : "rgba(20,24,20,0.22)"}
              strokeWidth={i === rings.length - 1 ? 1.5 : 1}
              strokeDasharray={i === rings.length - 1 ? "none" : "5 6"}
            />
            <text
              x={C + m * scale * 0.7071 + 4}
              y={C - m * scale * 0.7071 - 4}
              fontSize="10.5"
              fontFamily="var(--font-jetbrains), monospace"
              fill="rgba(20,24,20,0.45)"
              style={{ textTransform: "uppercase", letterSpacing: "0.08em" }}
            >
              {fmtDist(m)}
            </text>
          </g>
        ))}

        {/* croix cardinale */}
        <line x1={C} y1={C - PLOT_R} x2={C} y2={C + PLOT_R} stroke="rgba(20,24,20,0.14)" strokeWidth="1" />
        <line x1={C - PLOT_R} y1={C} x2={C + PLOT_R} y2={C} stroke="rgba(20,24,20,0.14)" strokeWidth="1" />

        {/* flèche nord */}
        <g transform={`translate(${SIZE - 34}, 38)`}>
          <path d="M0,-16 L7,8 L0,3 L-7,8 Z" fill="var(--ink)" />
          <text y="24" textAnchor="middle" fontSize="11" fontWeight="700" fontFamily="var(--font-jetbrains), monospace" fill="var(--ink)">
            N
          </text>
        </g>

        {/* échelle */}
        <g transform={`translate(28, ${SIZE - 30})`}>
          <line x1="0" y1="0" x2={rings[0] * scale} y2="0" stroke="var(--ink)" strokeWidth="2.5" />
          <line x1="0" y1="-4" x2="0" y2="4" stroke="var(--ink)" strokeWidth="2" />
          <line x1={rings[0] * scale} y1="-4" x2={rings[0] * scale} y2="4" stroke="var(--ink)" strokeWidth="2" />
          <text x={rings[0] * scale + 8} y="4" fontSize="10.5" fontFamily="var(--font-jetbrains), monospace" fill="var(--ink-2)">
            {fmtDist(rings[0])}
          </text>
        </g>

        {/* rayons vers comparables (au survol) */}
        {hovered && (
          <line
            x1={C}
            y1={C}
            x2={hovered.px}
            y2={hovered.py}
            stroke="var(--green)"
            strokeWidth="1.5"
            strokeDasharray="3 4"
          />
        )}

        {/* comparables : cercles numérotés, taille = poids */}
        {pts.map((p, i) => {
          const r = 9 + p.weight * 7;
          const on = p.id === active;
          return (
            <g
              key={p.id}
              transform={`translate(${p.px}, ${p.py})`}
              onMouseEnter={() => {
                setHover(p.id);
                onHover?.(p.id);
              }}
              onMouseLeave={() => {
                setHover(null);
                onHover?.(null);
              }}
              style={{ cursor: "pointer" }}
            >
              <circle
                r={r}
                fill={on ? "var(--lime)" : "var(--green)"}
                stroke="var(--ink)"
                strokeWidth={on ? 2.5 : 1.5}
              />
              <text
                textAnchor="middle"
                dy="0.36em"
                fontSize={r > 12 ? 12 : 10.5}
                fontWeight="700"
                fontFamily="var(--font-jetbrains), monospace"
                fill={on ? "var(--ink)" : "#f5f3ee"}
              >
                {i + 1}
              </text>
            </g>
          );
        })}

        {/* sujet : losange lime pulsant au centre */}
        <g transform={`translate(${C}, ${C})`}>
          <rect
            x={-13}
            y={-13}
            width={26}
            height={26}
            transform="rotate(45)"
            fill="var(--lime)"
            stroke="var(--ink)"
            strokeWidth="2.5"
          >
            <animate attributeName="opacity" values="1;0.75;1" dur="2.4s" repeatCount="indefinite" />
          </rect>
          <rect x={-4} y={-4} width={8} height={8} transform="rotate(45)" fill="var(--ink)" />
        </g>

        {/* cartouche */}
        <g fontFamily="var(--font-jetbrains), monospace">
          <text x="28" y="34" fontSize="11" fontWeight="700" fill="var(--ink)" style={{ textTransform: "uppercase", letterSpacing: "0.12em" }}>
            ◆ PLAN DES COMPARABLES
          </text>
          <text x="28" y="50" fontSize="10" fill="rgba(20,24,20,0.5)" style={{ textTransform: "uppercase", letterSpacing: "0.08em" }}>
            {comps.length} ventes · azimut + distance réels
          </text>
        </g>
      </svg>

      {/* infobulle */}
      {hovered && (
        <div
          className="pointer-events-none absolute z-10 max-w-[230px] rounded-lg border border-lime bg-ink px-3.5 py-2.5 text-[12px] leading-relaxed text-paper shadow-[0_8px_24px_rgba(16,18,16,0.35)]"
          style={{
            left: `${(hovered.px / SIZE) * 100}%`,
            top: `${(hovered.py / SIZE) * 100}%`,
            transform: `translate(${hovered.px > SIZE * 0.62 ? "-108%" : "12px"}, ${hovered.py > SIZE * 0.7 ? "-108%" : "-8px"})`,
          }}
        >
          <p className="vp-display mb-0.5 font-bold text-lime">{hovered.label}</p>
          <p className="vp-mono text-[10.5px] uppercase tracking-[0.05em]">
            {hovered.date} · {fmtDist(Math.round(hovered.distanceM))}
          </p>
          <p>
            Vendu {hovered.price} → ajusté <b>{hovered.adjusted}</b>
          </p>
        </div>
      )}
    </div>
  );
}
