import { useEffect, useRef, useState } from "react";
import { setOptions, importLibrary } from "@googlemaps/js-api-loader";
import { MapPin, AlertCircle } from "lucide-react";
import type { Competitor } from "@/lib/briefing.functions";

type Pin = {
  id: string;
  name: string;
  lat: number;
  lng: number;
  isAnchor?: boolean;
  threat_level?: "low" | "medium" | "high";
};

type Props = {
  anchor: { name: string; lat: number; lng: number };
  competitors: Competitor[];
  onCompetitorMove?: (name: string, lat: number, lng: number) => void;
  onAnchorMove?: (lat: number, lng: number) => void;
};

const THREAT_COLOR: Record<NonNullable<Pin["threat_level"]>, string> = {
  low: "#10b981",
  medium: "#f59e0b",
  high: "#ef4444",
};

export function CompetitorMap({ anchor, competitors, onCompetitorMove, onAnchorMove }: Props) {
  const apiKey = (import.meta.env.VITE_GOOGLE_MAPS_API_KEY as string | undefined) ?? "";
  const containerRef = useRef<HTMLDivElement>(null);
  const mapRef = useRef<google.maps.Map | null>(null);
  const markersRef = useRef<google.maps.Marker[]>([]);
  const [error, setError] = useState<string | null>(null);
  const [ready, setReady] = useState(false);

  // Build pin list: anchor + competitors with valid coords (fallback: scatter around anchor)
  const pins: Pin[] = [
    { id: "anchor", name: anchor.name, lat: anchor.lat, lng: anchor.lng, isAnchor: true },
    ...competitors.map((c, i) => {
      const hasCoords = typeof c.lat === "number" && typeof c.lng === "number";
      // Deterministic scatter ~1km-3km around anchor when no coords
      const angle = (i / Math.max(competitors.length, 1)) * Math.PI * 2;
      const r = 0.01 + (c.distance_km ?? 1) * 0.009; // ~1deg lat ≈ 111km
      return {
        id: `c-${i}`,
        name: c.name,
        lat: hasCoords ? (c.lat as number) : anchor.lat + Math.cos(angle) * r,
        lng: hasCoords ? (c.lng as number) : anchor.lng + Math.sin(angle) * r,
        threat_level: c.threat_level,
      };
    }),
  ];

  // Init map
  useEffect(() => {
    if (!apiKey) {
      setError("Google Maps API key not configured. Add VITE_GOOGLE_MAPS_API_KEY to .env to enable the live map.");
      return;
    }
    if (!containerRef.current) return;

    let cancelled = false;
    setOptions({ key: apiKey, v: "weekly" });

    importLibrary("maps")
      .then(({ Map }) => {
        if (cancelled || !containerRef.current) return;
        mapRef.current = new Map(containerRef.current, {
          center: { lat: anchor.lat, lng: anchor.lng },
          zoom: 14,
          mapTypeControl: false,
          streetViewControl: false,
          fullscreenControl: false,
          styles: [{ featureType: "poi.business", stylers: [{ visibility: "off" }] }],
        });
        setReady(true);
      })
      .catch((e: Error) => {
        setError(`Couldn't load Google Maps: ${e.message}`);
      });

    return () => {
      cancelled = true;
    };
    // eslint-disable-next-line react-hooks/exhaustive-deps
  }, [apiKey]);

  // Render markers whenever pins change and map is ready
  useEffect(() => {
    if (!ready || !mapRef.current) return;
    const map = mapRef.current;

    // Clear existing
    markersRef.current.forEach((m) => m.setMap(null));
    markersRef.current = [];

    pins.forEach((pin) => {
      const color = pin.isAnchor
        ? "#0f172a"
        : THREAT_COLOR[pin.threat_level ?? "low"];

      const marker = new google.maps.Marker({
        position: { lat: pin.lat, lng: pin.lng },
        map,
        draggable: true,
        title: pin.name,
        label: pin.isAnchor
          ? { text: "★", color: "#fff", fontSize: "14px", fontWeight: "700" }
          : undefined,
        icon: {
          path: google.maps.SymbolPath.CIRCLE,
          scale: pin.isAnchor ? 14 : 10,
          fillColor: color,
          fillOpacity: 1,
          strokeColor: "#ffffff",
          strokeWeight: 2,
        },
      });

      const info = new google.maps.InfoWindow({
        content: `<div style="font-family:system-ui;font-size:13px;padding:2px 4px">
          <strong>${pin.name}</strong>${pin.isAnchor ? " (you)" : ""}
        </div>`,
      });
      marker.addListener("click", () => info.open({ map, anchor: marker }));

      marker.addListener("dragend", () => {
        const pos = marker.getPosition();
        if (!pos) return;
        if (pin.isAnchor) onAnchorMove?.(pos.lat(), pos.lng());
        else onCompetitorMove?.(pin.name, pos.lat(), pos.lng());
      });

      markersRef.current.push(marker);
    });

    // Fit bounds
    if (pins.length > 1) {
      const bounds = new google.maps.LatLngBounds();
      pins.forEach((p) => bounds.extend({ lat: p.lat, lng: p.lng }));
      map.fitBounds(bounds, 60);
    }
    // eslint-disable-next-line react-hooks/exhaustive-deps
  }, [ready, JSON.stringify(pins)]);

  if (error) {
    return (
      <div className="flex flex-col items-center justify-center gap-3 rounded-2xl border border-dashed bg-muted/30 p-10 text-center">
        <AlertCircle className="h-8 w-8 text-muted-foreground" />
        <div>
          <p className="text-sm font-medium text-foreground">Map unavailable</p>
          <p className="mx-auto mt-1 max-w-md text-xs text-muted-foreground">{error}</p>
        </div>
        <FallbackList anchor={anchor} pins={pins} />
      </div>
    );
  }

  return (
    <div className="overflow-hidden rounded-2xl border bg-card shadow-[var(--shadow-elegant)]">
      <div ref={containerRef} className="h-[280px] w-full sm:h-[360px] md:h-[420px]" />
      <div className="flex items-center justify-between gap-3 border-t bg-muted/30 px-4 py-2.5 text-xs text-muted-foreground">
        <span className="inline-flex items-center gap-1.5">
          <MapPin className="h-3.5 w-3.5" /> Drag any pin to refine its location
        </span>
        <span className="inline-flex items-center gap-3">
          <LegendDot color="#0f172a" label="You" />
          <LegendDot color={THREAT_COLOR.high} label="High" />
          <LegendDot color={THREAT_COLOR.medium} label="Medium" />
          <LegendDot color={THREAT_COLOR.low} label="Low" />
        </span>
      </div>
    </div>
  );
}

function LegendDot({ color, label }: { color: string; label: string }) {
  return (
    <span className="inline-flex items-center gap-1">
      <span className="h-2.5 w-2.5 rounded-full" style={{ background: color }} />
      {label}
    </span>
  );
}

function FallbackList({ anchor, pins }: { anchor: Props["anchor"]; pins: Pin[] }) {
  return (
    <ul className="mt-2 w-full max-w-md space-y-1 text-left text-xs">
      <li className="text-muted-foreground">Pinned locations:</li>
      {pins.map((p) => (
        <li key={p.id} className="flex items-center justify-between rounded border bg-background px-2.5 py-1.5">
          <span className="font-medium text-foreground">
            {p.isAnchor ? "★ " : ""}
            {p.name}
          </span>
          <span className="text-muted-foreground">
            {p.lat.toFixed(4)}, {p.lng.toFixed(4)}
          </span>
        </li>
      ))}
      <li className="pt-1 text-muted-foreground">Anchor: {anchor.name}</li>
    </ul>
  );
}
