import { useEffect, useRef } from "react";
import { useQuery } from "@tanstack/react-query";
import { useAlert } from "../context/AlertContext";
import { useAuth } from "../context/AuthContext";
import Forbidden from "../components/Forbidden";
import { useNavigate, useParams, Link } from "react-router-dom";
import { motion } from "framer-motion";

import L from "leaflet";
import "leaflet/dist/leaflet.css";

import { formatDate, formatTime } from "../utils/attendanceHelpers";
import {
  attendanceLocationOptions,
  type LocationRecord,
} from "../lib/queries/attendance";

export default function AttendanceLocation() {
  const alert = useAlert();
  const { hasPermission } = useAuth();
  const navigate = useNavigate();
  const { id } = useParams<{ id: string }>();
  const mapRef = useRef<HTMLDivElement>(null);
  const mapInstanceRef = useRef<unknown>(null);

  const locationQuery = useQuery(attendanceLocationOptions(id));
  const record = locationQuery.data ?? null;
  const isPending = locationQuery.isPending;

  // Navigate away on fetch error
  useEffect(() => {
    if (locationQuery.error) {
      alert.error("Nepodařilo se načíst data");
      navigate("/attendance/admin");
    }
  }, [locationQuery.error]); // eslint-disable-line react-hooks/exhaustive-deps

  useEffect(() => {
    if (!record || isPending) return;

    const hasArrivalLocation = record.arrival_lat && record.arrival_lng;
    const hasDepartureLocation = record.departure_lat && record.departure_lng;
    const hasAnyLocation = hasArrivalLocation || hasDepartureLocation;

    if (!hasAnyLocation || !mapRef.current) return;

    const initMap = () => {
      if (mapInstanceRef.current) {
        (mapInstanceRef.current as { remove: () => void }).remove();
      }

      const map = L.map(mapRef.current!);
      mapInstanceRef.current = map;

      L.tileLayer("https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png", {
        attribution: "&copy; OpenStreetMap contributors",
      }).addTo(map);

      const bounds: [number, number][] = [];

      interface LocationPoint {
        lat: number;
        lng: number;
        type: string;
        label: string;
        time: string;
        accuracy: number;
      }

      const locations: LocationPoint[] = [];

      if (hasArrivalLocation) {
        locations.push({
          lat: parseFloat(String(record.arrival_lat)),
          lng: parseFloat(String(record.arrival_lng)),
          type: "arrival",
          label: "Příchod",
          time: formatTime(record.arrival_time),
          accuracy: Number(record.arrival_accuracy) || 0,
        });
      }

      if (hasDepartureLocation) {
        locations.push({
          lat: parseFloat(String(record.departure_lat)),
          lng: parseFloat(String(record.departure_lng)),
          type: "departure",
          label: "Odchod",
          time: formatTime(record.departure_time),
          accuracy: Number(record.departure_accuracy) || 0,
        });
      }

      locations.forEach((loc) => {
        const color = loc.type === "arrival" ? "#22c55e" : "#ef4444";

        const marker = L.circleMarker([loc.lat, loc.lng], {
          radius: 10,
          fillColor: color,
          color: "#fff",
          weight: 2,
          opacity: 1,
          fillOpacity: 0.8,
        }).addTo(map);

        const popupEl = document.createElement("div");
        const strong = document.createElement("strong");
        strong.textContent = loc.label;
        popupEl.appendChild(strong);
        popupEl.appendChild(document.createElement("br"));
        popupEl.appendChild(document.createTextNode(loc.time));
        popupEl.appendChild(document.createElement("br"));
        popupEl.appendChild(
          document.createTextNode(`Přesnost: ${Math.round(loc.accuracy)}m`),
        );
        marker.bindPopup(popupEl);

        if (loc.accuracy > 0) {
          L.circle([loc.lat, loc.lng], {
            radius: loc.accuracy,
            fillColor: color,
            color: color,
            weight: 1,
            opacity: 0.3,
            fillOpacity: 0.1,
          }).addTo(map);
        }

        bounds.push([loc.lat, loc.lng]);
      });

      if (bounds.length === 1) {
        map.setView(bounds[0], 16);
      } else if (bounds.length > 1) {
        map.fitBounds(bounds, { padding: [50, 50] });
      }
    };

    initMap();

    return () => {
      if (mapInstanceRef.current) {
        (mapInstanceRef.current as { remove: () => void }).remove();
        mapInstanceRef.current = null;
      }
    };
  }, [record, isPending]);

  const formatDatetimeLocal = (datetime: string | null | undefined): string => {
    if (!datetime) return "—";
    const d = new Date(datetime);
    return `${d.getDate()}.${d.getMonth() + 1}.${d.getFullYear()} ${formatTime(datetime)}`;
  };

  if (!hasPermission("attendance.manage")) return <Forbidden />;

  if (!record) {
    return null;
  }

  const hasArrivalLocation = record.arrival_lat && record.arrival_lng;
  const hasDepartureLocation = record.departure_lat && record.departure_lng;
  const hasAnyLocation = hasArrivalLocation || hasDepartureLocation;
  const shiftDateStr = record.shift_date.includes("T")
    ? record.shift_date.split("T")[0]
    : record.shift_date;
  const month = shiftDateStr.substring(0, 7);

  if (isPending) {
    return (
      <div className="admin-loading">
        <div className="admin-spinner" />
      </div>
    );
  }

  return (
    <div>
      <motion.div
        className="admin-page-header"
        initial={{ opacity: 0, y: 12 }}
        animate={{ opacity: 1, y: 0 }}
        transition={{ duration: 0.25 }}
      >
        <div>
          <h1 className="admin-page-title">Poloha záznamu</h1>
        </div>
        <div className="admin-page-actions">
          <Link
            to={`/attendance/admin?month=${month}`}
            className="admin-btn admin-btn-secondary"
          >
            &larr; Zpět na správu
          </Link>
        </div>
      </motion.div>

      <motion.div
        className="admin-card"
        initial={{ opacity: 0, y: 12 }}
        animate={{ opacity: 1, y: 0 }}
        transition={{ duration: 0.25, delay: 0.06 }}
      >
        <div className="admin-card-header">
          <h2 className="admin-card-title">
            {record.user_name} — {formatDate(record.shift_date)}
          </h2>
        </div>
        <div className="admin-card-body">
          {hasAnyLocation && (
            <div ref={mapRef} className="attendance-location-map" />
          )}

          <div className="attendance-location-grid">
            {/* Arrival */}
            <div
              className={`attendance-location-card ${!hasArrivalLocation ? "empty" : ""}`}
            >
              <h3 className="attendance-location-title">Příchod</h3>
              <div className="attendance-location-time">
                {record.arrival_time
                  ? formatDatetimeLocal(record.arrival_time)
                  : "—"}
              </div>
              {hasArrivalLocation ? (
                <>
                  <div className="attendance-location-address">
                    {record.arrival_address || <em>Adresa nezjištěna</em>}
                  </div>
                  <div className="attendance-location-coords">
                    GPS: {record.arrival_lat}, {record.arrival_lng}
                    {record.arrival_accuracy &&
                      ` (přesnost: ${Math.round(Number(record.arrival_accuracy))}m)`}
                  </div>
                  <a
                    href={`https://www.google.com/maps?q=${record.arrival_lat},${record.arrival_lng}`}
                    target="_blank"
                    rel="noopener noreferrer"
                    className="admin-btn admin-btn-secondary admin-btn-sm mt-2"
                  >
                    Otevřít v Google Maps
                  </a>
                </>
              ) : (
                <div className="attendance-location-address">
                  <em>Poloha nebyla zaznamenána</em>
                </div>
              )}
            </div>

            {/* Departure */}
            {(hasDepartureLocation || record.departure_time) && (
              <div
                className={`attendance-location-card ${!hasDepartureLocation ? "empty" : ""}`}
              >
                <h3 className="attendance-location-title">Odchod</h3>
                <div className="attendance-location-time">
                  {record.departure_time
                    ? formatDatetimeLocal(record.departure_time)
                    : "—"}
                </div>
                {hasDepartureLocation ? (
                  <>
                    <div className="attendance-location-address">
                      {record.departure_address || <em>Adresa nezjištěna</em>}
                    </div>
                    <div className="attendance-location-coords">
                      GPS: {record.departure_lat}, {record.departure_lng}
                      {record.departure_accuracy &&
                        ` (přesnost: ${Math.round(Number(record.departure_accuracy))}m)`}
                    </div>
                    <a
                      href={`https://www.google.com/maps?q=${record.departure_lat},${record.departure_lng}`}
                      target="_blank"
                      rel="noopener noreferrer"
                      className="admin-btn admin-btn-secondary admin-btn-sm mt-2"
                    >
                      Otevřít v Google Maps
                    </a>
                  </>
                ) : (
                  <div className="attendance-location-address">
                    <em>Poloha nebyla zaznamenána</em>
                  </div>
                )}
              </div>
            )}
          </div>
        </div>
      </motion.div>
    </div>
  );
}
