"use client";

import { type CSSProperties, useEffect, useRef } from "react";
import { divIcon } from "leaflet";
import { MapContainer, Marker, Pane, Polyline, Popup, TileLayer, ZoomControl, useMap } from "react-leaflet";

import { getVehicleColorHex } from "@tracker/shared";
import type { HistoryPoint, PositionSnapshot, VehicleSummary } from "@tracker/shared";

const TILE_URL = process.env.NEXT_PUBLIC_TILE_URL ?? "https://tile.openstreetmap.org/{z}/{x}/{y}.png";
const TILE_ATTRIBUTION =
  process.env.NEXT_PUBLIC_TILE_ATTRIBUTION ?? "&copy; OpenStreetMap contributors";
const SATELLITE_TILE_URL =
  process.env.NEXT_PUBLIC_SATELLITE_TILE_URL
  ?? "https://services.arcgisonline.com/ArcGIS/rest/services/World_Imagery/MapServer/tile/{z}/{y}/{x}";
const SATELLITE_TILE_ATTRIBUTION =
  process.env.NEXT_PUBLIC_SATELLITE_TILE_ATTRIBUTION
  ?? "Tiles &copy; Esri";

const escapeHtml = (value: string) =>
  value
    .replaceAll("&", "&amp;")
    .replaceAll("<", "&lt;")
    .replaceAll(">", "&gt;")
    .replaceAll('"', "&quot;")
    .replaceAll("'", "&#39;");

const clamp = (value: number, min: number, max: number) => Math.min(max, Math.max(min, value));

const STATIONARY_HIDE_SPEED_MS = 1000 * 60 * 5;

const formatDistanceKm = (distanceKm?: number | null) => {
  if (distanceKm == null || Number.isNaN(distanceKm)) {
    return "Brak";
  }

  return distanceKm >= 10 ? `${distanceKm.toFixed(0)} km` : `${distanceKm.toFixed(1)} km`;
};

const formatDurationMinutes = (durationMinutes?: number | null) => {
  if (durationMinutes == null || Number.isNaN(durationMinutes)) {
    return "Brak";
  }

  const roundedMinutes = Math.max(1, Math.round(durationMinutes));
  const hours = Math.floor(roundedMinutes / 60);
  const minutes = roundedMinutes % 60;

  if (hours === 0) {
    return `${minutes} min`;
  }

  if (minutes === 0) {
    return `${hours} h`;
  }

  return `${hours} h ${minutes} min`;
};

const formatArrivalTime = (durationMinutes?: number | null) => {
  if (durationMinutes == null || Number.isNaN(durationMinutes)) {
    return "Brak";
  }

  const arrivalDate = new Date(Date.now() + Math.max(0, durationMinutes) * 60 * 1000);
  return arrivalDate.toLocaleTimeString("pl-PL", {
    hour: "2-digit",
    minute: "2-digit",
  });
};

const formatSpeedKmh = (speed?: number | null) => {
  if (speed == null || Number.isNaN(speed) || !Number.isFinite(speed)) {
    return "0 km/h";
  }

  const normalized = clamp(Math.ceil(speed), 0, 240);
  return `${normalized} km/h`;
};

const formatDateTime = (value?: string | null) => {
  if (!value) {
    return "brak";
  }

  const date = new Date(value);
  if (Number.isNaN(date.getTime())) {
    return "brak";
  }

  return date.toLocaleString("pl-PL", {
    day: "2-digit",
    month: "2-digit",
    year: "numeric",
    hour: "2-digit",
    minute: "2-digit",
  });
};

const getPointTimestamp = (point?: Pick<HistoryPoint, "deviceTime" | "serverTime"> | null) => {
  if (!point) {
    return null;
  }

  const rawValue = point.deviceTime ?? point.serverTime;
  if (!rawValue) {
    return null;
  }

  const timestamp = new Date(rawValue).getTime();
  return Number.isNaN(timestamp) ? null : timestamp;
};

const isMovingPoint = (point?: Pick<HistoryPoint, "speed"> | null) => (point?.speed ?? 0) > 0;

const getVehicleStopInfo = (
  point: PositionSnapshot,
  historyForVehicle: HistoryPoint[],
) => {
  const pointTimestamp = getPointTimestamp(point);
  const fallbackLabel = point.deviceTime ?? point.serverTime ?? null;

  if (point.ignition !== false) {
    return {
      isStoppedLongEnough: false,
      stopStartedAt: null as string | null,
      lastDriveEndedAt: null as string | null,
    };
  }

  const relevantHistory = historyForVehicle
    .slice()
    .sort((a, b) => (getPointTimestamp(a) ?? 0) - (getPointTimestamp(b) ?? 0));

  let stopStartedAt = fallbackLabel;
  let lastDriveEndedAt = fallbackLabel;

  for (let index = relevantHistory.length - 1; index >= 0; index -= 1) {
    const candidate = relevantHistory[index];
    const candidateTimestamp = getPointTimestamp(candidate);

    if (candidateTimestamp == null || pointTimestamp == null || candidateTimestamp > pointTimestamp) {
      continue;
    }

    if (candidate.ignition === true) {
      lastDriveEndedAt = candidate.deviceTime ?? candidate.serverTime ?? lastDriveEndedAt;
      break;
    }

    if (candidate.ignition === false) {
      stopStartedAt = candidate.deviceTime ?? candidate.serverTime ?? stopStartedAt;
      lastDriveEndedAt = stopStartedAt;
    }
  }

  const stopStartedTimestamp = stopStartedAt ? new Date(stopStartedAt).getTime() : pointTimestamp;
  const isStoppedLongEnough = stopStartedTimestamp != null
    ? (pointTimestamp ?? stopStartedTimestamp) - stopStartedTimestamp >= STATIONARY_HIDE_SPEED_MS
    : false;

  return {
    isStoppedLongEnough,
    stopStartedAt,
    lastDriveEndedAt,
  };
};

const shiftHex = (hex: string, amount: number) => {
  const normalized = hex.replace("#", "");
  const safeHex = normalized.length === 6 ? normalized : "4068F8";
  const [r, g, b] = [0, 2, 4].map((offset) => Number.parseInt(safeHex.slice(offset, offset + 2), 16));
  const shifted = [r, g, b]
    .map((channel) => clamp(channel + amount, 0, 255).toString(16).padStart(2, "0"))
    .join("");

  return `#${shifted}`;
};

const getHeadingLabel = (heading?: number | null) => {
  if (heading == null || Number.isNaN(heading)) {
    return "N";
  }

  const normalized = ((heading % 360) + 360) % 360;
  const directions = ["N", "NE", "E", "SE", "S", "SW", "W", "NW"];
  return directions[Math.round(normalized / 45) % 8];
};

const getBearingBetweenPoints = (
  start: Pick<HistoryPoint, "lat" | "lon">,
  end: Pick<HistoryPoint, "lat" | "lon">,
) => {
  const toRad = (value: number) => (value * Math.PI) / 180;
  const toDeg = (value: number) => (value * 180) / Math.PI;
  const lat1 = toRad(start.lat);
  const lat2 = toRad(end.lat);
  const deltaLon = toRad(end.lon - start.lon);

  const y = Math.sin(deltaLon) * Math.cos(lat2);
  const x = Math.cos(lat1) * Math.sin(lat2)
    - Math.sin(lat1) * Math.cos(lat2) * Math.cos(deltaLon);

  return (toDeg(Math.atan2(y, x)) + 360) % 360;
};

const getPlaybackPoint = (
  points: HistoryPoint[],
  playbackTimestamp: number | null,
  playbackDirection: "forward" | "backward",
) => {
  if (points.length === 0) {
    return null;
  }

  if (points.length === 1) {
    return points[0] ?? null;
  }

  if (playbackTimestamp == null) {
    return playbackDirection === "backward"
      ? (points[points.length - 1] ?? null)
      : (points[0] ?? null);
  }

  const stampedPoints = points
    .map((point) => ({
      point,
      timestamp: getPointTimestamp(point),
    }))
    .filter((entry): entry is { point: HistoryPoint; timestamp: number } => entry.timestamp != null);

  if (stampedPoints.length === 0) {
    return playbackDirection === "backward"
      ? (points[points.length - 1] ?? null)
      : (points[0] ?? null);
  }

  if (stampedPoints.length === 1) {
    return stampedPoints[0].point;
  }

  if (playbackTimestamp <= stampedPoints[0].timestamp) {
    const heading = playbackDirection === "backward"
      ? getBearingBetweenPoints(stampedPoints[1].point, stampedPoints[0].point)
      : getBearingBetweenPoints(stampedPoints[0].point, stampedPoints[1].point);
    return { ...stampedPoints[0].point, heading };
  }

  const lastStampedPoint = stampedPoints[stampedPoints.length - 1];
  if (playbackTimestamp >= lastStampedPoint.timestamp) {
    const previousStampedPoint = stampedPoints[stampedPoints.length - 2];
    const heading = playbackDirection === "backward"
      ? getBearingBetweenPoints(lastStampedPoint.point, previousStampedPoint.point)
      : getBearingBetweenPoints(previousStampedPoint.point, lastStampedPoint.point);
    return { ...lastStampedPoint.point, heading };
  }

  for (let index = 0; index < stampedPoints.length - 1; index += 1) {
    const current = stampedPoints[index];
    const next = stampedPoints[index + 1];

    if (playbackTimestamp < current.timestamp || playbackTimestamp > next.timestamp) {
      continue;
    }

    const segmentDuration = next.timestamp - current.timestamp;
    const progress = segmentDuration === 0 ? 0 : (playbackTimestamp - current.timestamp) / segmentDuration;
    const lat = current.point.lat + (next.point.lat - current.point.lat) * progress;
    const lon = current.point.lon + (next.point.lon - current.point.lon) * progress;
    const heading = playbackDirection === "backward"
      ? getBearingBetweenPoints(next.point, current.point)
      : getBearingBetweenPoints(current.point, next.point);
    const referencePoint = progress < 0.5 ? current.point : next.point;

    return {
      ...referencePoint,
      lat,
      lon,
      heading,
      speed: current.point.speed != null && next.point.speed != null
        ? current.point.speed + (next.point.speed - current.point.speed) * progress
        : referencePoint.speed ?? null,
      serverTime: new Date(playbackTimestamp).toISOString(),
      deviceTime: new Date(playbackTimestamp).toISOString(),
    };
  }

  return lastStampedPoint.point;
};

const distanceMeters = (a: HistoryPoint, b: HistoryPoint) => {
  const toRad = (value: number) => (value * Math.PI) / 180;
  const earthRadius = 6_371_000;
  const dLat = toRad(b.lat - a.lat);
  const dLon = toRad(b.lon - a.lon);
  const lat1 = toRad(a.lat);
  const lat2 = toRad(b.lat);
  const haversine = Math.sin(dLat / 2) ** 2
    + Math.cos(lat1) * Math.cos(lat2) * Math.sin(dLon / 2) ** 2;

  return 2 * earthRadius * Math.atan2(Math.sqrt(haversine), Math.sqrt(1 - haversine));
};

const filterHistoryPath = (points: HistoryPoint[]) =>
  points.reduce<HistoryPoint[]>((accumulator, point) => {
    if (accumulator.length === 0) {
      return [point];
    }

    const previousPoint = accumulator[accumulator.length - 1];
    if (distanceMeters(previousPoint, point) <= 5) {
      return accumulator;
    }

    return [...accumulator, point];
  }, []);

const getRenderableHistoryPath = (points: HistoryPoint[]) => {
  const filtered = filterHistoryPath(points);
  if (filtered.length > 1 || points.length <= 1) {
    return filtered;
  }

  return points;
};

const buildVehicleIcon = (color: string, heading: number, active: boolean, status: string, label?: string) =>
  divIcon({
    className: "vehicle-marker-wrapper",
    html: `
      <div class="vehicle-marker ${active ? "is-active" : ""} is-${status}" style="--vehicle-color:${color}; --vehicle-rotation:${heading}deg;">
        <div class="vehicle-marker__body">
          <svg viewBox="0 0 88 172" aria-hidden="true">
            <g fill="none" fill-rule="evenodd">
              <path d="M18 9c7-6 45-6 52 0 9 9 12 27 13 76 1 48-4 71-13 79-7 6-45 6-52 0C9 156 4 133 5 85 6 36 9 18 18 9Z" fill="${shiftHex(color, -36)}"/>
              <path d="M22 14c6-5 38-5 44 0 8 8 10 24 11 71 1 44-3 65-11 72-6 5-38 5-44 0-8-7-12-28-11-72 1-47 3-63 11-71Z" fill="${shiftHex(color, 8)}"/>
              <path d="M27 19h34c8 0 14 6 16 19l2 12H9l2-12c2-13 8-19 16-19Z" fill="#102F45"/>
              <path d="M9 122h70l-2 13c-2 13-8 19-16 19H27c-8 0-14-6-16-19l-2-13Z" fill="#102F45"/>
              <path d="M13 45h11v37H13zM13 85h11v37H13zM64 45h11v37H64zM64 85h11v37H64z" fill="#0C2433"/>
              <path d="M18 9c7-6 45-6 52 0" stroke="#2F2F2F" stroke-width="5" stroke-linecap="round"/>
              <path d="M5 84c0-46 4-67 13-75M83 84c0-46-4-67-13-75" stroke="#2F2F2F" stroke-width="5" stroke-linecap="round"/>
              <path d="M18 164c7 6 45 6 52 0" stroke="#2F2F2F" stroke-width="5" stroke-linecap="round"/>
              <path d="M6 40H1M87 40h-5" stroke="#2F2F2F" stroke-width="5" stroke-linecap="round"/>
              <path d="M26 25h36c7 0 12 5 13 15l1 6H12l1-6c1-10 6-15 13-15Z" fill="#0C2433"/>
              <path d="M13 128h62l-1 6c-1 10-6 15-13 15H27c-7 0-12-5-13-15l-1-6Z" fill="#0C2433"/>
            </g>
          </svg>
        </div>
        ${label ? `<div class="vehicle-marker__label">${escapeHtml(label)}</div>` : ""}
      </div>
    `,
    iconSize: [14, 28],
    iconAnchor: [7, 14],
    popupAnchor: [0, -14],
  });

const FitMap = ({
  vehicles,
  activeVehicle,
  focusVehicleKey,
  isBottomPanelExpanded,
  history,
  playbackTimestamp,
  overviewKey,
  showHistoryPath,
}: {
  vehicles: VehicleSummary[];
  activeVehicle?: VehicleSummary | null;
  focusVehicleKey?: string | null;
  isBottomPanelExpanded?: boolean;
  history: HistoryPoint[];
  playbackTimestamp?: number | null;
  overviewKey?: string | null;
  showHistoryPath: boolean;
}) => {
  const map = useMap();
  const viewportKeyRef = useRef<string | null>(null);
  const focusKeyRef = useRef<string | null>(null);
  const liveFollowKeyRef = useRef<string | null>(null);

  const getAdjustedCenter = (lat: number, lon: number) => {
    if (typeof window === "undefined" || window.innerWidth >= 768) {
      return [lat, lon] as [number, number];
    }

    const point = map.project([lat, lon], map.getZoom());
    const offsetY = map.getSize().y * (isBottomPanelExpanded ? 0.24 : -0.18);
    const adjusted = map.unproject(point.add([0, offsetY]), map.getZoom());
    return [adjusted.lat, adjusted.lng] as [number, number];
  };

  useEffect(() => {
    if (!focusVehicleKey || !activeVehicle?.lastPosition || showHistoryPath) {
      return;
    }

    if (focusKeyRef.current === focusVehicleKey) {
      return;
    }

    const point = activeVehicle.lastPosition;
    const targetZoom = Math.max(
      map.getZoom(),
      typeof window !== "undefined" && window.innerWidth < 768 ? 18 : 16,
    );
    map.setView(getAdjustedCenter(point.lat, point.lon), targetZoom, { animate: true });
    focusKeyRef.current = focusVehicleKey;
    viewportKeyRef.current = `focus:${focusVehicleKey}`;
  }, [activeVehicle, focusVehicleKey, map, showHistoryPath]);

  useEffect(() => {
    if (!overviewKey) {
      return;
    }

    const overviewViewportKey = `overview:${overviewKey}`;
    if (viewportKeyRef.current === overviewViewportKey) {
      return;
    }

    const positions = vehicles
      .map((vehicle) => vehicle.lastPosition)
      .filter((point): point is NonNullable<VehicleSummary["lastPosition"]> => point != null)
      .map((point) => [point.lat, point.lon] as [number, number]);

    if (positions.length > 1) {
      const fitPadding = typeof window !== "undefined" && window.innerWidth >= 1280
        ? { paddingTopLeft: [50, 60] as [number, number], paddingBottomRight: [410, 80] as [number, number] }
        : { paddingTopLeft: [40, 40] as [number, number], paddingBottomRight: [40, 40] as [number, number] };
      map.fitBounds(positions, fitPadding);
      const centerAfterFit = map.getCenter();
      map.setView(getAdjustedCenter(centerAfterFit.lat, centerAfterFit.lng), map.getZoom(), { animate: true });
      viewportKeyRef.current = overviewViewportKey;
      return;
    }

    if (positions.length === 1) {
      const [lat, lon] = positions[0];
      map.panTo(getAdjustedCenter(lat, lon));
      viewportKeyRef.current = overviewViewportKey;
    }
  }, [isBottomPanelExpanded, map, overviewKey, vehicles]);

  useEffect(() => {
    if (overviewKey) {
      return;
    }

    if (!activeVehicle && history.length === 0) {
      return;
    }

    const shouldFitHistory = showHistoryPath && history.length > 1;
    const historyKey = shouldFitHistory
      ? `history:${activeVehicle?.id ?? "none"}:${history[0]?.id ?? "start"}:${history[history.length - 1]?.id ?? "end"}:${history.length}`
      : `vehicle:${activeVehicle?.id ?? "none"}`;

    if (viewportKeyRef.current === historyKey) {
      return;
    }

    if (shouldFitHistory) {
      const focusPoint = history.length > 0
        ? getPlaybackPoint(history, playbackTimestamp ?? getPointTimestamp(history[0]), "forward") ?? history[0]
        : null;

      if (focusPoint) {
        const targetZoom = Math.max(
          map.getZoom(),
          typeof window !== "undefined" && window.innerWidth < 768 ? 18 : 15,
        );
        map.setView(getAdjustedCenter(focusPoint.lat, focusPoint.lon), targetZoom, { animate: true });
      }
      viewportKeyRef.current = historyKey;
      return;
    }

    const point = activeVehicle?.lastPosition;
    if (point) {
      map.panTo(getAdjustedCenter(point.lat, point.lon));
      viewportKeyRef.current = historyKey;
    }
  }, [activeVehicle, history, isBottomPanelExpanded, map, overviewKey, playbackTimestamp, showHistoryPath]);

  useEffect(() => {
    if (overviewKey || showHistoryPath) {
      liveFollowKeyRef.current = null;
      return;
    }

    const point = activeVehicle?.lastPosition;
    if (!activeVehicle || !point) {
      liveFollowKeyRef.current = null;
      return;
    }

    const followKey = [
      activeVehicle.id,
      point.serverTime ?? point.deviceTime ?? "",
      point.lat.toFixed(6),
      point.lon.toFixed(6),
    ].join(":");

    if (liveFollowKeyRef.current === followKey) {
      return;
    }

    map.panTo(getAdjustedCenter(point.lat, point.lon), { animate: true });
    liveFollowKeyRef.current = followKey;
  }, [activeVehicle, isBottomPanelExpanded, map, overviewKey, showHistoryPath]);

  return null;
};

const ClosePopupOnSelectionChange = ({
  selectionKey,
}: {
  selectionKey: string;
}) => {
  const map = useMap();
  const previousSelectionKeyRef = useRef<string | null>(null);

  useEffect(() => {
    if (previousSelectionKeyRef.current == null) {
      previousSelectionKeyRef.current = selectionKey;
      return;
    }

    if (previousSelectionKeyRef.current !== selectionKey) {
      map.closePopup();
      previousSelectionKeyRef.current = selectionKey;
    }
  }, [map, selectionKey]);

  return null;
};

export function MapView({
  vehicles,
  activeVehicleId,
  focusVehicleKey,
  isBottomPanelExpanded,
  closePopupKey,
  history,
  playbackTimestamp,
  playbackDirection,
  showHistoryPath,
  overviewKey,
  tileMode,
  popupAddress,
  companyDistanceKm,
  companyDurationMinutes,
  onTileModeChange,
  onVehicleSelect,
}: {
  vehicles: VehicleSummary[];
  activeVehicleId?: string | null;
  focusVehicleKey?: string | null;
  isBottomPanelExpanded?: boolean;
  closePopupKey?: string | null;
  history: HistoryPoint[];
  playbackTimestamp?: number | null;
  playbackDirection: "forward" | "backward";
  showHistoryPath: boolean;
  overviewKey?: string | null;
  tileMode: "standard" | "satellite";
  popupAddress?: string | null;
  companyDistanceKm?: number | null;
  companyDurationMinutes?: number | null;
  onTileModeChange?: (nextMode: "standard" | "satellite") => void;
  onVehicleSelect?: (vehicleId: string) => void;
}) {
  const activeVehicle = vehicles.find((vehicle) => vehicle.id === activeVehicleId) ?? null;
  const playbackPoint = history.length > 0
    ? getPlaybackPoint(history, playbackTimestamp ?? null, playbackDirection)
    : null;
  const center = showHistoryPath && playbackPoint
    ? ([playbackPoint.lat, playbackPoint.lon] as [number, number])
    : activeVehicle?.lastPosition
      ? ([activeVehicle.lastPosition.lat, activeVehicle.lastPosition.lon] as [number, number])
    : ([52.2297, 21.0122] as [number, number]);
  const activeVehicleColor = getVehicleColorHex(activeVehicle?.colorKey);
  const visibleHistory = showHistoryPath ? getRenderableHistoryPath(history) : [];
  const completedHistory = playbackPoint
    ? [
        ...visibleHistory.filter((point) => {
          const pointTimestamp = new Date(point.deviceTime ?? point.serverTime).getTime();
          return !Number.isNaN(pointTimestamp) && playbackTimestamp != null && pointTimestamp <= playbackTimestamp;
        }),
        playbackPoint,
      ]
    : [];
  const upcomingHistory = playbackPoint
    ? [
        playbackPoint,
        ...visibleHistory.filter((point) => {
          const pointTimestamp = new Date(point.deviceTime ?? point.serverTime).getTime();
          return !Number.isNaN(pointTimestamp) && playbackTimestamp != null && pointTimestamp >= playbackTimestamp;
        }),
      ]
    : visibleHistory;
  const selectionKey = closePopupKey ?? "popup-idle";

  return (
    <div className="brand-map-canvas relative h-full w-full rounded-[1.75rem]">
      <MapContainer
        center={center}
        zoom={6}
        minZoom={4}
        maxZoom={26}
        zoomSnap={0}
        zoomDelta={0.25}
        wheelPxPerZoomLevel={120}
        wheelDebounceTime={20}
        touchZoom="center"
        doubleClickZoom
        bounceAtZoomLimits={false}
        scrollWheelZoom
        zoomControl={false}
        className="h-full w-full rounded-[1.75rem]"
      >
        <ClosePopupOnSelectionChange selectionKey={selectionKey} />
        <TileLayer
          attribution={tileMode === "satellite" ? SATELLITE_TILE_ATTRIBUTION : TILE_ATTRIBUTION}
          url={tileMode === "satellite" ? SATELLITE_TILE_URL : TILE_URL}
        />
        <ZoomControl position="topleft" />
        <Pane name="history">
        {visibleHistory.length > 1 ? (
          <>
            <Polyline
              positions={upcomingHistory.map((point) => [point.lat, point.lon])}
              pathOptions={{ color: activeVehicleColor, weight: 5, opacity: 0.72 }}
            />
            <Polyline
              positions={completedHistory.map((point) => [point.lat, point.lon])}
              pathOptions={{ color: "#8ea2b7", weight: 4, opacity: 0.28 }}
            />
          </>
        ) : null}
        </Pane>
        {vehicles.map((vehicle) => {
        const point = vehicle.id === activeVehicleId && showHistoryPath && playbackPoint
          ? playbackPoint
          : vehicle.lastPosition;
        if (!point) {
          return null;
        }

        const stopInfo = getVehicleStopInfo(
          point,
          vehicle.id === activeVehicleId ? history : [],
        );
        const popupIgnitionOn = vehicle.deviceState?.ignition === true || point.ignition === true;

        const color = getVehicleColorHex(vehicle.colorKey);

        return (
          <Marker
            key={vehicle.id}
            position={[point.lat, point.lon]}
            icon={buildVehicleIcon(
              color,
              point.heading ?? 0,
              vehicle.id === activeVehicleId,
              vehicle.status,
              vehicle.name,
            )}
            eventHandlers={{
              click: () => onVehicleSelect?.(vehicle.id),
            }}
          >
            <Popup className="vehicle-status-popup" autoPan={false} autoPanPadding={[28, 28]}>
              <div
                className="vehicle-status-card"
                style={
                  {
                    "--popup-accent": color,
                    "--popup-accent-soft": `${color}22`,
                    "--popup-accent-strong": shiftHex(color, 18),
                  } as CSSProperties
                }
              >
                <div className="vehicle-status-card__header">
                  <div className="vehicle-status-card__titlewrap">
                    <div className="vehicle-status-card__title">
                      {vehicle.name.toUpperCase()}
                    </div>
                    {vehicle.plateNumber ? (
                      <div className="vehicle-status-card__plate">| {vehicle.plateNumber.toUpperCase()}</div>
                    ) : null}
                  </div>
                  <div className="vehicle-status-card__speedbadge min-w-[88px] text-center tabular-nums">
                    {formatSpeedKmh(point.speed)}
                  </div>
                </div>

                <div className="vehicle-status-card__row">
                  <span className="vehicle-status-card__icon vehicle-status-card__icon--pin" aria-hidden="true">
                    <svg viewBox="0 0 24 24" className="h-4 w-4" fill="currentColor">
                      <path d="M12 2C8.13 2 5 5.13 5 9c0 5.25 7 13 7 13s7-7.75 7-13c0-3.87-3.13-7-7-7Zm0 9.5A2.5 2.5 0 1 1 12 6.5a2.5 2.5 0 0 1 0 5Z" />
                    </svg>
                  </span>
                  <span className="vehicle-status-card__text">
                    {vehicle.id === activeVehicleId ? (popupAddress ?? "Ładowanie adresu...") : "Kliknij, aby wczytać adres"}
                  </span>
                </div>

                <div className="vehicle-status-card__row">
                  <span className="vehicle-status-card__icon vehicle-status-card__icon--road" aria-hidden="true">
                    <svg viewBox="0 0 24 24" className="h-4 w-4" fill="currentColor">
                      <path d="M18 4l2 16h-4l-1.1-8H13v8h-2v-8H9.1L8 20H4L6 4h4l-.8 6H11V4h2v6h1.8L14 4h4Z" />
                    </svg>
                  </span>
                  <span className="vehicle-status-card__text text-[11px]">
                    {vehicle.id === activeVehicleId ? (
                      popupIgnitionOn
                        ? (
                          <>
                            Na P20 - <span className="vehicle-status-card__value">{formatDurationMinutes(companyDurationMinutes)}</span>,{" "}
                            dojazd <span className="vehicle-status-card__value vehicle-status-card__value--eta">{formatArrivalTime(companyDurationMinutes)}</span>,{" "}
                            <span className="vehicle-status-card__value">{formatDistanceKm(companyDistanceKm)}</span>
                          </>
                        )
                        : (
                          <>
                            Na P20 - <span className="vehicle-status-card__value">{formatDistanceKm(companyDistanceKm)}</span>
                          </>
                        )
                    ) : "Brak"}
                  </span>
                </div>

                <div className="vehicle-status-card__row vehicle-status-card__row--between">
                  <div className="vehicle-status-card__meta">
                    <span className="vehicle-status-card__icon vehicle-status-card__icon--gps" aria-hidden="true">
                      <svg viewBox="0 0 24 24" className="h-4 w-4" fill="currentColor">
                        <path d="M12 2a1 1 0 0 1 1 1v1.06a8.002 8.002 0 0 1 6.94 6.94H21a1 1 0 1 1 0 2h-1.06a8.002 8.002 0 0 1-6.94 6.94V21a1 1 0 1 1-2 0v-1.06a8.002 8.002 0 0 1-6.94-6.94H3a1 1 0 1 1 0-2h1.06a8.002 8.002 0 0 1 6.94-6.94V3a1 1 0 0 1 1-1Zm0 4a6 6 0 1 0 0 12a6 6 0 0 0 0-12Zm0 2.5a3.5 3.5 0 1 1 0 7a3.5 3.5 0 0 1 0-7Zm0 2a1.5 1.5 0 1 0 0 3a1.5 1.5 0 0 0 0-3Z" />
                      </svg>
                    </span>
                    <span className="vehicle-status-card__text">
                      GPS: <span className="vehicle-status-card__value">{vehicle.deviceState?.satelliteCount ?? point.satelliteCount ?? "Brak"}</span>
                    </span>
                  </div>
                  <div className="vehicle-status-card__meta">
                    <span
                      className="vehicle-status-card__icon vehicle-status-card__icon--nav"
                      aria-hidden="true"
                      style={{ transform: `rotate(${point.heading ?? 0}deg)` }}
                    >
                      <svg viewBox="0 0 24 24" className="h-4 w-4" fill="currentColor">
                        <path d="M12 2 19 21l-7-4-7 4L12 2Z" />
                      </svg>
                    </span>
                    <span className="vehicle-status-card__text">
                      {getHeadingLabel(point.heading)}
                    </span>
                  </div>
                  <span className="vehicle-status-card__icon vehicle-status-card__icon--battery" aria-hidden="true">
                    <svg viewBox="0 0 24 24" className="h-4 w-4" fill="currentColor">
                      <path d="M15.67 4H14V2h-4v2H8.33C7.6 4 7 4.6 7 5.33v13.34C7 19.4 7.6 20 8.33 20h7.34c.73 0 1.33-.6 1.33-1.33V5.33C17 4.6 16.4 4 15.67 4M9 6h6v4H9V6m2 12v-2H9v-2h2v-2h2v2h2v2h-2v2h-2Z" />
                    </svg>
                  </span>
                  <span className="vehicle-status-card__text">
                    <span className="vehicle-status-card__value">{vehicle.deviceState?.battery ?? point.battery ?? "Brak"}%</span>
                  </span>
                </div>

                <div className="vehicle-status-card__row">
                  <span className="vehicle-status-card__icon vehicle-status-card__icon--ignition" aria-hidden="true">
                    <svg viewBox="0 0 24 24" className="h-4 w-4" fill="currentColor">
                      <path d="M13 3h-2v10h2V3Zm4.83 2.17-1.42 1.42A7 7 0 1 1 7.59 6.6L6.17 5.17A9 9 0 1 0 17.83 5.17Z" />
                    </svg>
                  </span>
                  <span className="vehicle-status-card__text">
                    {popupIgnitionOn ? (
                      <span className="vehicle-status-card__value vehicle-status-card__value--moving uppercase tracking-[0.14em]">W drodze</span>
                    ) : (
                      <>
                        Zapłon: <span className="vehicle-status-card__value">OFF</span>
                        {stopInfo.stopStartedAt ? (
                          <>
                            {" "}od <span className="vehicle-status-card__value">{formatDateTime(stopInfo.stopStartedAt)}</span>
                          </>
                        ) : null}
                      </>
                    )}
                  </span>
                </div>
              </div>
            </Popup>
          </Marker>
        );
        })}
        <FitMap
          vehicles={vehicles}
          activeVehicle={activeVehicle}
          focusVehicleKey={focusVehicleKey}
          isBottomPanelExpanded={isBottomPanelExpanded}
          history={history}
          playbackTimestamp={playbackTimestamp}
          overviewKey={overviewKey}
          showHistoryPath={showHistoryPath}
        />
      </MapContainer>
      <button
        type="button"
        onClick={() => onTileModeChange?.(tileMode === "standard" ? "satellite" : "standard")}
        className="map-layer-toggle flex h-10 w-10 items-center justify-center rounded-xl border border-slate-200 bg-white/90 text-ink shadow-md"
        aria-label={tileMode === "standard" ? "Przełącz na mapę satelitarną" : "Przełącz na mapę standardową"}
        title={tileMode === "standard" ? "Mapa satelitarna" : "Mapa standardowa"}
      >
        <svg viewBox="0 0 24 24" className="h-5 w-5" fill="currentColor" aria-hidden="true">
          {tileMode === "standard" ? (
            <path d="M3,5L8,3L16,6L21,4V19L16,21L8,18L3,20V5M8,5V16L16,19V8L8,5Z" />
          ) : (
            <path d="M3,5H21V19H3V5M5,7V17H19V7H5M7,9H11V13H7V9M13,9H17V11H13V9M13,12H17V15H13V12M7,14H11V15H7V14Z" />
          )}
        </svg>
      </button>
    </div>
  );
}
