"use client";

import { useEffect, useState, useCallback, useMemo } from "react";
import dynamic from "next/dynamic";
import { Badge } from "@/components/ui/badge";
import { Button } from "@/components/ui/button";
import { Switch } from "@/components/ui/switch";
import { Label } from "@/components/ui/label";
import { Slider } from "@/components/ui/slider";
import { CruiserProfileView } from "@/components/CruiserProfileView";
import { GuestUpgradeBanner } from "@/components/GuestUpgradeBanner";
import { Filter, X, Locate } from "lucide-react";
import type { Profile, CruisingSpot, MapFilters, Position } from "@/types";
import { KINK_OPTIONS } from "@/types";
import { MOCK_PROFILES, MOCK_SPOTS } from "@/lib/mock-data";
import { useOpenIdVerification, useAccess } from "@/components/Providers";
import { distanceMiles } from "@/lib/profile-stats";

import "leaflet/dist/leaflet.css";

const MapContainer = dynamic(
  () => import("react-leaflet").then((m) => m.MapContainer),
  { ssr: false }
);
const TileLayer = dynamic(
  () => import("react-leaflet").then((m) => m.TileLayer),
  { ssr: false }
);
const Marker = dynamic(
  () => import("react-leaflet").then((m) => m.Marker),
  { ssr: false }
);

const DEFAULT_LAT = parseFloat(process.env.NEXT_PUBLIC_DEFAULT_LAT || "26.1224");
const DEFAULT_LNG = parseFloat(process.env.NEXT_PUBLIC_DEFAULT_LNG || "-80.1373");
const DARK_TILES =
  "https://{s}.basemaps.cartocdn.com/dark_all/{z}/{x}/{y}{r}.png";

interface MapProps {
  vanillaMode: boolean;
  onActiveCountChange?: (count: number) => void;
}

export function CruisingMap({ vanillaMode, onActiveCountChange }: MapProps) {
  const openIdVerification = useOpenIdVerification();
  const { capabilities, blurExplicit } = useAccess();
  const [profiles] = useState<Profile[]>(MOCK_PROFILES);
  const [spots] = useState<CruisingSpot[]>(MOCK_SPOTS);
  const [selectedProfile, setSelectedProfile] = useState<Profile | null>(null);
  const [showFilters, setShowFilters] = useState(false);
  const [leafletReady, setLeafletReady] = useState(false);
  const [iconFactory, setIconFactory] = useState<{
    createPhoto: (p: Profile, blur: boolean) => import("leaflet").DivIcon;
    createYou: () => import("leaflet").DivIcon;
    createSpot: (category: string, count: number) => import("leaflet").DivIcon;
  } | null>(null);

  const [filters, setFilters] = useState<MapFilters>({
    ageMin: 18,
    ageMax: 65,
    positions: [],
    kinks: [],
    onPrep: null,
    status: [],
    onlineOnly: true,
  });

  useEffect(() => {
    import("leaflet").then((L) => {
      const createPhoto = (p: Profile, blur: boolean) => {
        const url =
          p.avatar_url ||
          "https://placehold.co/96x96/0a1628/3b82f6?text=?";
        const dist =
          p.distance_miles ??
          (p.lat && p.lng
            ? distanceMiles(DEFAULT_LAT, DEFAULT_LNG, p.lat, p.lng)
            : 1);
        const distLabel =
          dist < 1 ? dist.toFixed(1) : String(Math.max(1, Math.round(dist)));
        const blurStyle = blur ? "filter:blur(6px);" : "";
        const safeUrl = url.replace(/'/g, "%27");

        return L.divIcon({
          className: "sniffies-marker-wrap",
          html: `<div class="sniffies-marker">
            <div class="sniffies-avatar-ring ${p.status !== "offline" ? "sniffies-online" : ""}">
              <div class="sniffies-avatar" style="background-image:url('${safeUrl}');${blurStyle}"></div>
            </div>
            <div class="sniffies-dist-badge">${distLabel}</div>
          </div>`,
          iconSize: [52, 58],
          iconAnchor: [26, 29],
        });
      };

      const createYou = () =>
        L.divIcon({
          className: "sniffies-you-wrap",
          html: `<div class="sniffies-you">
            <div class="sniffies-you-dot"></div>
            <span class="sniffies-you-label">You</span>
          </div>`,
          iconSize: [48, 56],
          iconAnchor: [24, 28],
        });

      const createSpot = (category: string, count: number) => {
        const icons: Record<string, string> = {
          club: "🍸",
          gym: "💪",
          beach: "🏖",
          park: "🌳",
          bookstore: "📚",
          restroom: "🚻",
          other: "📍",
        };
        const emoji = icons[category] || "📍";
        return L.divIcon({
          className: "sniffies-spot-wrap",
          html: `<div class="sniffies-spot">
            <span>${emoji}</span>
            ${count > 0 ? `<div class="sniffies-spot-count">${count}</div>` : ""}
          </div>`,
          iconSize: [36, 36],
          iconAnchor: [18, 18],
        });
      };

      setIconFactory({ createPhoto, createYou, createSpot });
      setLeafletReady(true);
    });
  }, []);

  const filteredProfiles = useMemo(() => {
    return profiles.filter((p) => {
      if (filters.onlineOnly && p.status === "offline") return false;
      if (p.age && (p.age < filters.ageMin || p.age > filters.ageMax)) return false;
      if (filters.positions.length && p.position && !filters.positions.includes(p.position))
        return false;
      if (filters.kinks.length && !filters.kinks.some((k) => p.kinks.includes(k)))
        return false;
      if (filters.onPrep === true && !p.on_prep) return false;
      if (filters.status.length && !filters.status.includes(p.status)) return false;
      return true;
    });
  }, [profiles, filters]);

  useEffect(() => {
    onActiveCountChange?.(filteredProfiles.filter((p) => p.status !== "offline").length);
  }, [filteredProfiles, onActiveCountChange]);

  const handleChat = useCallback((profile: Profile) => {
    if (!capabilities.canSendMessages) return;
    window.location.href = `/chat?user=${profile.id}`;
  }, [capabilities.canSendMessages]);

  const togglePosition = (pos: Position) => {
    setFilters((f) => ({
      ...f,
      positions: f.positions.includes(pos)
        ? f.positions.filter((p) => p !== pos)
        : [...f.positions, pos],
    }));
  };

  const toggleKink = (kink: string) => {
    setFilters((f) => ({
      ...f,
      kinks: f.kinks.includes(kink)
        ? f.kinks.filter((k) => k !== kink)
        : [...f.kinks, kink],
    }));
  };

  return (
    <div className="relative h-full w-full bg-[#0a1628]">
      {/* Minimal top controls — Sniffies style */}
      <div className="absolute top-2 left-2 right-2 z-[1000] flex gap-2 items-start pointer-events-none">
        <div className="pointer-events-auto flex gap-2 flex-wrap">
          <Button
            variant="secondary"
            size="sm"
            onClick={() => setShowFilters(!showFilters)}
            className="shadow-lg bg-[#0a1628]/90 border-white/10 text-white h-9"
          >
            <Filter className="h-4 w-4" />
          </Button>
          <Badge
            variant="online"
            className="shadow-lg self-center bg-blue-500/20 text-blue-300 border-blue-500/30"
          >
            {filteredProfiles.filter((p) => p.status !== "offline").length} cruising
          </Badge>
        </div>
        {!capabilities.canSendMessages && (
          <div className="pointer-events-auto flex-1 max-w-xs ml-auto hidden sm:block">
            <GuestUpgradeBanner reason="general" compact />
          </div>
        )}
      </div>

      {showFilters && (
        <div className="absolute top-12 left-2 z-[1000] w-72 rounded-xl border border-white/10 bg-[#0a1628]/98 backdrop-blur-md p-4 shadow-2xl space-y-4 max-h-[70vh] overflow-y-auto">
          <div className="flex items-center justify-between">
            <span className="font-semibold text-sm text-white">Filters</span>
            <Button variant="ghost" size="icon" onClick={() => setShowFilters(false)}>
              <X className="h-4 w-4" />
            </Button>
          </div>
          <div>
            <Label className="text-xs text-white/70">
              Age: {filters.ageMin}–{filters.ageMax}
            </Label>
            <Slider
              min={18}
              max={80}
              step={1}
              value={[filters.ageMin, filters.ageMax]}
              onValueChange={([min, max]) =>
                setFilters((f) => ({ ...f, ageMin: min, ageMax: max }))
              }
              className="mt-2"
            />
          </div>
          <div>
            <Label className="text-xs mb-2 block text-white/70">Position</Label>
            <div className="flex flex-wrap gap-1">
              {(["top", "bottom", "vers", "side"] as Position[]).map((pos) => (
                <Badge
                  key={pos}
                  variant={filters.positions.includes(pos) ? pos : "outline"}
                  className="cursor-pointer uppercase"
                  onClick={() => togglePosition(pos)}
                >
                  {pos}
                </Badge>
              ))}
            </div>
          </div>
          <div>
            <Label className="text-xs mb-2 block text-white/70">Into</Label>
            <div className="flex flex-wrap gap-1 max-h-24 overflow-y-auto">
              {KINK_OPTIONS.slice(0, 12).map((k) => (
                <Badge
                  key={k}
                  variant={filters.kinks.includes(k) ? "default" : "outline"}
                  className="cursor-pointer text-[10px]"
                  onClick={() => toggleKink(k)}
                >
                  {k}
                </Badge>
              ))}
            </div>
          </div>
          <div className="flex items-center justify-between">
            <Label className="text-xs text-white/70">On PrEP only</Label>
            <Switch
              checked={filters.onPrep === true}
              onCheckedChange={(v) =>
                setFilters((f) => ({ ...f, onPrep: v ? true : null }))
              }
            />
          </div>
          <div className="flex items-center justify-between">
            <Label className="text-xs text-white/70">Online only</Label>
            <Switch
              checked={filters.onlineOnly}
              onCheckedChange={(v) =>
                setFilters((f) => ({ ...f, onlineOnly: v }))
              }
            />
          </div>
        </div>
      )}

      {/* Guest banner mobile */}
      {!capabilities.canSendMessages && (
        <div className="sm:hidden absolute top-12 left-2 right-2 z-[999]">
          <GuestUpgradeBanner reason="general" compact />
        </div>
      )}

      {leafletReady && iconFactory && (
        <MapContainer
          center={[DEFAULT_LAT, DEFAULT_LNG]}
          zoom={15}
          className="h-full w-full sniffies-map"
          zoomControl={false}
        >
          <TileLayer
            attribution='&copy; <a href="https://carto.com/">CARTO</a>'
            url={DARK_TILES}
          />

          <Marker
            position={[DEFAULT_LAT, DEFAULT_LNG]}
            icon={iconFactory.createYou()}
            zIndexOffset={1000}
          />

          {filteredProfiles.map((p) =>
            p.lat && p.lng ? (
              <Marker
                key={p.id}
                position={[p.lat, p.lng]}
                icon={iconFactory.createPhoto(p, blurExplicit)}
                eventHandlers={{
                  click: () => setSelectedProfile(p),
                }}
              />
            ) : null
          )}

          {spots.map((s) => (
            <Marker
              key={s.id}
              position={[s.lat, s.lng]}
              icon={iconFactory.createSpot(s.category, s.active_count)}
              eventHandlers={{
                click: () => {
                  /* spot detail future */
                },
              }}
            />
          ))}
        </MapContainer>
      )}

      {/* Recenter */}
      <button
        type="button"
        className="absolute bottom-20 right-3 z-[1000] p-3 rounded-full bg-[#0a1628]/90 border border-white/15 text-blue-400 shadow-lg touch-manipulation md:bottom-6"
        aria-label="Recenter map"
      >
        <Locate className="h-5 w-5" />
      </button>

      <CruiserProfileView
        profile={selectedProfile}
        open={!!selectedProfile}
        onClose={() => setSelectedProfile(null)}
        onChat={handleChat}
        vanillaMode={vanillaMode}
        onVerifyClick={openIdVerification}
      />
    </div>
  );
}