"use client";
import { useState, useRef } from "react";
import Link from "next/link";
import Image from "next/image";
import { Search, Maximize, Plus, Minus, X, MapPin } from "lucide-react";
import { Button } from "@/components/ui/button";
import { Input } from "@/components/ui/input";
type MapPoint = {
  id: string;
  name: string;
  latitude: number;
  longitude: number;
  href: string;
  status?: string;
};
export function OfflineMap({
  points,
  kind,
}: {
  points: MapPoint[];
  kind: "locations" | "chargepoints";
}) {
  const [query, setQuery] = useState("");
  const [zoom, setZoom] = useState(1);
  const [offset, setOffset] = useState({ x: 0, y: 0 });
  const [selected, setSelected] = useState<MapPoint[]>([]);
  const [notice, setNotice] = useState("");
  const container = useRef<HTMLDivElement>(null);
  const drag = useRef<{
    x: number;
    y: number;
    left: number;
    top: number;
  } | null>(null);
  const results = points.filter((point) =>
    point.name.toLowerCase().includes(query.trim().toLowerCase()),
  );
  const groups = new Map<string, MapPoint[]>();
  results.forEach((point) => {
    const key = `${point.latitude.toFixed(2)}-${point.longitude.toFixed(2)}`;
    groups.set(key, [...(groups.get(key) ?? []), point]);
  });
  async function fullscreen() {
    try {
      if (document.fullscreenElement) await document.exitFullscreen();
      else await container.current?.requestFullscreen();
    } catch {
      setNotice("Fullscreen is unavailable in this browser.");
    }
  }
  return (
    <div
      ref={container}
      className="relative min-h-[320px] h-[calc(100dvh-240px)] overflow-hidden rounded-xl border bg-muted"
      onPointerDown={(event) => {
        if ((event.target as HTMLElement).closest("button,input,a")) return;
        drag.current = {
          x: event.clientX,
          y: event.clientY,
          left: offset.x,
          top: offset.y,
        };
        event.currentTarget.setPointerCapture(event.pointerId);
      }}
      onPointerMove={(event) => {
        if (drag.current)
          setOffset({
            x: drag.current.left + event.clientX - drag.current.x,
            y: drag.current.top + event.clientY - drag.current.y,
          });
      }}
      onPointerUp={() => (drag.current = null)}
      onPointerCancel={() => (drag.current = null)}
    >
      <div
        className="absolute inset-0 touch-none"
        style={{
          transform: `translate(${offset.x}px,${offset.y}px) scale(${zoom})`,
          transformOrigin: "25% 75%",
        }}
      >
        <Image
          loading="eager"
          src="/images/map/indonesia.svg"
          alt="Offline map of Indonesia"
          fill
          unoptimized
          className="object-fill"
          draggable={false}
        />
        {[...groups.entries()].map(([key, group]) => (
          <button
            key={key}
            className="absolute flex size-10 -translate-x-1/2 -translate-y-1/2 items-center justify-center rounded-full border-4 border-info/30 bg-info text-white shadow-md"
            style={{
              left: `${(group[0].longitude - 94) * 2}%`,
              top: `${(((14 - group[0].latitude) * 24) / 650) * 100}%`,
              transform: `translate(-50%,-50%) scale(${1 / zoom})`,
            }}
            aria-label={`View ${group.length > 1 ? `${group.length} ${kind} near ${group[0].name}` : group[0].name}`}
            onClick={() => setSelected(group)}
          >
            {group.length > 1 ? group.length : <MapPin className="size-5" />}
          </button>
        ))}
      </div>
      <div className="absolute left-3 top-3 w-[calc(100%-76px)] max-w-[360px]">
        <div className="relative">
          <Search className="absolute left-3 top-3 size-5 text-muted-foreground" />
          <Input
            placeholder={`Search ${kind}...`}
            aria-label={`Search map ${kind}`}
            value={query}
            onChange={(event) => {
              setQuery(event.target.value);
              setSelected([]);
            }}
            className="bg-card pl-10 shadow-md"
          />
        </div>
        {query && (
          <div className="mt-1 max-h-56 overflow-auto rounded-lg bg-card shadow-lg">
            {results.slice(0, 10).map((point) => (
              <button
                key={point.id}
                className="block w-full border-b px-4 py-3 text-left hover:bg-muted"
                onClick={() => {
                  setSelected([point]);
                  setZoom(1);
                  setOffset({ x: 0, y: 0 });
                }}
              >
                {point.name}
              </button>
            ))}
            {!results.length && (
              <p className="p-4 text-muted-foreground">No {kind} found</p>
            )}
          </div>
        )}
      </div>
      <Button
        variant="outline"
        size="icon"
        aria-label="Toggle fullscreen map"
        className="absolute right-3 top-3 bg-card shadow-md"
        onClick={fullscreen}
      >
        <Maximize />
      </Button>
      <div className="absolute bottom-8 right-3 flex flex-col rounded-lg bg-card shadow-md">
        <Button
          variant="ghost"
          size="icon"
          aria-label="Zoom in"
          onClick={() => setZoom(Math.min(5, zoom + 0.5))}
          disabled={zoom >= 5}
        >
          <Plus />
        </Button>
        <Button
          variant="ghost"
          size="icon"
          aria-label="Zoom out"
          onClick={() => setZoom(Math.max(1, zoom - 0.5))}
          disabled={zoom <= 1}
        >
          <Minus />
        </Button>
      </div>
      {selected.length > 0 && (
        <section
          aria-label="Selected map markers"
          className="absolute bottom-10 left-3 max-h-[50%] w-[calc(100%-76px)] max-w-sm overflow-auto rounded-xl bg-card p-4 shadow-lg"
        >
          <div className="mb-3 flex items-center justify-between">
            <h2 className="font-semibold">
              {kind === "locations" ? "Location" : "Chargestation"} Details
            </h2>
            <Button
              variant="ghost"
              size="icon-sm"
              aria-label="Close map details"
              onClick={() => setSelected([])}
            >
              <X />
            </Button>
          </div>
          {selected.map((point) => (
            <div key={point.id} className="border-t py-3">
              <p className="font-medium">{point.name}</p>
              {point.status && (
                <p className="text-xs text-muted-foreground">{point.status}</p>
              )}
              <Link
                href={point.href}
                className="mt-2 inline-block text-primary underline"
              >
                View Details
              </Link>
            </div>
          ))}
        </section>
      )}
      <p
        role="status"
        className="absolute bottom-0 left-0 right-0 bg-card/90 px-3 py-1.5 text-xs text-muted-foreground"
      >
        {notice || "Offline preview · Local mock markers · Natural Earth"}
      </p>
    </div>
  );
}
