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 as RouterLink } from "react-router-dom";
import Box from "@mui/material/Box";
import Typography from "@mui/material/Typography";
import { styled } from "@mui/material/styles";

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

// Leaflet map container (was the .attendance-location-map rule). zIndex:0
// creates a stacking context so Leaflet's internal z-indexes stay contained.
const LocationMap = styled("div")(({ theme }) => ({
  height: "400px",
  borderRadius: "8px",
  marginBottom: "1.5rem",
  background: theme.vars!.palette.background.paper,
  position: "relative",
  zIndex: 0,
  "@media (max-width:640px)": {
    height: "clamp(220px, 45vh, 400px)",
  },
}));

import { formatDate, formatTime } from "../utils/attendanceHelpers";
import {
  attendanceLocationOptions,
  type LocationRecord,
} from "../lib/queries/attendance";
import { Button, Card, LoadingState, PageEnter, PageHeader } from "../ui";

const BackIcon = (
  <svg
    width="20"
    height="20"
    viewBox="0 0 24 24"
    fill="none"
    stroke="currentColor"
    strokeWidth="2"
  >
    <path d="M19 12H5M12 19l-7-7 7-7" />
  </svg>
);

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 />;

  // Show the spinner while the record is still loading — this must precede the
  // `!record` null-return below, otherwise a pending query (record === undefined)
  // renders a blank page and this branch is dead.
  if (isPending) {
    return <LoadingState />;
  }

  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);

  return (
    <PageEnter>
      {/* Header */}
      <PageHeader
        title="Poloha záznamu"
        actions={
          <Button
            component={RouterLink}
            to={`/attendance/admin?month=${month}`}
            variant="outlined"
            color="inherit"
            startIcon={BackIcon}
          >
            Zpět na správu
          </Button>
        }
      />

      {/* Info + map card */}
      <Card sx={{ mb: 3 }}>
        <Typography variant="subtitle2" sx={{ mb: 2, fontWeight: 600 }}>
          {record.user_name} — {formatDate(record.shift_date)}
        </Typography>

        {/* Leaflet map */}
        {hasAnyLocation && <LocationMap ref={mapRef} />}

        {/* Location detail grid */}
        <Box
          sx={{
            display: "grid",
            gridTemplateColumns: { xs: "1fr", sm: "1fr 1fr" },
            gap: 2,
            mt: hasAnyLocation ? 2 : 0,
          }}
        >
          {/* Arrival */}
          <Box
            sx={{
              p: 2,
              borderRadius: 1,
              border: "1px solid",
              borderColor: "divider",
              opacity: hasArrivalLocation ? 1 : 0.6,
            }}
          >
            <Typography variant="subtitle2" sx={{ mb: 1, fontWeight: 600 }}>
              Příchod
            </Typography>
            <Typography
              variant="body2"
              sx={{ fontFamily: "'DM Mono', Menlo, monospace", mb: 1 }}
            >
              {record.arrival_time
                ? formatDatetimeLocal(record.arrival_time)
                : "—"}
            </Typography>
            {hasArrivalLocation ? (
              <>
                <Typography variant="body2" sx={{ mb: 0.5 }}>
                  {record.arrival_address || <em>Adresa nezjištěna</em>}
                </Typography>
                <Typography
                  variant="body2"
                  sx={{
                    fontFamily: "'DM Mono', Menlo, monospace",
                    fontSize: "0.75rem",
                    color: "text.secondary",
                    mb: 1,
                  }}
                >
                  GPS: {record.arrival_lat}, {record.arrival_lng}
                  {record.arrival_accuracy &&
                    ` (přesnost: ${Math.round(Number(record.arrival_accuracy))}m)`}
                </Typography>
                <Button
                  component="a"
                  href={`https://www.google.com/maps?q=${record.arrival_lat},${record.arrival_lng}`}
                  target="_blank"
                  rel="noopener noreferrer"
                  variant="outlined"
                  color="inherit"
                  size="small"
                >
                  Otevřít v Google Maps
                </Button>
              </>
            ) : (
              <Typography variant="body2" color="text.secondary">
                <em>Poloha nebyla zaznamenána</em>
              </Typography>
            )}
          </Box>

          {/* Departure */}
          {(hasDepartureLocation || record.departure_time) && (
            <Box
              sx={{
                p: 2,
                borderRadius: 1,
                border: "1px solid",
                borderColor: "divider",
                opacity: hasDepartureLocation ? 1 : 0.6,
              }}
            >
              <Typography variant="subtitle2" sx={{ mb: 1, fontWeight: 600 }}>
                Odchod
              </Typography>
              <Typography
                variant="body2"
                sx={{ fontFamily: "'DM Mono', Menlo, monospace", mb: 1 }}
              >
                {record.departure_time
                  ? formatDatetimeLocal(record.departure_time)
                  : "—"}
              </Typography>
              {hasDepartureLocation ? (
                <>
                  <Typography variant="body2" sx={{ mb: 0.5 }}>
                    {record.departure_address || <em>Adresa nezjištěna</em>}
                  </Typography>
                  <Typography
                    variant="body2"
                    sx={{
                      fontFamily: "'DM Mono', Menlo, monospace",
                      fontSize: "0.75rem",
                      color: "text.secondary",
                      mb: 1,
                    }}
                  >
                    GPS: {record.departure_lat}, {record.departure_lng}
                    {record.departure_accuracy &&
                      ` (přesnost: ${Math.round(Number(record.departure_accuracy))}m)`}
                  </Typography>
                  <Button
                    component="a"
                    href={`https://www.google.com/maps?q=${record.departure_lat},${record.departure_lng}`}
                    target="_blank"
                    rel="noopener noreferrer"
                    variant="outlined"
                    color="inherit"
                    size="small"
                  >
                    Otevřít v Google Maps
                  </Button>
                </>
              ) : (
                <Typography variant="body2" color="text.secondary">
                  <em>Poloha nebyla zaznamenána</em>
                </Typography>
              )}
            </Box>
          )}
        </Box>
      </Card>
    </PageEnter>
  );
}
