import { useEffect, useMemo, useRef, useState } from "react";
import exteriorSvgUrl from "/scheme/exterior.svg?url";
import { cn } from "@/lib/utils";

// Zone color states
const COLOR_DEFAULT_FILL = "rgba(0, 0, 0, 0)";           // transparent
const COLOR_HOVER_FILL = "rgba(59, 130, 246, 0.20)";     // soft blue
const COLOR_HAS_DAMAGE_FILL = "rgba(239, 68, 68, 0.30)"; // red tint for zones with active damage
const COLOR_RESOLVED_FILL = "rgba(156, 163, 175, 0.30)"; // gray for resolved-only zones

export interface SchemeMarker {
  id: number;
  side?: string | null;
  damage_type?: string | null;
  severity?: string | null;
  resolved: boolean;
  /** Координаты точек повреждения в композитной SVG-системе (827×1209). */
  polygon?: { x: number; y: number }[] | null;
}

const SVG_NS = "http://www.w3.org/2000/svg";
const POINT_RADIUS = 9;
const POINT_FILL_ACTIVE = "rgb(220, 38, 38)";
const POINT_FILL_RESOLVED = "rgb(107, 114, 128)";
const COMPOSITE_W = 827;
const COMPOSITE_H = 1209;

interface Props {
  markers: SchemeMarker[];
  onZoneTap?: (zoneId: number) => void;
  onTireWearClick?: () => void;
  editable?: boolean;
}

/** Parse "zone-23" -> 23, anything else -> null */
function parseZoneId(side: string | null | undefined): number | null {
  if (!side) return null;
  const m = /^zone-(\d+)$/.exec(side);
  if (!m) return null;
  const n = Number(m[1]);
  return Number.isFinite(n) ? n : null;
}

export function VendorVehicleScheme({
  markers,
  onZoneTap,
  onTireWearClick,
  editable = true,
}: Props) {
  const containerRef = useRef<HTMLDivElement>(null);
  const [svgText, setSvgText] = useState<string | null>(null);
  const [hoverZone, setHoverZone] = useState<number | null>(null);

  // Load SVG once from public/scheme/exterior.svg as a separate asset
  useEffect(() => {
    let cancelled = false;
    fetch(exteriorSvgUrl)
      .then((r) => r.text())
      .then((t) => {
        if (!cancelled) setSvgText(t);
      })
      .catch(() => {
        if (!cancelled) setSvgText("<!-- failed to load -->");
      });
    return () => {
      cancelled = true;
    };
  }, []);

  // Count damage per zone, separately track has-any vs has-only-resolved
  const zoneStats = useMemo(() => {
    const stats = new Map<number, { count: number; activeCount: number }>();
    for (const m of markers) {
      const z = parseZoneId(m.side);
      if (z == null) continue;
      const s = stats.get(z) ?? { count: 0, activeCount: 0 };
      s.count += 1;
      if (!m.resolved) s.activeCount += 1;
      stats.set(z, s);
    }
    return stats;
  }, [markers]);

  const tireCount = markers.filter((m) => m.side === "tires").length;

  // Apply zone fills after SVG renders or when hover/damage state changes
  useEffect(() => {
    if (!svgText) return;
    const el = containerRef.current;
    if (!el) return;
    const svg = el.querySelector("svg");
    if (!svg) return;

    // Strip any inline <script> the vendor included
    svg.querySelectorAll("script").forEach((s) => s.remove());

    // Make the SVG fill its container
    svg.setAttribute("width", "100%");
    svg.setAttribute("height", "100%");
    svg.setAttribute("preserveAspectRatio", "xMidYMid meet");

    // Reset all numeric-class paths to appropriate fill
    const all = svg.querySelectorAll("path[class]");
    all.forEach((p) => {
      const cls = p.getAttribute("class") ?? "";
      const zid = /^\d+$/.test(cls) ? Number(cls) : null;
      if (zid == null) return;

      const s = zoneStats.get(zid);
      let fill = COLOR_DEFAULT_FILL;
      if (s) {
        fill = s.activeCount > 0 ? COLOR_HAS_DAMAGE_FILL : COLOR_RESOLVED_FILL;
      }
      if (hoverZone === zid && editable) fill = COLOR_HOVER_FILL;

      p.setAttribute("fill", fill);
      (p as SVGElement).style.cursor = editable ? "pointer" : "default";
      (p as SVGElement).style.transition = "fill 0.15s";
    });
  }, [svgText, zoneStats, hoverZone, editable]);

  // Overlay точек повреждений (multi-point координаты в композитной 827×1209)
  useEffect(() => {
    if (!svgText) return;
    const el = containerRef.current;
    if (!el) return;
    const svg = el.querySelector("svg") as SVGSVGElement | null;
    if (!svg) return;

    // Удаляем предыдущий overlay
    const existing = svg.querySelector("g[data-damage-points]");
    if (existing) existing.remove();

    const group = document.createElementNS(SVG_NS, "g");
    group.setAttribute("data-damage-points", "1");

    let counter = 1;
    for (const m of markers) {
      const pts = m.polygon || [];
      if (pts.length === 0) continue;
      const fill = m.resolved ? POINT_FILL_RESOLVED : POINT_FILL_ACTIVE;

      for (const pt of pts) {
        if (
          typeof pt.x !== "number" ||
          typeof pt.y !== "number" ||
          !Number.isFinite(pt.x) ||
          !Number.isFinite(pt.y)
        ) {
          continue;
        }
        // Polygon хранится в normalised 0..1 (см. ZoneDetailView). SVG viewBox
        // в композитной 827×1209, поэтому умножаем перед отрисовкой.
        const cx = pt.x * COMPOSITE_W;
        const cy = pt.y * COMPOSITE_H;
        const circle = document.createElementNS(SVG_NS, "circle");
        circle.setAttribute("cx", String(cx));
        circle.setAttribute("cy", String(cy));
        circle.setAttribute("r", String(POINT_RADIUS));
        circle.setAttribute("fill", fill);
        circle.setAttribute("stroke", "white");
        circle.setAttribute("stroke-width", "2");
        (circle as SVGElement).style.pointerEvents = "none";
        group.appendChild(circle);

        const text = document.createElementNS(SVG_NS, "text");
        text.setAttribute("x", String(cx));
        text.setAttribute("y", String(cy));
        text.setAttribute("text-anchor", "middle");
        text.setAttribute("dominant-baseline", "central");
        text.setAttribute("fill", "white");
        text.setAttribute("font-size", "11");
        text.setAttribute("font-weight", "bold");
        (text as SVGElement).style.pointerEvents = "none";
        (text as SVGElement).style.userSelect = "none";
        text.textContent = String(counter);
        group.appendChild(text);
        counter += 1;
      }
    }

    svg.appendChild(group);
  }, [svgText, markers]);

  // Walk up from event.target to find a path[class="N"] (numeric zone id)
  function zoneFromEvent(e: React.MouseEvent | React.TouchEvent): number | null {
    let node = e.target as Element | null;
    while (node && node !== e.currentTarget) {
      if (node.tagName?.toLowerCase() === "path") {
        const cls = node.getAttribute("class") ?? "";
        if (/^\d+$/.test(cls)) return Number(cls);
      }
      node = node.parentElement;
    }
    return null;
  }

  function handleClick(e: React.MouseEvent<HTMLDivElement>) {
    if (!editable) return;
    const z = zoneFromEvent(e);
    if (z != null) onZoneTap?.(z);
  }

  function handleMove(e: React.MouseEvent<HTMLDivElement>) {
    if (!editable) return;
    setHoverZone(zoneFromEvent(e));
  }

  return (
    <div className="space-y-3">
      {/* SVG container — aspect ratio matches vendor viewBox 827×1209 */}
      <div
        ref={containerRef}
        onClick={handleClick}
        onMouseMove={handleMove}
        onMouseLeave={() => setHoverZone(null)}
        className={cn(
          "mx-auto w-full max-w-md bg-card border rounded-lg p-2 aspect-[827/1209]",
          "overflow-hidden",
        )}
        style={{ touchAction: "manipulation" }}
        dangerouslySetInnerHTML={svgText ? { __html: svgText } : undefined}
      />

      {/* Summary line: count of zones with damage */}
      {zoneStats.size > 0 && (
        <div className="mx-auto max-w-md text-xs text-muted-foreground text-center">
          Зон с повреждениями:{" "}
          <span className="font-semibold text-foreground">{zoneStats.size}</span>
          {" · "}
          Всего меток:{" "}
          <span className="font-semibold text-foreground">
            {markers.filter((m) => parseZoneId(m.side) != null).length}
          </span>
        </div>
      )}

      {/* Global tire-wear button */}
      <button
        type="button"
        onClick={onTireWearClick}
        disabled={!editable && !onTireWearClick}
        className="w-full max-w-md mx-auto flex items-center justify-between gap-3 rounded-lg border bg-card px-4 py-3 hover:bg-accent transition-colors text-sm font-medium"
      >
        <span className="flex items-center gap-2">
          <span className="text-xl">&#8857;</span>
          <span>Состояние резины</span>
        </span>
        {tireCount > 0 && (
          <span className="bg-destructive text-destructive-foreground text-xs font-bold rounded-full px-2 py-0.5">
            {tireCount}
          </span>
        )}
      </button>

      {editable && (
        <p className="text-xs text-center text-muted-foreground">
          Тапните по зоне машины, чтобы добавить метку повреждения.
        </p>
      )}
    </div>
  );
}
