"use client";

import { memo, type CSSProperties, useCallback, 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 COMPANY_GROUP_MIN_STOP_MS = 60 * 60 * 1000;
const COMPANY_GROUP_SEED_RADIUS_METERS = 30;
const COMPANY_GROUP_JOIN_RADIUS_METERS = 30;
const DENSE_MARKER_CLUSTER_RADIUS_METERS = 50;
const vehicleIconCache = new Map<string, ReturnType<typeof divIcon>>();
const VEHICLE_ICON_CACHE_MAX_ENTRIES = 512;
const EMPTY_HISTORY: HistoryPoint[] = [];
const MDI_TIRE_ALERT_ICON_URL = "https://cdn.jsdelivr.net/npm/@mdi/svg/svg/car-tire-alert.svg";
const MDI_OIL_ICON_URL = "https://cdn.jsdelivr.net/npm/@mdi/svg/svg/oil.svg";

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 formatMileageKm = (value?: number | null) => {
  if (value == null || Number.isNaN(value)) {
    return "Brak";
  }

  return `${Math.round(value).toLocaleString("pl-PL")} 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;
};

type StampedHistoryPoint = {
  point: HistoryPoint;
  timestamp: number;
};

const stampHistoryPoints = (points: HistoryPoint[]) => points
  .map((point) => ({
    point,
    timestamp: getPointTimestamp(point),
  }))
  .filter((entry): entry is StampedHistoryPoint => entry.timestamp != null);

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

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

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

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

  let low = 0;
  let high = stampedPoints.length - 2;
  while (low <= high) {
    const index = Math.floor((low + high) / 2);
    const current = stampedPoints[index];
    const next = stampedPoints[index + 1];

    if (playbackTimestamp < current.timestamp) {
      high = index - 1;
      continue;
    }
    if (playbackTimestamp > next.timestamp) {
      low = index + 1;
      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[]) => {
  const filtered: HistoryPoint[] = [];

  for (const point of points) {
    const previousPoint = filtered[filtered.length - 1];
    if (previousPoint && distanceMeters(previousPoint, point) <= 5) {
      continue;
    }

    filtered.push(point);
  }

  return filtered;
};

const getRenderableHistoryPath = (points: HistoryPoint[]) => {
  const sortedPoints = [...points].sort((left, right) => {
    const leftTimestamp = getPointTimestamp(left) ?? 0;
    const rightTimestamp = getPointTimestamp(right) ?? 0;
    return leftTimestamp - rightTimestamp;
  });
  const filtered = filterHistoryPath(sortedPoints);
  if (filtered.length > 1 || points.length <= 1) {
    return filtered;
  }

  return sortedPoints;
};

const MAX_HISTORY_SEGMENT_GAP_METERS = 1500;
const MAX_HISTORY_SEGMENT_SPEED_KMH = 200;

const splitRenderableHistoryPath = (points: HistoryPoint[]) => {
  if (points.length < 2) {
    return points.length === 0 ? [] : [points];
  }

  const segments: HistoryPoint[][] = [];
  let currentSegment: HistoryPoint[] = [points[0]];

  for (let index = 1; index < points.length; index += 1) {
    const previousPoint = points[index - 1];
    const currentPoint = points[index];
    const previousTimestamp = getPointTimestamp(previousPoint);
    const currentTimestamp = getPointTimestamp(currentPoint);
    const gapMeters = distanceMeters(previousPoint, currentPoint);
    const deltaSeconds =
      previousTimestamp != null && currentTimestamp != null
        ? Math.max(0, (currentTimestamp - previousTimestamp) / 1000)
        : 0;
    const inferredSpeedKmh =
      deltaSeconds > 0
        ? (gapMeters / deltaSeconds) * 3.6
        : Number.POSITIVE_INFINITY;

    const shouldBreakSegment =
      gapMeters > MAX_HISTORY_SEGMENT_GAP_METERS
      || inferredSpeedKmh > MAX_HISTORY_SEGMENT_SPEED_KMH;

    if (shouldBreakSegment) {
      if (currentSegment.length > 1) {
        segments.push(currentSegment);
      }
      currentSegment = [currentPoint];
      continue;
    }

    currentSegment.push(currentPoint);
  }

  if (currentSegment.length > 1) {
    segments.push(currentSegment);
  }

  return segments;
};

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 getDateVisualState = (
  status?: VehicleSummary["inspectionStatus"],
  dueDate?: string | null,
): InspectionVisualState => {
  const normalizedInspectionDate = normalizeInspectionDate(dueDate);
  if (!normalizedInspectionDate) {
    return status === "missing" ? "missing" : "missing";
  }

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

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

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

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

  return "ok";
};

const getInspectionVisualState = (vehicle: VehicleSummary): InspectionVisualState => {
  const serviceStates: InspectionVisualState[] = [
    getDateVisualState(vehicle.inspectionStatus, vehicle.inspectionDueDate),
    getDateVisualState(vehicle.oilChangeStatus, vehicle.oilChangeDueDate),
    !normalizeInspectionDate(vehicle.tireChangedAt) || !normalizeInspectionDate(vehicle.nextTireChangeDueDate)
      ? "missing"
      : getDateVisualState(vehicle.tireChangeStatus, vehicle.nextTireChangeDueDate),
  ];

  if (serviceStates.includes("overdue")) {
    return "overdue";
  }
  if (serviceStates.includes("missing")) {
    return "missing";
  }
  if (serviceStates.includes("due_soon")) {
    return "due_soon";
  }
  return "ok";
};

const buildServiceNoticeLabels = (vehicle: VehicleSummary) => {
  const notices: string[] = [];

  const inspectionState = getDateVisualState(vehicle.inspectionStatus, vehicle.inspectionDueDate);
  if (inspectionState === "missing") {
    notices.push("WPISZ TERMIN PRZEGLĄDU");
  } else if ((inspectionState === "due_soon" || inspectionState === "overdue") && vehicle.inspectionDueDate) {
    notices.push(`PRZEGLĄD ${formatInspectionDueDate(vehicle.inspectionDueDate)}`);
  }

  const oilState = getDateVisualState(vehicle.oilChangeStatus, vehicle.oilChangeDueDate);
  if (oilState === "missing") {
    notices.push("WPISZ TERMIN WYMIANY OLEJU");
  } else if ((oilState === "due_soon" || oilState === "overdue") && vehicle.oilChangeDueDate) {
    notices.push(`OLEJ ${formatInspectionDueDate(vehicle.oilChangeDueDate)}`);
  }

  const tireState = !normalizeInspectionDate(vehicle.tireChangedAt) || !normalizeInspectionDate(vehicle.nextTireChangeDueDate)
    ? "missing"
    : getDateVisualState(vehicle.tireChangeStatus, vehicle.nextTireChangeDueDate);
  if (tireState === "missing") {
    notices.push("WPISZ DATY WYMIANY OPON");
  } else if ((tireState === "due_soon" || tireState === "overdue") && vehicle.nextTireChangeDueDate) {
    notices.push(`OPONY ${formatInspectionDueDate(vehicle.nextTireChangeDueDate)}`);
  }

  return notices;
};

const getOilMarkerAlertState = (vehicle: VehicleSummary) => {
  const oilState = getDateVisualState(vehicle.oilChangeStatus, vehicle.oilChangeDueDate);
  return oilState === "due_soon" || oilState === "overdue";
};

const getTireMarkerAlertState = (vehicle: VehicleSummary) => {
  const hasTireChangeDate = Boolean(normalizeInspectionDate(vehicle.tireChangedAt));
  const hasNextTireChangeDate = Boolean(normalizeInspectionDate(vehicle.nextTireChangeDueDate));
  if (!hasTireChangeDate || !hasNextTireChangeDate) {
    return false;
  }

  const tireState = getDateVisualState(vehicle.tireChangeStatus, vehicle.nextTireChangeDueDate);
  return tireState === "due_soon" || tireState === "overdue";
};

const getMissingServiceAlertState = (vehicle: VehicleSummary) => {
  const inspectionState = getDateVisualState(vehicle.inspectionStatus, vehicle.inspectionDueDate);
  const oilState = getDateVisualState(vehicle.oilChangeStatus, vehicle.oilChangeDueDate);
  const hasTireChangeDate = Boolean(normalizeInspectionDate(vehicle.tireChangedAt));
  const hasNextTireChangeDate = Boolean(normalizeInspectionDate(vehicle.nextTireChangeDueDate));
  const tireState = !hasTireChangeDate || !hasNextTireChangeDate
    ? "missing"
    : getDateVisualState(vehicle.tireChangeStatus, vehicle.nextTireChangeDueDate);

  return inspectionState === "missing" || oilState === "missing" || tireState === "missing";
};

const buildVehicleIcon = (
  color: string,
  heading: number,
  active: boolean,
  status: string,
  label?: string,
  inspectionVisualState?: InspectionVisualState,
  showAlertBadge?: boolean,
  showOilIcon?: boolean,
  showTireIcon?: boolean,
  grouped?: boolean,
) => {
  const cacheKey = [
    color,
    Math.round(heading),
    active ? 1 : 0,
    status,
    label ?? "",
    inspectionVisualState ?? "ok",
    showAlertBadge ? 1 : 0,
    showOilIcon ? 1 : 0,
    showTireIcon ? 1 : 0,
    grouped ? 1 : 0,
  ].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" : ""} ${grouped ? "is-grouped" : ""} 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>' : ""}
        ${showAlertBadge ? '<span class="vehicle-marker__alert-badge" title="Brak wymaganych danych serwisowych">!</span>' : ""}
        ${showOilIcon || showTireIcon ? `
          <div class="vehicle-marker__service-icons">
            ${showOilIcon ? `
              <span class="vehicle-marker__service-icon vehicle-marker__service-icon--oil" title="Wymiana oleju">
                <img src="${MDI_OIL_ICON_URL}" alt="Wymiana oleju" />
              </span>
            ` : ""}
            ${showTireIcon ? `
              <span class="vehicle-marker__service-icon vehicle-marker__service-icon--tire" title="Brak dat wymiany opon">
                <img src="${MDI_TIRE_ALERT_ICON_URL}" alt="Brak dat wymiany opon" />
              </span>
            ` : ""}
          </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],
  });
  if (vehicleIconCache.size >= VEHICLE_ICON_CACHE_MAX_ENTRIES) {
    const oldestKey = vehicleIconCache.keys().next().value;
    if (oldestKey) {
      vehicleIconCache.delete(oldestKey);
    }
  }
  vehicleIconCache.set(cacheKey, icon);
  return icon;
};

type MarkerRenderEntry = {
  vehicle: VehicleSummary;
  point: NonNullable<VehicleSummary["lastPosition"]> | HistoryPoint;
  markerLat: number;
  markerLon: number;
  markerHeading: number;
  isGrouped: boolean;
};

const getMetersPerPixel = (lat: number, zoom: number) =>
  (156_543.03392 * Math.cos((lat * Math.PI) / 180)) / (2 ** zoom);

const getMarkerLineRotationRadians = (
  cluster: MarkerRenderEntry[],
  firstVehicleName: string,
  secondVehicleName: string,
) => {
  const first = cluster.find((entry) => entry.vehicle.name.toUpperCase() === firstVehicleName);
  const second = cluster.find((entry) => entry.vehicle.name.toUpperCase() === secondVehicleName);

  if (!first || !second) {
    return 0;
  }

  const averageLatRadians = (((first.point.lat + second.point.lat) / 2) * Math.PI) / 180;
  const eastMeters = (second.point.lon - first.point.lon) * 111_320 * Math.cos(averageLatRadians);
  const northMeters = (second.point.lat - first.point.lat) * 111_320;

  if (Math.hypot(eastMeters, northMeters) < 1) {
    return 0;
  }

  let rotationRadians = Math.atan2(northMeters, eastMeters);
  if (rotationRadians > Math.PI / 2) {
    rotationRadians -= Math.PI;
  } else if (rotationRadians < -Math.PI / 2) {
    rotationRadians += Math.PI;
  }

  return rotationRadians;
};

const arrangeMarkerGroup = (
  cluster: MarkerRenderEntry[],
  options: {
    zoom?: number;
    horizontalShiftPx?: number;
    verticalSpacingReductionPx?: number;
    rotationRadians?: number;
  } = {},
) => {
  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 sortedLats = orderedCluster.map((item) => item.point.lat).sort((left, right) => left - right);
  const sortedLons = orderedCluster.map((item) => item.point.lon).sort((left, right) => left - right);
  const middleIndex = Math.floor(orderedCluster.length / 2);
  const centerLat = orderedCluster.length % 2 === 0
    ? (sortedLats[middleIndex - 1] + sortedLats[middleIndex]) / 2
    : sortedLats[middleIndex];
  const centerLon = orderedCluster.length % 2 === 0
    ? (sortedLons[middleIndex - 1] + sortedLons[middleIndex]) / 2
    : sortedLons[middleIndex];
  const metersPerPixel = options.zoom == null ? 0 : getMetersPerPixel(centerLat, options.zoom);
  const horizontalSpacingMeters = 9.4;
  const verticalSpacingMeters = Math.max(
    0,
    20.75 - (options.verticalSpacingReductionPx ?? 0) * metersPerPixel,
  );
  const horizontalShiftMeters = (options.horizontalShiftPx ?? 0) * metersPerPixel;
  const rotationRadians = options.rotationRadians ?? 0;
  const rotationCos = Math.cos(rotationRadians);
  const rotationSin = Math.sin(rotationRadians);
  const columns = Math.min(5, orderedCluster.length);

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

    return {
      ...item,
      markerLat: offset.lat,
      markerLon: offset.lon,
      markerHeading: 0,
      isGrouped: true,
    };
  });
};

type VehicleMarkerProps = {
  entry: MarkerRenderEntry;
  isActive: boolean;
  isPopupOpen: boolean;
  isHistoricalPopup: boolean;
  popupAddress?: string | null;
  popupAddressLoading?: boolean;
  companyDistanceKm?: number | null;
  companyDurationMinutes?: number | null;
  shouldShowServiceIcons: boolean;
  historyForVehicle: HistoryPoint[];
  onMarkerRef: (vehicleId: string, instance: LeafletMarker | null) => void;
  onMarkerClick: (vehicleId: string) => void;
  onMarkerPopupRemove: (vehicleId: string) => void;
  onVehicleSelect?: (vehicleId: string, options?: { focusMap?: boolean }) => void;
  onVehiclePopupOpen?: (vehicleId: string) => void;
  onInspectionNoticeClick?: (vehicleId: string) => void;
};

const VehicleMarker = memo(({
  entry,
  isActive,
  isPopupOpen,
  isHistoricalPopup,
  popupAddress,
  popupAddressLoading,
  companyDistanceKm,
  companyDurationMinutes,
  shouldShowServiceIcons,
  historyForVehicle,
  onMarkerRef,
  onMarkerClick,
  onMarkerPopupRemove,
  onVehicleSelect,
  onVehiclePopupOpen,
  onInspectionNoticeClick,
}: VehicleMarkerProps) => {
  const { vehicle, point, markerLat, markerLon, markerHeading } = entry;
  const stopInfo = getVehicleStopInfo(
    point,
    historyForVehicle,
  );
  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);
  const serviceNoticeLabels = buildServiceNoticeLabels(vehicle);
  const showAlertBadge = getMissingServiceAlertState(vehicle);
  const showOilIcon = shouldShowServiceIcons && getOilMarkerAlertState(vehicle);
  const showTireIcon = shouldShowServiceIcons && getTireMarkerAlertState(vehicle);

  return (
    <Marker
      ref={(instance) => {
        onMarkerRef(vehicle.id, instance);
      }}
      position={[markerLat, markerLon]}
      zIndexOffset={isPopupOpen ? 3000 : isActive ? 2000 : 0}
      icon={buildVehicleIcon(
        color,
        markerHeading ?? point.heading ?? 0,
        isActive,
        vehicle.status,
        vehicle.name,
        inspectionVisualState,
        showAlertBadge,
        showOilIcon,
        showTireIcon,
        entry.isGrouped,
      )}
      eventHandlers={{
        click: (event) => {
          onMarkerClick(vehicle.id);
          onVehiclePopupOpen?.(vehicle.id);
          if (!isActive) {
            onVehicleSelect?.(vehicle.id, { focusMap: false });
          }
          event.target.openPopup();
        },
      }}
    >
      <Popup
        className="vehicle-status-popup"
        autoPan={false}
        autoPanPadding={[28, 28]}
        eventHandlers={{
          remove: () => {
            onMarkerPopupRemove(vehicle.id);
          },
        }}
      >
        <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">
              {isActive
                ? (popupAddressLoading ? "Ładowanie adresu..." : (popupAddress ?? "Brak 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]">
              {isActive ? (
                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>
          {serviceNoticeLabels.map((label) => (
            onInspectionNoticeClick && label.startsWith("WPISZ") ? (
              <button
                key={label}
                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"
              >
                {label}
              </button>
            ) : (
              <div key={label} className="vehicle-status-card__inspection-alert">
                {label}
              </div>
            )
          ))}
        </div>
      </Popup>
    </Marker>
  );
}, (previousProps, nextProps) => {
  const previousEntry = previousProps.entry;
  const nextEntry = nextProps.entry;
  const previousVehicle = previousEntry.vehicle;
  const nextVehicle = nextEntry.vehicle;
  const previousPoint = previousEntry.point;
  const nextPoint = nextEntry.point;

  return previousVehicle.id === nextVehicle.id
    && previousVehicle.name === nextVehicle.name
    && previousVehicle.plateNumber === nextVehicle.plateNumber
    && previousVehicle.colorKey === nextVehicle.colorKey
    && previousVehicle.status === nextVehicle.status
    && previousVehicle.inspectionDueDate === nextVehicle.inspectionDueDate
    && previousVehicle.oilChangeDueDate === nextVehicle.oilChangeDueDate
    && previousVehicle.oilChangeOdometer === nextVehicle.oilChangeOdometer
    && previousVehicle.oilChangeIntervalKm === nextVehicle.oilChangeIntervalKm
    && previousVehicle.tireChangedAt === nextVehicle.tireChangedAt
    && previousVehicle.nextTireChangeDueDate === nextVehicle.nextTireChangeDueDate
    && previousEntry.markerLat === nextEntry.markerLat
    && previousEntry.markerLon === nextEntry.markerLon
    && previousEntry.markerHeading === nextEntry.markerHeading
    && previousPoint.lat === nextPoint.lat
    && previousPoint.lon === nextPoint.lon
    && previousPoint.speed === nextPoint.speed
    && previousPoint.heading === nextPoint.heading
    && previousPoint.ignition === nextPoint.ignition
    && previousPoint.battery === nextPoint.battery
    && previousPoint.satelliteCount === nextPoint.satelliteCount
    && previousPoint.deviceTime === nextPoint.deviceTime
    && previousPoint.serverTime === nextPoint.serverTime
    && previousProps.isActive === nextProps.isActive
    && previousProps.isPopupOpen === nextProps.isPopupOpen
    && previousProps.isHistoricalPopup === nextProps.isHistoricalPopup
    && previousProps.popupAddress === nextProps.popupAddress
    && previousProps.popupAddressLoading === nextProps.popupAddressLoading
    && previousProps.companyDistanceKm === nextProps.companyDistanceKm
    && previousProps.companyDurationMinutes === nextProps.companyDurationMinutes
    && previousProps.shouldShowServiceIcons === nextProps.shouldShowServiceIcons
    && previousProps.historyForVehicle === nextProps.historyForVehicle;
});

const FitMap = ({
  vehicles,
  activeVehicle,
  focusVehicleKey,
  historyFocusKey,
  suppressVehicleAutoCenter,
  isUserInteracting,
  isBottomPanelExpanded,
  history,
  playbackTimestamp,
  overviewKey,
  overviewMode,
  overviewVehicleIds,
  companyOverviewCenter,
  showHistoryPath,
}: {
  vehicles: VehicleSummary[];
  activeVehicle?: VehicleSummary | null;
  focusVehicleKey?: string | null;
  historyFocusKey?: string | null;
  suppressVehicleAutoCenter?: { vehicleId: string | null; until: number };
  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 stampedHistory = useMemo(() => stampHistoryPoints(history), [history]);
  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 isAutoCenterSuppressed = (vehicleId?: string | null) =>
    vehicleId != null
    && suppressVehicleAutoCenter?.vehicleId === vehicleId
    && Date.now() < suppressVehicleAutoCenter.until;

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

    const fallbackTop = clamp(Math.round(mapSize.y * 0.15), 96, 150);
    const fallbackBottom = isBottomPanelExpanded
      ? clamp(Math.round(mapSize.y * 0.35), 220, 340)
      : clamp(Math.round(mapSize.y * 0.18), 110, 170);
    const mapRect = map.getContainer().getBoundingClientRect();
    const topOverlayRect = document.querySelector<HTMLElement>("[data-map-top-overlay]")?.getBoundingClientRect();
    const bottomOverlayRect = document.querySelector<HTMLElement>("[data-map-bottom-overlay]")?.getBoundingClientRect();
    const measuredTop = topOverlayRect
      ? Math.round(topOverlayRect.bottom - mapRect.top + 12)
      : fallbackTop;
    const measuredBottom = bottomOverlayRect
      ? Math.round(mapRect.bottom - bottomOverlayRect.top + 12)
      : fallbackBottom;

    return {
      top: clamp(measuredTop, 72, Math.round(mapSize.y * 0.46)),
      left: clamp(Math.round(mapSize.x * 0.08), 28, 52),
      bottom: clamp(measuredBottom, 72, Math.round(mapSize.y * 0.62)),
      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.right - safePadding.left) / 2;
    const offsetY = (safePadding.bottom - safePadding.top) / 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;
    }

    if (isAutoCenterSuppressed(activeVehicle.id)) {
      focusKeyRef.current = focusVehicleKey;
      viewportKeyRef.current = `focus:${focusVehicleKey}`;
      return;
    }

    if (isAutoCenterSuppressed(activeVehicle.id)) {
      focusKeyRef.current = focusVehicleKey;
      viewportKeyRef.current = `focus:${focusVehicleKey}`;
      return;
    }

    const point = activeVehicle.lastPosition;
    const targetZoom = 18;
    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(stampedHistory, 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;
    }

    if (activeVehicle && isAutoCenterSuppressed(activeVehicle.id)) {
      viewportKeyRef.current = historyKey;
      return;
    }

    if (activeVehicle && isAutoCenterSuppressed(activeVehicle.id)) {
      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;
    }

    if (isAutoCenterSuppressed(activeVehicle.id)) {
      liveFollowKeyRef.current = [
        activeVehicle.id,
        point.serverTime ?? point.deviceTime ?? "",
        point.lat.toFixed(6),
        point.lon.toFixed(6),
      ].join(":");
      return;
    }

    if (isAutoCenterSuppressed(activeVehicle.id)) {
      liveFollowKeyRef.current = [
        activeVehicle.id,
        point.serverTime ?? point.deviceTime ?? "",
        point.lat.toFixed(6),
        point.lon.toFixed(6),
      ].join(":");
      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(stampedHistory, 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 desiredX = (safePadding.left + mapSize.x - safePadding.right) / 2;
    const desiredY = (safePadding.top + mapSize.y - safePadding.bottom) / 2;
    const isNearSafeViewportCenter = Math.abs(containerPoint.x - desiredX) <= 18
      && Math.abs(containerPoint.y - desiredY) <= 18;

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

    const now = Date.now();
    if (now - historyLastPanAtRef.current < 300) {
      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,
  animatedVehiclePosition,
  activeVehicleId,
  focusVehicleKey,
  suppressVehicleAutoCenter,
  historyFocusKey,
  isBottomPanelExpanded,
  closePopupKey,
  history,
  playbackTimestamp,
  playbackDirection,
  showHistoryPath,
  overviewKey,
  overviewMode,
  overviewVehicleIds,
  companyCenter,
  companyOverviewCenter,
  tileMode,
  popupAddress,
  popupAddressLoading,
  companyDistanceKm,
  companyDurationMinutes,
  onTileModeChange,
  onViewportChange,
  onVehicleSelect,
  onVehiclePopupOpen,
  onVehiclePopupClose,
  onInspectionNoticeClick,
}: {
  vehicles: VehicleSummary[];
  animatedVehiclePosition?: PositionSnapshot | null;
  activeVehicleId?: string | null;
  focusVehicleKey?: string | null;
  suppressVehicleAutoCenter?: { vehicleId: string | null; until: number };
  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;
  companyCenter?: { lat: number; lon: number } | null;
  companyOverviewCenter?: { lat: number; lon: number } | null;
  tileMode: "standard" | "satellite";
  popupAddress?: string | null;
  popupAddressLoading?: boolean;
  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, options?: { focusMap?: boolean }) => void;
  onVehiclePopupOpen?: (vehicleId: string) => void;
  onVehiclePopupClose?: (vehicleId: string) => void;
  onInspectionNoticeClick?: (vehicleId: string) => void;
}) {
  const activeVehicle = useMemo(
    () => vehicles.find((candidate) => candidate.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 handleViewStateChange = useCallback((state: { zoom: number }) => {
    setCurrentZoom((current) => current === state.zoom ? current : state.zoom);
  }, []);
  const suppressAutoCenterRef = useRef<{ vehicleId: string | null; until: number }>({
    vehicleId: null,
    until: 0,
  });
  const isAutoCenterSuppressed = (vehicleId?: string | null) =>
    vehicleId != null
    && suppressAutoCenterRef.current.vehicleId === vehicleId
    && Date.now() < suppressAutoCenterRef.current.until;
  const stampedHistory = useMemo(() => stampHistoryPoints(history), [history]);
  const playbackPoint = stampedHistory.length > 0
    ? getPlaybackPoint(stampedHistory, 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 stampedVisibleHistory = useMemo(() => stampHistoryPoints(visibleHistory), [visibleHistory]);
  const visibleHistorySplit = useMemo(() => {
    if (playbackTimestamp == null || stampedVisibleHistory.length === 0) {
      return { completedEnd: 0, upcomingStart: 0 };
    }

    let low = 0;
    let high = stampedVisibleHistory.length;
    while (low < high) {
      const middle = Math.floor((low + high) / 2);
      if (stampedVisibleHistory[middle].timestamp <= playbackTimestamp) {
        low = middle + 1;
      } else {
        high = middle;
      }
    }
    const completedEnd = low;

    low = 0;
    high = stampedVisibleHistory.length;
    while (low < high) {
      const middle = Math.floor((low + high) / 2);
      if (stampedVisibleHistory[middle].timestamp < playbackTimestamp) {
        low = middle + 1;
      } else {
        high = middle;
      }
    }

    return { completedEnd, upcomingStart: low };
  }, [playbackTimestamp, stampedVisibleHistory]);
  const completedHistory = useMemo(
    () => (playbackPoint
      ? [
          ...stampedVisibleHistory.slice(0, visibleHistorySplit.completedEnd).map((entry) => entry.point),
          playbackPoint,
        ]
      : []),
    [playbackPoint, stampedVisibleHistory, visibleHistorySplit.completedEnd],
  );
  const completedHistorySegments = useMemo(
    () => splitRenderableHistoryPath(completedHistory),
    [completedHistory],
  );
  const upcomingHistory = useMemo(
    () => (playbackPoint
      ? [
          playbackPoint,
          ...stampedVisibleHistory.slice(visibleHistorySplit.upcomingStart).map((entry) => entry.point),
        ]
      : visibleHistory),
    [playbackPoint, stampedVisibleHistory, visibleHistory, visibleHistorySplit.upcomingStart],
  );
  const upcomingHistorySegments = useMemo(
    () => splitRenderableHistoryPath(upcomingHistory),
    [upcomingHistory],
  );
  const selectionKey = closePopupKey ?? "popup-idle";
  const shouldSpreadDenseMarkers = !showHistoryPath && currentZoom >= 18;
  const shouldShowServiceIcons = 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,
          isGrouped: false,
        };
      })
      .filter((entry): entry is MarkerRenderEntry => entry != null);

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

    const companyGroupIds = new Set<string>();
    if (companyCenter) {
      const ignitionOffMarkers = rawMarkers.filter((entry) =>
        (entry.vehicle.deviceState?.ignition ?? entry.point.ignition) === false,
      );
      const companyQueue = ignitionOffMarkers.filter((entry) =>
        distanceMeters(entry.point, companyCenter) <= COMPANY_GROUP_SEED_RADIUS_METERS,
      );

      for (const entry of companyQueue) {
        companyGroupIds.add(entry.vehicle.id);
      }

      for (let queueIndex = 0; queueIndex < companyQueue.length; queueIndex += 1) {
        const current = companyQueue[queueIndex];

        for (const candidate of ignitionOffMarkers) {
          if (companyGroupIds.has(candidate.vehicle.id)) {
            continue;
          }

          const stoppedAt = getPointTimestamp(candidate.point);
          const isStoppedLongEnough = stoppedAt != null
            && Date.now() - stoppedAt >= COMPANY_GROUP_MIN_STOP_MS;

          if (
            isStoppedLongEnough
            && distanceMeters(current.point, candidate.point) <= COMPANY_GROUP_JOIN_RADIUS_METERS
          ) {
            companyGroupIds.add(candidate.vehicle.id);
            companyQueue.push(candidate);
          }
        }
      }
    }

    const companyGroup = rawMarkers.filter((entry) => companyGroupIds.has(entry.vehicle.id));
    const remainingMarkers = rawMarkers.filter((entry) => !companyGroupIds.has(entry.vehicle.id));
    const visited = new Set<number>();
    const clusters: typeof rawMarkers[] = [];

    for (let startIndex = 0; startIndex < remainingMarkers.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 = remainingMarkers[currentIndex];

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

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

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

    const arrangedCompanyGroup = companyGroup.length >= 2
      ? arrangeMarkerGroup(companyGroup, {
          zoom: currentZoom,
          horizontalShiftPx: -40,
          verticalSpacingReductionPx: 3,
          rotationRadians: getMarkerLineRotationRadians(companyGroup, "MK", "NTBK"),
        })
      : companyGroup;
    const arrangedRemainingMarkers = clusters.flatMap((cluster) => {
      if (cluster.length < 2) {
        return cluster;
      }

      return arrangeMarkerGroup(cluster);
    });

    return [...arrangedCompanyGroup, ...arrangedRemainingMarkers];
  }, [activeVehicleId, companyCenter, currentZoom, playbackPoint, vehicles, shouldSpreadDenseMarkers, showHistoryPath]);

  const handleMarkerRef = useCallback((vehicleId: string, instance: LeafletMarker | null) => {
    markerRefs.current[vehicleId] = instance;
  }, []);

  const handleMarkerClick = useCallback((vehicleId: string) => {
    suppressAutoCenterRef.current = {
      vehicleId,
      until: Date.now() + 1500,
    };
    setOpenPopupVehicleId(vehicleId);
    setPopupOpenRequestKey((current) => current + 1);
  }, []);

  const handleMarkerPopupRemove = useCallback((vehicleId: string) => {
    setOpenPopupVehicleId((current) => current === vehicleId ? null : current);
    onVehiclePopupClose?.(vehicleId);
  }, [onVehiclePopupClose]);

  useEffect(() => {
    if (!activeVehicleId || !animatedVehiclePosition || showHistoryPath) {
      return;
    }

    const marker = markerRefs.current[activeVehicleId];
    if (!marker) {
      return;
    }

    const activeMarkerEntry = markerRenderData.find((entry) => entry.vehicle.id === activeVehicleId);
    if (activeMarkerEntry?.isGrouped) {
      marker.setLatLng([activeMarkerEntry.markerLat, activeMarkerEntry.markerLon]);
      return;
    }

    marker.setLatLng([animatedVehiclePosition.lat, animatedVehiclePosition.lon]);
  }, [activeVehicleId, animatedVehiclePosition, markerRenderData, showHistoryPath]);

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

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

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

  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={handleViewStateChange}
          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 ? (
          <>
            {upcomingHistorySegments.map((segment, index) => (
              <Polyline
                key={`history-upcoming-${index}-${segment[0]?.id ?? "start"}`}
                positions={segment.map((point) => [point.lat, point.lon])}
                pathOptions={{ color: activeVehicleColor, weight: 5, opacity: 0.72, fill: false, lineCap: "round", lineJoin: "round" }}
              />
            ))}
            {completedHistorySegments.map((segment, index) => (
              <Polyline
                key={`history-completed-${index}-${segment[0]?.id ?? "start"}`}
                positions={segment.map((point) => [point.lat, point.lon])}
                pathOptions={{ color: "#8ea2b7", weight: 4, opacity: 0.28, fill: false, lineCap: "round", lineJoin: "round" }}
              />
            ))}
          </>
        ) : null}
        </Pane>
        {markerRenderData.map((entry) => (
          <VehicleMarker
            key={entry.vehicle.id}
            entry={entry}
            isActive={entry.vehicle.id === activeVehicleId}
            isPopupOpen={openPopupVehicleId === entry.vehicle.id}
            isHistoricalPopup={entry.vehicle.id === activeVehicleId && showHistoryPath}
            popupAddress={entry.vehicle.id === activeVehicleId ? popupAddress : null}
            popupAddressLoading={entry.vehicle.id === activeVehicleId ? popupAddressLoading : false}
            companyDistanceKm={entry.vehicle.id === activeVehicleId ? companyDistanceKm : null}
            companyDurationMinutes={entry.vehicle.id === activeVehicleId ? companyDurationMinutes : null}
            shouldShowServiceIcons={shouldShowServiceIcons}
            historyForVehicle={entry.vehicle.id === activeVehicleId ? history : EMPTY_HISTORY}
            onMarkerRef={handleMarkerRef}
            onMarkerClick={handleMarkerClick}
            onMarkerPopupRemove={handleMarkerPopupRemove}
            onVehicleSelect={onVehicleSelect}
            onVehiclePopupOpen={onVehiclePopupOpen}
            onInspectionNoticeClick={onInspectionNoticeClick}
          />
        ))}
        <FitMap
          vehicles={vehicles}
          activeVehicle={activeVehicle}
          focusVehicleKey={focusVehicleKey}
          suppressVehicleAutoCenter={suppressVehicleAutoCenter}
          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);
