"use client";

import { memo, type CSSProperties, useEffect, useMemo, useRef, useState } from "react";
import { divIcon, type Marker as LeafletMarker } from "leaflet";
import { MapContainer, Marker, Pane, Polyline, Popup, TileLayer, ZoomControl, useMap, useMapEvents } 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 MAZOWIECKIE_MIN_OVERVIEW_ZOOM = 8;
const COMPANY_OVERVIEW_ZOOM = 18;
const vehicleIconCache = new Map<string, ReturnType<typeof divIcon>>();

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: Pick<HistoryPoint, "lat" | "lon">,
  b: Pick<HistoryPoint, "lat" | "lon">,
) => {
  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 offsetPointMeters = (lat: number, lon: number, eastMeters: number, northMeters = 0) => {
  const earthRadius = 6_378_137;
  const dLat = (northMeters / earthRadius) * (180 / Math.PI);
  const dLon = (eastMeters / (earthRadius * Math.cos((lat * Math.PI) / 180))) * (180 / Math.PI);

  return {
    lat: lat + dLat,
    lon: lon + dLon,
  };
};

const getDenseMarkerOrderWeight = (name: string) => {
  const normalized = name.trim().toUpperCase();
  if (normalized.startsWith("F")) {
    return 0;
  }
  if (normalized.startsWith("MB")) {
    return 1;
  }
  if (normalized.startsWith("T")) {
    return 2;
  }

  return 3;
};

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 normalizeInspectionDate = (value?: string | null) => {
  if (!value) {
    return null;
  }

  const trimmed = value.trim();
  if (!trimmed) {
    return null;
  }

  const dateOnlyMatch = trimmed.match(/^(\d{4}-\d{2}-\d{2})/);
  if (dateOnlyMatch) {
    return dateOnlyMatch[1] ?? null;
  }

  const parsed = new Date(trimmed);
  if (Number.isNaN(parsed.getTime())) {
    return null;
  }

  return parsed.toISOString().slice(0, 10);
};

const formatInspectionDueDate = (value?: string | null) => {
  const normalizedInspectionDate = normalizeInspectionDate(value);
  if (!normalizedInspectionDate) {
    return "Brak";
  }

  const date = new Date(`${normalizedInspectionDate}T00:00:00`);
  if (Number.isNaN(date.getTime())) {
    return normalizedInspectionDate;
  }

  return new Intl.DateTimeFormat("pl-PL", {
    year: "numeric",
    month: "2-digit",
    day: "2-digit",
  }).format(date);
};

type InspectionVisualState = "ok" | "missing" | "due_soon" | "overdue";

const getInspectionVisualState = (
  inspectionStatus?: VehicleSummary["inspectionStatus"],
  inspectionDueDate?: string | null,
): InspectionVisualState => {
  const normalizedInspectionDate = normalizeInspectionDate(inspectionDueDate);
  if (!normalizedInspectionDate) {
    return inspectionStatus === "missing" ? "missing" : "missing";
  }

  const today = new Date();
  const todayUtc = Date.UTC(today.getFullYear(), today.getMonth(), today.getDate());
  const dueDate = new Date(`${normalizedInspectionDate}T00:00:00`);
  const dueUtc = Date.UTC(dueDate.getFullYear(), dueDate.getMonth(), dueDate.getDate());

  if (Number.isNaN(dueUtc)) {
    return "missing";
  }

  const dayDiff = Math.floor((dueUtc - todayUtc) / 86400000);
  if (dayDiff < 0) {
    return "overdue";
  }

  if (dayDiff <= 14 || inspectionStatus === "due_soon") {
    return "due_soon";
  }

  return "ok";
};

const buildVehicleIcon = (
  color: string,
  heading: number,
  active: boolean,
  status: string,
  label?: string,
  inspectionVisualState?: InspectionVisualState,
) => {
  const cacheKey = [
    color,
    Math.round(heading),
    active ? 1 : 0,
    status,
    label ?? "",
    inspectionVisualState ?? "ok",
  ].join("|");
  const cachedIcon = vehicleIconCache.get(cacheKey);
  if (cachedIcon) {
    return cachedIcon;
  }

  const icon = divIcon({
    className: "vehicle-marker-wrapper",
    html: `
      <div class="vehicle-marker ${active ? "is-active" : ""} is-${status} ${inspectionVisualState && inspectionVisualState !== "ok" ? "vehicle-marker--inspection-warning" : ""}" style="--vehicle-color:${color}; --vehicle-rotation:${heading}deg;">
        ${inspectionVisualState && inspectionVisualState !== "ok" ? '<div class="vehicle-marker__inspection-overdue-glow"></div>' : ""}
        <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: [24, 38],
    iconAnchor: [12, 12],
    popupAnchor: [0, -12],
  });
  vehicleIconCache.set(cacheKey, icon);
  return icon;
};

const FitMap = ({
  vehicles,
  activeVehicle,
  focusVehicleKey,
  historyFocusKey,
  isUserInteracting,
  isBottomPanelExpanded,
  history,
  playbackTimestamp,
  overviewKey,
  overviewMode,
  overviewVehicleIds,
  companyOverviewCenter,
  showHistoryPath,
}: {
  vehicles: VehicleSummary[];
  activeVehicle?: VehicleSummary | null;
  focusVehicleKey?: string | null;
  historyFocusKey?: string | null;
  isUserInteracting?: boolean;
  isBottomPanelExpanded?: boolean;
  history: HistoryPoint[];
  playbackTimestamp?: number | null;
  overviewKey?: string | null;
  overviewMode?: "all" | "warsaw" | "company" | null;
  overviewVehicleIds?: string[] | null;
  companyOverviewCenter?: { lat: number; lon: number } | 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 liveLastPanAtRef = useRef(0);
  const historyFollowKeyRef = useRef<string | null>(null);
  const historyLastPanAtRef = useRef(0);

  const getSafeViewportPadding = () => {
    const mapSize = map.getSize();

    if (typeof window !== "undefined" && window.innerWidth >= 768) {
      return {
        top: clamp(Math.round(mapSize.y * 0.16), 140, 220),
        left: clamp(Math.round(mapSize.x * 0.06), 60, 110),
        bottom: clamp(Math.round(mapSize.y * 0.12), 80, 150),
        right: clamp(Math.round(mapSize.x * 0.3), 320, 520),
      };
    }

    return {
      top: clamp(Math.round(mapSize.y * 0.15), 96, 150),
      left: clamp(Math.round(mapSize.x * 0.08), 28, 52),
      bottom: isBottomPanelExpanded
        ? clamp(Math.round(mapSize.y * 0.35), 220, 340)
        : clamp(Math.round(mapSize.y * 0.18), 110, 170),
      right: clamp(Math.round(mapSize.x * 0.08), 28, 52),
    };
  };

  const getAdjustedCenter = (lat: number, lon: number) => {
    const point = map.project([lat, lon], map.getZoom());
    const mapSize = map.getSize();
    const safePadding = getSafeViewportPadding();
    const offsetX = (safePadding.left - safePadding.right) / 2;
    const offsetY = (safePadding.top - safePadding.bottom) / 2;
    const adjusted = map.unproject(
      point.add([offsetX, offsetY]),
      map.getZoom(),
    );

    return [adjusted.lat, adjusted.lng] as [number, number];
  };

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

    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,
    );
    const applyVehicleFocus = () => {
      map.invalidateSize(false);
      map.setView(getAdjustedCenter(point.lat, point.lon), targetZoom, { animate: false });
    };

    applyVehicleFocus();
    window.requestAnimationFrame(applyVehicleFocus);
    focusKeyRef.current = focusVehicleKey;
    viewportKeyRef.current = `focus:${focusVehicleKey}`;
  }, [activeVehicle, focusVehicleKey, isUserInteracting, map, showHistoryPath]);

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

    if (!overviewKey) {
      return;
    }

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

    if (overviewMode === "company" && companyOverviewCenter) {
      const targetZoom = COMPANY_OVERVIEW_ZOOM;
      const applyCompanyOverview = () => {
        map.invalidateSize(false);
        map.setView(
          getAdjustedCenter(companyOverviewCenter.lat, companyOverviewCenter.lon),
          targetZoom,
          { animate: false },
        );
      };

      applyCompanyOverview();
      window.requestAnimationFrame(applyCompanyOverview);
      viewportKeyRef.current = overviewViewportKey;
      return;
    }

    const vehiclesForOverview = overviewVehicleIds?.length
      ? vehicles.filter((vehicle) => overviewVehicleIds.includes(vehicle.id))
      : vehicles;

    const positions = vehiclesForOverview
      .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 safePadding = getSafeViewportPadding();
      const fitPadding = {
        paddingTopLeft: [safePadding.left, safePadding.top] as [number, number],
        paddingBottomRight: [safePadding.right, safePadding.bottom] as [number, number],
      };
      map.fitBounds(positions, fitPadding);
      const adjustedZoom = overviewMode === "warsaw"
        ? Math.max(map.getZoom(), MAZOWIECKIE_MIN_OVERVIEW_ZOOM)
        : map.getZoom();
      if (adjustedZoom !== map.getZoom()) {
        map.setZoom(adjustedZoom, { animate: true });
      }
      viewportKeyRef.current = overviewViewportKey;
      return;
    }

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

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

    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}:${historyFocusKey ?? ""}`
      : `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, historyFocusKey, isBottomPanelExpanded, isUserInteracting, map, overviewKey, playbackTimestamp, showHistoryPath]);

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

    if (overviewKey || showHistoryPath) {
      liveFollowKeyRef.current = null;
      liveLastPanAtRef.current = 0;
      return;
    }

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

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

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

    const containerPoint = map.latLngToContainerPoint([point.lat, point.lon]);
    const mapSize = map.getSize();
    const safePadding = getSafeViewportPadding();
    const isInsideSafeViewport = containerPoint.x >= safePadding.left
      && containerPoint.x <= mapSize.x - safePadding.right
      && containerPoint.y >= safePadding.top
      && containerPoint.y <= mapSize.y - safePadding.bottom;

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

    const now = Date.now();
    if (now - liveLastPanAtRef.current < 500) {
      return;
    }

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

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

    if (!showHistoryPath) {
      historyFollowKeyRef.current = null;
      historyLastPanAtRef.current = 0;
      return;
    }

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

    if (!focusPoint) {
      historyFollowKeyRef.current = null;
      return;
    }

    const followKey = [
      activeVehicle?.id ?? "history",
      playbackTimestamp ?? getPointTimestamp(focusPoint) ?? "",
      focusPoint.lat.toFixed(6),
      focusPoint.lon.toFixed(6),
    ].join(":");

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

    const containerPoint = map.latLngToContainerPoint([focusPoint.lat, focusPoint.lon]);
    const mapSize = map.getSize();
    const safePadding = getSafeViewportPadding();
    const isInsideSafeViewport = containerPoint.x >= safePadding.left
      && containerPoint.x <= mapSize.x - safePadding.right
      && containerPoint.y >= safePadding.top
      && containerPoint.y <= mapSize.y - safePadding.bottom;

    if (isInsideSafeViewport) {
      historyFollowKeyRef.current = followKey;
      return;
    }

    const now = Date.now();
    if (now - historyLastPanAtRef.current < 500) {
      return;
    }

    map.panTo(getAdjustedCenter(focusPoint.lat, focusPoint.lon), { animate: true });
    historyLastPanAtRef.current = now;
    historyFollowKeyRef.current = followKey;
  }, [activeVehicle, history, isBottomPanelExpanded, isUserInteracting, map, playbackTimestamp, 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;
};

const ViewportReporter = ({
  onViewportChange,
  onViewStateChange,
  onInteractionChange,
}: {
  onViewportChange?: (bounds: { south: number; west: number; north: number; east: number }) => void;
  onViewStateChange?: (state: { zoom: number }) => void;
  onInteractionChange?: (isInteracting: boolean) => void;
}) => {
  const interactionTimeoutRef = useRef<number | null>(null);

  const markInteractionIdle = () => {
    if (interactionTimeoutRef.current != null) {
      window.clearTimeout(interactionTimeoutRef.current);
    }

    interactionTimeoutRef.current = window.setTimeout(() => {
      onInteractionChange?.(false);
      interactionTimeoutRef.current = null;
    }, 220);
  };

  const map = useMapEvents({
    movestart: () => {
      onInteractionChange?.(true);
    },
    zoomstart: () => {
      onInteractionChange?.(true);
    },
    moveend: () => {
      const bounds = map.getBounds();
      onViewportChange?.({
        south: bounds.getSouth(),
        west: bounds.getWest(),
        north: bounds.getNorth(),
        east: bounds.getEast(),
      });
      onViewStateChange?.({ zoom: map.getZoom() });
      markInteractionIdle();
    },
    zoomend: () => {
      const bounds = map.getBounds();
      onViewportChange?.({
        south: bounds.getSouth(),
        west: bounds.getWest(),
        north: bounds.getNorth(),
        east: bounds.getEast(),
      });
      onViewStateChange?.({ zoom: map.getZoom() });
      markInteractionIdle();
    },
  });

  useEffect(() => {
    const bounds = map.getBounds();
    onViewportChange?.({
      south: bounds.getSouth(),
      west: bounds.getWest(),
      north: bounds.getNorth(),
      east: bounds.getEast(),
    });
    onViewStateChange?.({ zoom: map.getZoom() });
  }, [map, onViewportChange, onViewStateChange]);

  useEffect(() => () => {
    if (interactionTimeoutRef.current != null) {
      window.clearTimeout(interactionTimeoutRef.current);
    }
  }, []);

  return null;
};

function MapViewInner({
  vehicles,
  activeVehicleId,
  focusVehicleKey,
  historyFocusKey,
  isBottomPanelExpanded,
  closePopupKey,
  history,
  playbackTimestamp,
  playbackDirection,
  showHistoryPath,
  overviewKey,
  overviewMode,
  overviewVehicleIds,
  companyOverviewCenter,
  tileMode,
  popupAddress,
  companyDistanceKm,
  companyDurationMinutes,
  onTileModeChange,
  onViewportChange,
  onVehicleSelect,
  onInspectionNoticeClick,
}: {
  vehicles: VehicleSummary[];
  activeVehicleId?: string | null;
  focusVehicleKey?: string | null;
  historyFocusKey?: string | null;
  isBottomPanelExpanded?: boolean;
  closePopupKey?: string | null;
  history: HistoryPoint[];
  playbackTimestamp?: number | null;
  playbackDirection: "forward" | "backward";
  showHistoryPath: boolean;
  overviewKey?: string | null;
  overviewMode?: "all" | "warsaw" | "company" | null;
  overviewVehicleIds?: string[] | null;
  companyOverviewCenter?: { lat: number; lon: number } | null;
  tileMode: "standard" | "satellite";
  popupAddress?: string | null;
  companyDistanceKm?: number | null;
  companyDurationMinutes?: number | null;
  onTileModeChange?: (nextMode: "standard" | "satellite") => void;
  onViewportChange?: (bounds: { south: number; west: number; north: number; east: number }) => void;
  onVehicleSelect?: (vehicleId: string) => void;
  onInspectionNoticeClick?: (vehicleId: string) => void;
}) {
  const activeVehicle = useMemo(
    () => vehicles.find((vehicle) => vehicle.id === activeVehicleId) ?? null,
    [activeVehicleId, vehicles],
  );
  const markerRefs = useRef<Record<string, LeafletMarker | null>>({});
  const [openPopupVehicleId, setOpenPopupVehicleId] = useState<string | null>(null);
  const [popupOpenRequestKey, setPopupOpenRequestKey] = useState(0);
  const [currentZoom, setCurrentZoom] = useState(6);
  const [isUserInteracting, setIsUserInteracting] = useState(false);
  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 = useMemo(
    () => (showHistoryPath ? getRenderableHistoryPath(history) : []),
    [history, showHistoryPath],
  );
  const completedHistory = useMemo(
    () => (playbackPoint
      ? [
          ...visibleHistory.filter((point) => {
            const pointTimestamp = new Date(point.deviceTime ?? point.serverTime).getTime();
            return !Number.isNaN(pointTimestamp) && playbackTimestamp != null && pointTimestamp <= playbackTimestamp;
          }),
          playbackPoint,
        ]
      : []),
    [playbackPoint, playbackTimestamp, visibleHistory],
  );
  const upcomingHistory = useMemo(
    () => (playbackPoint
      ? [
          playbackPoint,
          ...visibleHistory.filter((point) => {
            const pointTimestamp = new Date(point.deviceTime ?? point.serverTime).getTime();
            return !Number.isNaN(pointTimestamp) && playbackTimestamp != null && pointTimestamp >= playbackTimestamp;
          }),
        ]
      : visibleHistory),
    [playbackPoint, playbackTimestamp, visibleHistory],
  );
  const selectionKey = closePopupKey ?? "popup-idle";
  const shouldSpreadDenseMarkers = !showHistoryPath && currentZoom >= 18;

  const markerRenderData = useMemo(() => {
    const rawMarkers = vehicles
      .map((vehicle) => {
        const point = vehicle.id === activeVehicleId && showHistoryPath && playbackPoint
          ? playbackPoint
          : vehicle.lastPosition;

        if (!point) {
          return null;
        }

        return {
          vehicle,
          point,
          markerLat: point.lat,
          markerLon: point.lon,
          markerHeading: point.heading ?? 0,
        };
      })
      .filter((entry): entry is {
        vehicle: VehicleSummary;
        point: NonNullable<VehicleSummary["lastPosition"]> | HistoryPoint;
        markerLat: number;
        markerLon: number;
        markerHeading: number;
      } => entry != null);

    if (!shouldSpreadDenseMarkers || rawMarkers.length < 2) {
      return rawMarkers;
    }

    const visited = new Set<number>();
    const clusters: typeof rawMarkers[] = [];

    for (let startIndex = 0; startIndex < rawMarkers.length; startIndex += 1) {
      if (visited.has(startIndex)) {
        continue;
      }

      const clusterIndexes: number[] = [];
      const queue = [startIndex];
      visited.add(startIndex);

      while (queue.length > 0) {
        const currentIndex = queue.shift();
        if (currentIndex == null) {
          continue;
        }

        clusterIndexes.push(currentIndex);
        const currentMarker = rawMarkers[currentIndex];

        for (let candidateIndex = 0; candidateIndex < rawMarkers.length; candidateIndex += 1) {
          if (visited.has(candidateIndex)) {
            continue;
          }

          const candidate = rawMarkers[candidateIndex];
          if (distanceMeters(currentMarker.point, candidate.point) <= 50) {
            visited.add(candidateIndex);
            queue.push(candidateIndex);
          }
        }
      }

      clusters.push(clusterIndexes.map((index) => rawMarkers[index]));
    }

    return clusters.flatMap((cluster) => {
      if (cluster.length < 2) {
        return cluster;
      }

      const orderedCluster = [...cluster].sort((left, right) => {
        const leftWeight = getDenseMarkerOrderWeight(left.vehicle.name);
        const rightWeight = getDenseMarkerOrderWeight(right.vehicle.name);

        if (leftWeight !== rightWeight) {
          return leftWeight - rightWeight;
        }

        return left.vehicle.name.localeCompare(right.vehicle.name, "pl", {
          numeric: true,
          sensitivity: "base",
        });
      });

      const centerLat = orderedCluster.reduce((sum, item) => sum + item.point.lat, 0) / orderedCluster.length;
      const centerLon = orderedCluster.reduce((sum, item) => sum + item.point.lon, 0) / orderedCluster.length;
      const horizontalSpacingMeters = 9.4;
      const verticalSpacingMeters = 26.75;
      const columns = Math.min(5, orderedCluster.length);

      return orderedCluster.map((item, index) => {
        const columnIndex = index % columns;
        const rowIndex = Math.floor(index / columns);
        const eastOffset = (columnIndex - (columns - 1) / 2) * horizontalSpacingMeters;
        const northOffset = rowIndex * verticalSpacingMeters;
        const offset = offsetPointMeters(centerLat, centerLon, eastOffset, northOffset);

        return {
          ...item,
          markerLat: offset.lat,
          markerLon: offset.lon,
          markerHeading: 0,
        };
      });
    });
  }, [activeVehicleId, currentZoom, playbackPoint, shouldSpreadDenseMarkers, showHistoryPath, vehicles]);

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

    const frameId = window.requestAnimationFrame(() => {
      markerRefs.current[openPopupVehicleId]?.openPopup();
    });

    return () => window.cancelAnimationFrame(frameId);
  }, [activeVehicleId, openPopupVehicleId, playbackTimestamp, popupOpenRequestKey, showHistoryPath, vehicles]);

  return (
    <div className="brand-map-canvas relative h-full w-full rounded-[1.75rem]">
      <MapContainer
        center={center}
        zoom={6}
        minZoom={4}
        maxZoom={18}
        zoomSnap={1}
        zoomDelta={1}
        wheelPxPerZoomLevel={60}
        wheelDebounceTime={40}
        touchZoom="center"
        doubleClickZoom
        bounceAtZoomLimits={false}
        scrollWheelZoom
        zoomControl={false}
        className="h-full w-full rounded-[1.75rem]"
      >
        <ViewportReporter
          onViewportChange={onViewportChange}
          onViewStateChange={(state) => setCurrentZoom(state.zoom)}
          onInteractionChange={setIsUserInteracting}
        />
        <ClosePopupOnSelectionChange selectionKey={selectionKey} />
        <TileLayer
          attribution={tileMode === "satellite" ? SATELLITE_TILE_ATTRIBUTION : TILE_ATTRIBUTION}
          url={tileMode === "satellite" ? SATELLITE_TILE_URL : TILE_URL}
          maxNativeZoom={18}
        />
        <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>
        {markerRenderData.map(({ vehicle, point, markerLat, markerLon, markerHeading }) => {

        const stopInfo = getVehicleStopInfo(
          point,
          vehicle.id === activeVehicleId ? history : [],
        );
        const isHistoricalPopup = vehicle.id === activeVehicleId && showHistoryPath;
        const popupIgnitionOn = isHistoricalPopup
          ? point.ignition === true || (point.speed ?? 0) > 0
          : vehicle.deviceState?.ignition === true || point.ignition === true || (point.speed ?? 0) > 0;

        const color = getVehicleColorHex(vehicle.colorKey);
        const inspectionVisualState = getInspectionVisualState(vehicle.inspectionStatus, vehicle.inspectionDueDate);

        return (
          <Marker
            key={vehicle.id}
            ref={(instance) => {
              markerRefs.current[vehicle.id] = instance;
            }}
            position={[markerLat, markerLon]}
            zIndexOffset={openPopupVehicleId === vehicle.id ? 3000 : vehicle.id === activeVehicleId ? 2000 : 0}
            icon={buildVehicleIcon(
              color,
              markerHeading ?? point.heading ?? 0,
              vehicle.id === activeVehicleId,
              vehicle.status,
              vehicle.name,
              inspectionVisualState,
            )}
            eventHandlers={{
              click: (event) => {
                setOpenPopupVehicleId(vehicle.id);
                setPopupOpenRequestKey((current) => current + 1);
                if (vehicle.id !== activeVehicleId) {
                  onVehicleSelect?.(vehicle.id);
                }
                event.target.openPopup();
              },
            }}
          >
            <Popup
              className="vehicle-status-popup"
              autoPan={false}
              autoPanPadding={[28, 28]}
              eventHandlers={{
                remove: () => {
                  setOpenPopupVehicleId((current) => current === vehicle.id ? null : current);
                },
              }}
            >
              <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>
                {inspectionVisualState === "missing" ? (
                  onInspectionNoticeClick ? (
                    <button
                      type="button"
                      onClick={() => onInspectionNoticeClick(vehicle.id)}
                      className="vehicle-status-card__inspection-alert transition hover:scale-[1.02] hover:border-coral/60 hover:bg-coral/20"
                    >
                      WPISZ TERMIN PRZEGLĄDU
                    </button>
                  ) : (
                    <div className="vehicle-status-card__inspection-alert">
                      WPISZ TERMIN PRZEGLĄDU
                    </div>
                  )
                ) : null}
                {(inspectionVisualState === "due_soon" || inspectionVisualState === "overdue") && vehicle.inspectionDueDate ? (
                  <div className="vehicle-status-card__inspection-alert">
                    PRZEGLĄD {formatInspectionDueDate(vehicle.inspectionDueDate)}
                  </div>
                ) : null}
              </div>
            </Popup>
          </Marker>
        );
        })}
        <FitMap
          vehicles={vehicles}
          activeVehicle={activeVehicle}
          focusVehicleKey={focusVehicleKey}
          historyFocusKey={historyFocusKey}
          isUserInteracting={isUserInteracting}
          isBottomPanelExpanded={isBottomPanelExpanded}
          history={history}
          playbackTimestamp={playbackTimestamp}
          overviewKey={overviewKey}
          overviewMode={overviewMode}
          overviewVehicleIds={overviewVehicleIds}
          companyOverviewCenter={companyOverviewCenter}
          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>
  );
}

export const MapView = memo(MapViewInner);
