import { useState } from "react";
import { useNavigate } from "react-router-dom";
import {
  BOROUGH_PATHS,
  LONDON_VIEWBOX,
  REGION_BORDERS_PATH,
  RIVERS_PATH,
} from "@/lib/londonMap";
import { COUNCIL_META } from "@/lib/councilMeta";

export interface BoroughDatum {
  slug: string;
  name: string;
  isLive: boolean;
  hasHistory?: boolean;
  median?: number | null;
  resolved?: number | null;
  /** Closed reports in the current window — shown while metrics are still null. */
  sampleSize?: number;
  historicalTotal?: number;
  historyMonths?: number;
}

interface Props {
  data: Record<string, BoroughDatum>;
  onSelect: (d: BoroughDatum) => void;
  /** True while borough stats are still loading — tooltips say so instead
   *  of claiming every borough is "coming soon". */
  loading?: boolean;
}

interface Tip {
  x: number;
  y: number;
  d: BoroughDatum;
}

const BOROUGH_LAYER_TRANSFORM = "matrix(1 0 0 1.6 0 -62.661196)";

const fmtPct = (n?: number | null) =>
  n == null ? "—" : `${Math.round(n)}%`;
const fmtDays = (n?: number | null) =>
  n == null ? "—" : `${n.toFixed(1).replace(/\.0$/, "")}d`;

/** "4mo" below a year, "1.5y" style above — never a misleading "0y". */
const fmtHistorySpan = (months?: number) => {
  if (!months || months <= 0) return "";
  if (months < 12) return ` · ${months}mo`;
  const years = months / 12;
  return ` · ${years >= 3 ? Math.round(years) : years.toFixed(1).replace(/\.0$/, "")}y`;
};

export function LondonMap({ data, onSelect, loading = false }: Props) {
  const [tip, setTip] = useState<Tip | null>(null);
  const navigate = useNavigate();

  const handleMove = (e: React.MouseEvent, d: BoroughDatum) => {
    const wrap = (e.currentTarget as SVGElement).ownerSVGElement?.parentElement;
    if (!wrap) return;
    const r = wrap.getBoundingClientRect();
    setTip({ x: e.clientX - r.left, y: e.clientY - r.top, d });
  };

  return (
    <div
      className="london-map-wrap"
      onMouseLeave={() => setTip(null)}
    >
      <svg
        className="london-map"
        viewBox={LONDON_VIEWBOX}
        xmlns="http://www.w3.org/2000/svg"
        role="img"
        aria-label="Map of London boroughs"
      >
        <defs>
          <clipPath id="london-clip">
            {Object.entries(BOROUGH_PATHS).map(([slug, dPath]) => (
              <path key={slug} d={dPath} transform={BOROUGH_LAYER_TRANSFORM} />
            ))}
          </clipPath>
        </defs>
        <g>
          <g transform={BOROUGH_LAYER_TRANSFORM}>
            {Object.entries(BOROUGH_PATHS).map(([slug, dPath]) => {
            const datum =
              data[slug] ?? {
                slug,
                name:
                  COUNCIL_META[slug]?.name ??
                  slug.replace(/(^|-)\w/g, (m) => m.toUpperCase()).replace(/-/g, " "),
                isLive: false,
              };
            const party = COUNCIL_META[slug]?.rulingParty ?? "ind";
            const cls = ["b-region", party].filter(Boolean).join(" ");
            const interactive = datum.isLive || datum.hasHistory;
            return (
              <path
                key={slug}
                d={dPath}
                className={cls + (interactive ? "" : " inert")}
                onMouseMove={(e) => handleMove(e, datum)}
                onClick={() => {
                  if (interactive) navigate(`/${slug}`);
                }}
              />
            );
          })}
          </g>
          <g clipPath="url(#london-clip)">
            <path d={RIVERS_PATH} className="b-river" />
          </g>
          <path d={REGION_BORDERS_PATH} className="b-border" transform={BOROUGH_LAYER_TRANSFORM} />
        </g>
      </svg>

      {tip && (
        <div
          className="map-tooltip"
          style={{ left: tip.x, top: tip.y }}
        >
          <div className="tt-name">
            {tip.d.name}
            {tip.d.isLive && <span className="tt-live-badge">● live data</span>}
          </div>
          {loading ? (
            <div className="tt-row">Loading borough data…</div>
          ) : tip.d.isLive ? (
            <>
              <div className="tt-row">
                {tip.d.resolved != null && tip.d.median != null
                  ? `${fmtPct(tip.d.resolved)} resolved · ${fmtDays(tip.d.median)} median`
                  : `Ingesting — ${new Intl.NumberFormat("en-GB").format(tip.d.sampleSize ?? 0)} reports so far`}
              </div>
              <div className="tt-cta">View dashboard →</div>
            </>
          ) : tip.d.hasHistory ? (
            <>
              <div className="tt-row">
                {tip.d.historicalTotal
                  ? `Historical archive · ${new Intl.NumberFormat("en-GB").format(tip.d.historicalTotal)} reports`
                  : "Historical archive"}
                {fmtHistorySpan(tip.d.historyMonths)}
              </div>
              <div className="tt-cta">View borough →</div>
            </>
          ) : (
            <div className="tt-row">Planned — awaiting ingestion</div>
          )}
        </div>
      )}

      <div className="map-legend">
        <span><span className="swatch" style={{ background: "#c84a4a" }} /> Labour</span>
        <span><span className="swatch" style={{ background: "#1f6dd1" }} /> Conservative</span>
        <span><span className="swatch" style={{ background: "#d6a23a" }} /> Lib Dem</span>
        <span><span className="swatch" style={{ background: "#3aa05a" }} /> Green</span>
        <span><span className="swatch" style={{ background: "#12b6cf" }} /> Reform UK</span>
        <span><span className="swatch" style={{ background: "#7e57c2" }} /> Aspire</span>
        <span><span className="swatch" style={{ background: "#6b6f78" }} /> NOC</span>
      </div>
    </div>
  );
}
