import { useEffect, useState, useRef, useCallback } from "react";
import { useTranslation } from "react-i18next";
import { IconButton } from "@trails-cool/ui";
import type { DayStage } from "@trails-cool/gpx";
import type { YjsState } from "~/lib/use-yjs";
import {
  SURFACE_COLORS,
  DEFAULT_SURFACE_COLOR,
  HIGHWAY_COLORS,
  DEFAULT_HIGHWAY_COLOR,
  SMOOTHNESS_COLORS,
  DEFAULT_SMOOTHNESS_COLOR,
  CYCLEWAY_COLORS,
  DEFAULT_CYCLEWAY_COLOR,
} from "@trails-cool/map-core";
import { drawElevationChart, PADDING } from "~/lib/elevation-chart-draw";
import { useElevationData } from "~/lib/use-elevation-data";
import { Select } from "@trails-cool/ui";
import { setColorMode, type ColorMode } from "~/lib/route-data";

interface ElevationChartProps {
  yjs: YjsState;
  onHover?: (position: [number, number] | null) => void;
  highlightDistance?: number | null;
  onClickPosition?: (position: [number, number]) => void;
  onDragSelect?: (bounds: [[number, number], [number, number]]) => void;
  days?: DayStage[];
  /** Authoritative route stats (same source as the sidebar) for the summary. */
  routeStats?: { distance?: number; elevationGain?: number; elevationLoss?: number };
}

const COLLAPSE_KEY = "planner:elevationCollapsed";

const ChevronDown = () => (
  <svg width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2.5" strokeLinecap="round" strokeLinejoin="round">
    <polyline points="6 9 12 15 18 9" />
  </svg>
);
const ChevronUp = () => (
  <svg width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2.5" strokeLinecap="round" strokeLinejoin="round">
    <polyline points="18 15 12 9 6 15" />
  </svg>
);

/** Tiny inline elevation sparkline for the collapsed summary bar. */
function Sparkline({ points }: { points: Array<{ distance: number; elevation: number }> }) {
  if (points.length < 2) return null;
  const W = 72;
  const H = 18;
  const eles = points.map((p) => p.elevation);
  const min = Math.min(...eles);
  const range = Math.max(...eles) - min || 1;
  const maxD = points[points.length - 1]!.distance || 1;
  const d = points
    .map((p) => `${((p.distance / maxD) * W).toFixed(1)},${(H - ((p.elevation - min) / range) * H).toFixed(1)}`)
    .join(" ");
  return (
    <svg width={W} height={H} viewBox={`0 0 ${W} ${H}`} className="shrink-0 text-accent" aria-hidden>
      <polyline points={d} fill="none" stroke="currentColor" strokeWidth="1.5" strokeLinejoin="round" />
    </svg>
  );
}

export function ElevationChart({ yjs, onHover, highlightDistance, onClickPosition, onDragSelect, days, routeStats }: ElevationChartProps) {
  const { t } = useTranslation("planner");
  const { points, colorMode, surfaces, highways, maxspeeds, smoothnesses, tracktypes, cycleways, bikeroutes } = useElevationData(yjs.routeData);
  const [collapsed, setCollapsed] = useState(
    () => typeof window !== "undefined" && localStorage.getItem(COLLAPSE_KEY) === "1",
  );
  const toggleCollapsed = useCallback(() => {
    setCollapsed((c) => {
      const next = !c;
      try {
        localStorage.setItem(COLLAPSE_KEY, next ? "1" : "0");
      } catch {
        /* ignore */
      }
      return next;
    });
  }, []);

  // Collapsed-bar summary. Uses the authoritative routeStats (same source as
  // the sidebar) so the figures match; falls back to the chart's own distance
  // only when stats aren't available yet.
  const distanceMeters = routeStats?.distance ?? (points.length ? points[points.length - 1]!.distance : 0);
  const distanceKm = (distanceMeters / 1000).toFixed(1);
  const ascent = routeStats?.elevationGain;
  const descent = routeStats?.elevationLoss;

  const [hoverIdx, setHoverIdx] = useState<number | null>(null);
  const canvasRef = useRef<HTMLCanvasElement>(null);
  const isExternalHover = useRef(false);
  const dragStartX = useRef<number | null>(null);
  const dragStartClientX = useRef<number | null>(null);
  const isDragging = useRef(false);
  const dragCurrentX = useRef<number | null>(null);
  const dragCleanup = useRef<(() => void) | null>(null);

  // Detach any dangling window drag listeners on unmount.
  useEffect(() => () => dragCleanup.current?.(), []);

  // External highlight from map hover: find closest point by distance
  useEffect(() => {
    if (highlightDistance == null) {
      if (isExternalHover.current) {
        isExternalHover.current = false;
        setHoverIdx(null);
      }
      return;
    }
    if (points.length < 2) return;

    let closest = 0;
    let minDiff = Infinity;
    for (let i = 0; i < points.length; i++) {
      const diff = Math.abs(points[i]!.distance - highlightDistance);
      if (diff < minDiff) {
        minDiff = diff;
        closest = i;
      }
    }
    isExternalHover.current = true;
    setHoverIdx(closest);
  }, [highlightDistance, points]);

  const draw = useCallback(
    (highlightIdx: number | null) => {
      const canvas = canvasRef.current;
      if (!canvas || points.length < 2) return;

      const ctx = canvas.getContext("2d");
      if (!ctx) return;

      const dpr = window.devicePixelRatio || 1;
      const rect = canvas.getBoundingClientRect();
      canvas.width = rect.width * dpr;
      canvas.height = rect.height * dpr;
      ctx.scale(dpr, dpr);

      drawElevationChart(ctx, rect.width, rect.height, {
        points,
        colorMode,
        surfaces,
        highways,
        maxspeeds,
        smoothnesses,
        tracktypes,
        cycleways,
        bikeroutes,
        hoverIdx: highlightIdx,
        isDragging: isDragging.current,
        dragStartX: dragStartX.current,
        dragCurrentX: dragCurrentX.current,
        days,
      });
    },
    [points, colorMode, surfaces, highways, maxspeeds, smoothnesses, tracktypes, cycleways, bikeroutes, days],
  );

  useEffect(() => {
    draw(hoverIdx);
  }, [points, hoverIdx, colorMode, draw]);

  const handleMouseMove = useCallback(
    (e: React.MouseEvent<HTMLCanvasElement>) => {
      const canvas = canvasRef.current;
      if (!canvas || points.length < 2) return;

      // Drag is tracked via window listeners (see handleMouseDown); ignore
      // canvas moves while a press/drag gesture is active.
      if (dragStartClientX.current != null) return;

      const rect = canvas.getBoundingClientRect();
      const mouseX = e.clientX - rect.left;
      const chartW = rect.width - PADDING.left - PADDING.right;
      const ratio = (mouseX - PADDING.left) / chartW;

      if (ratio < 0 || ratio > 1) {
        setHoverIdx(null);
        onHover?.(null);
        return;
      }

      const maxDist = points[points.length - 1]!.distance;
      const targetDist = ratio * maxDist;

      let closest = 0;
      let minDiff = Infinity;
      for (let i = 0; i < points.length; i++) {
        const diff = Math.abs(points[i]!.distance - targetDist);
        if (diff < minDiff) {
          minDiff = diff;
          closest = i;
        }
      }

      isExternalHover.current = false;
      setHoverIdx(closest);
      const p = points[closest]!;
      onHover?.([p.lat, p.lon]);
    },
    [points, onHover],
  );

  const handleMouseLeave = useCallback(() => {
    // Keep an in-progress drag alive when the pointer leaves the canvas —
    // the window listeners keep tracking it.
    if (dragStartClientX.current != null) return;
    setHoverIdx(null);
    onHover?.(null);
  }, [onHover]);

  const handleMouseDown = useCallback(
    (e: React.MouseEvent<HTMLCanvasElement>) => {
      const canvas = canvasRef.current;
      if (!canvas) return;
      const rect = canvas.getBoundingClientRect();
      const chartW = rect.width - PADDING.left - PADDING.right;

      dragStartX.current = e.clientX - rect.left;
      dragStartClientX.current = e.clientX;
      isDragging.current = false;
      dragCurrentX.current = null;
      setHoverIdx(null);
      onHover?.(null);

      const clampX = (clientX: number) =>
        Math.max(PADDING.left, Math.min(clientX - rect.left, PADDING.left + chartW));

      // Track the drag on the window so it survives the pointer leaving the
      // canvas and still completes if the button is released outside it.
      const onWindowMove = (ev: MouseEvent) => {
        if (dragStartClientX.current == null) return;
        if (Math.abs(ev.clientX - dragStartClientX.current) > 5) {
          isDragging.current = true;
          dragCurrentX.current = clampX(ev.clientX);
          draw(null);
        }
      };

      const detach = () => {
        window.removeEventListener("mousemove", onWindowMove);
        window.removeEventListener("mouseup", onWindowUp);
        dragCleanup.current = null;
      };

      function onWindowUp(ev: MouseEvent) {
        detach();
        if (points.length >= 2) {
          const maxDist = points[points.length - 1]!.distance;
          if (isDragging.current && dragStartX.current != null) {
            const startRatio = Math.max(0, Math.min(1, (dragStartX.current - PADDING.left) / chartW));
            const endRatio = Math.max(0, Math.min(1, (clampX(ev.clientX) - PADDING.left) / chartW));
            const startDist = Math.min(startRatio, endRatio) * maxDist;
            const endDist = Math.max(startRatio, endRatio) * maxDist;
            let minLat = Infinity, maxLat = -Infinity, minLon = Infinity, maxLon = -Infinity;
            let found = false;
            for (const p of points) {
              if (p.distance >= startDist && p.distance <= endDist) {
                minLat = Math.min(minLat, p.lat);
                maxLat = Math.max(maxLat, p.lat);
                minLon = Math.min(minLon, p.lon);
                maxLon = Math.max(maxLon, p.lon);
                found = true;
              }
            }
            if (found && onDragSelect) onDragSelect([[minLat, minLon], [maxLat, maxLon]]);
          } else if (onClickPosition) {
            const ratio = (ev.clientX - rect.left - PADDING.left) / chartW;
            if (ratio >= 0 && ratio <= 1) {
              const targetDist = ratio * maxDist;
              let closest = 0;
              let minDiff = Infinity;
              for (let i = 0; i < points.length; i++) {
                const diff = Math.abs(points[i]!.distance - targetDist);
                if (diff < minDiff) { minDiff = diff; closest = i; }
              }
              onClickPosition([points[closest]!.lat, points[closest]!.lon]);
            }
          }
        }
        dragStartX.current = null;
        dragStartClientX.current = null;
        isDragging.current = false;
        dragCurrentX.current = null;
        draw(null);
      }

      dragCleanup.current = detach;
      window.addEventListener("mousemove", onWindowMove);
      window.addEventListener("mouseup", onWindowUp);
    },
    [points, onHover, onDragSelect, onClickPosition, draw],
  );

  const handleTouchStart = useCallback(
    (e: React.TouchEvent<HTMLCanvasElement>) => {
      e.preventDefault();
      const canvas = canvasRef.current;
      if (!canvas) return;
      const rect = canvas.getBoundingClientRect();

      if (e.touches.length === 1) {
        const x = e.touches[0]!.clientX - rect.left;
        dragStartX.current = x;
        dragStartClientX.current = e.touches[0]!.clientX;
        isDragging.current = false;
        dragCurrentX.current = null;
        const chartW = rect.width - PADDING.left - PADDING.right;
        const ratio = (x - PADDING.left) / chartW;
        if (ratio >= 0 && ratio <= 1 && points.length >= 2) {
          const maxDist = points[points.length - 1]!.distance;
          const targetDist = ratio * maxDist;
          let closest = 0;
          let minDiff = Infinity;
          for (let i = 0; i < points.length; i++) {
            const diff = Math.abs(points[i]!.distance - targetDist);
            if (diff < minDiff) { minDiff = diff; closest = i; }
          }
          isExternalHover.current = false;
          setHoverIdx(closest);
          const p = points[closest]!;
          onHover?.([p.lat, p.lon]);
        }
      } else if (e.touches.length === 2) {
        const x1 = e.touches[0]!.clientX - rect.left;
        const x2 = e.touches[1]!.clientX - rect.left;
        dragStartX.current = Math.min(x1, x2);
        dragCurrentX.current = Math.max(x1, x2);
        isDragging.current = true;
        draw(hoverIdx);
      }
    },
    [points, onHover, hoverIdx, draw],
  );

  const handleTouchMove = useCallback(
    (e: React.TouchEvent<HTMLCanvasElement>) => {
      e.preventDefault();
      const canvas = canvasRef.current;
      if (!canvas || points.length < 2) return;
      const rect = canvas.getBoundingClientRect();

      if (e.touches.length === 1 && !isDragging.current) {
        const x = e.touches[0]!.clientX - rect.left;
        const chartW = rect.width - PADDING.left - PADDING.right;
        const ratio = (x - PADDING.left) / chartW;
        if (ratio >= 0 && ratio <= 1) {
          const maxDist = points[points.length - 1]!.distance;
          const targetDist = ratio * maxDist;
          let closest = 0;
          let minDiff = Infinity;
          for (let i = 0; i < points.length; i++) {
            const diff = Math.abs(points[i]!.distance - targetDist);
            if (diff < minDiff) { minDiff = diff; closest = i; }
          }
          isExternalHover.current = false;
          setHoverIdx(closest);
          const p = points[closest]!;
          onHover?.([p.lat, p.lon]);
        }
      } else if (e.touches.length === 2) {
        const x1 = e.touches[0]!.clientX - rect.left;
        const x2 = e.touches[1]!.clientX - rect.left;
        dragStartX.current = Math.min(x1, x2);
        dragCurrentX.current = Math.max(x1, x2);
        isDragging.current = true;
        draw(hoverIdx);
      }
    },
    [points, onHover, hoverIdx, draw],
  );

  const handleTouchEnd = useCallback(
    (e: React.TouchEvent<HTMLCanvasElement>) => {
      if (isDragging.current && dragStartX.current != null && dragCurrentX.current != null && points.length >= 2) {
        const canvas = canvasRef.current;
        if (canvas) {
          const rect = canvas.getBoundingClientRect();
          const chartW = rect.width - PADDING.left - PADDING.right;
          const maxDist = points[points.length - 1]!.distance;
          const startRatio = Math.max(0, Math.min(1, (dragStartX.current - PADDING.left) / chartW));
          const endRatio = Math.max(0, Math.min(1, (dragCurrentX.current - PADDING.left) / chartW));
          const startDist = Math.min(startRatio, endRatio) * maxDist;
          const endDist = Math.max(startRatio, endRatio) * maxDist;

          let minLat = Infinity, maxLat = -Infinity, minLon = Infinity, maxLon = -Infinity;
          let found = false;
          for (const p of points) {
            if (p.distance >= startDist && p.distance <= endDist) {
              minLat = Math.min(minLat, p.lat);
              maxLat = Math.max(maxLat, p.lat);
              minLon = Math.min(minLon, p.lon);
              maxLon = Math.max(maxLon, p.lon);
              found = true;
            }
          }
          if (found && onDragSelect) {
            onDragSelect([[minLat, minLon], [maxLat, maxLon]]);
          }
        }
      } else if (e.changedTouches.length === 1 && onClickPosition && dragStartClientX.current != null) {
        const dx = Math.abs(e.changedTouches[0]!.clientX - dragStartClientX.current);
        if (dx <= 10) {
          const canvas = canvasRef.current;
          if (canvas && points.length >= 2) {
            const rect = canvas.getBoundingClientRect();
            const chartW = rect.width - PADDING.left - PADDING.right;
            const mouseX = e.changedTouches[0]!.clientX - rect.left;
            const ratio = (mouseX - PADDING.left) / chartW;
            if (ratio >= 0 && ratio <= 1) {
              const maxDist = points[points.length - 1]!.distance;
              const targetDist = ratio * maxDist;
              let closest = 0;
              let minDiff = Infinity;
              for (let i = 0; i < points.length; i++) {
                const diff = Math.abs(points[i]!.distance - targetDist);
                if (diff < minDiff) { minDiff = diff; closest = i; }
              }
              onClickPosition([points[closest]!.lat, points[closest]!.lon]);
            }
          }
        }
      }

      setHoverIdx(null);
      onHover?.(null);
      dragStartX.current = null;
      dragStartClientX.current = null;
      isDragging.current = false;
      dragCurrentX.current = null;
      draw(null);
    },
    [points, onHover, onClickPosition, onDragSelect, draw],
  );

  const setMode = useCallback((mode: string) => {
    setColorMode(yjs.routeData, mode as ColorMode);
  }, [yjs.routeData]);

  if (points.length < 2) return null;

  if (collapsed) {
    return (
      <div className="flex items-center gap-3 border-t border-border px-4 py-2 pb-[max(0.5rem,env(safe-area-inset-bottom))]">
        <Sparkline points={points} />
        <span className="font-mono text-xs text-text-md">
          {distanceKm} km
          {ascent !== undefined && (
            <>
              <span className="mx-1.5 text-text-lo">·</span>↑ {ascent} m
            </>
          )}
          {descent !== undefined && (
            <>
              <span className="mx-1.5 text-text-lo">·</span>↓ {descent} m
            </>
          )}
        </span>
        <div className="ml-auto">
          <IconButton size="sm" label={t("elevation.expand", "Expand elevation profile")} onClick={toggleCollapsed}>
            <ChevronUp />
          </IconButton>
        </div>
      </div>
    );
  }

  return (
    <div className="border-t border-border px-2 py-2 pb-[max(0.5rem,env(safe-area-inset-bottom))]">
      <div className="mb-1 flex items-center gap-2 px-2">
        {(() => {
          const osmLinks: Record<string, string> = {
            highway: "https://wiki.openstreetmap.org/wiki/Key:highway",
            maxspeed: "https://wiki.openstreetmap.org/wiki/Key:maxspeed",
            surface: "https://wiki.openstreetmap.org/wiki/Key:surface",
            smoothness: "https://wiki.openstreetmap.org/wiki/Key:smoothness",
            tracktype: "https://wiki.openstreetmap.org/wiki/Key:tracktype",
            cycleway: "https://wiki.openstreetmap.org/wiki/Key:cycleway",
            bikeroute: "https://wiki.openstreetmap.org/wiki/Tag:route%3Dbicycle",
          };
          const titles: Record<string, string> = {
            grade: t("elevation.grade"),
            highway: t("elevation.highway"),
            maxspeed: t("elevation.maxspeed"),
            smoothness: t("elevation.smoothness"),
            tracktype: t("elevation.tracktype"),
            cycleway: t("elevation.cycleway"),
            bikeroute: t("elevation.bikeroute"),
          };
          const title = titles[colorMode] ?? t("elevation.profile");
          const link = osmLinks[colorMode];
          return link ? (
            <a href={link} target="_blank" rel="noopener" className="shrink-0 text-xs font-medium text-text-md hover:text-accent hover:underline">
              {title}
            </a>
          ) : (
            <p className="shrink-0 text-xs font-medium text-text-md">{title}</p>
          );
        })()}
        <div className="flex flex-1 items-center justify-center gap-1.5 text-[10px] text-text-lo">
          {colorMode === "grade" && (<>
            <span className="flex items-center gap-0.5"><span className="inline-block h-1.5 w-2.5 rounded-sm" style={{ background: "#22c55e" }} />{"<3%"}</span>
            <span className="flex items-center gap-0.5"><span className="inline-block h-1.5 w-2.5 rounded-sm" style={{ background: "#eab308" }} />{"<6%"}</span>
            <span className="flex items-center gap-0.5"><span className="inline-block h-1.5 w-2.5 rounded-sm" style={{ background: "#f97316" }} />{"<10%"}</span>
            <span className="flex items-center gap-0.5"><span className="inline-block h-1.5 w-2.5 rounded-sm" style={{ background: "#ef4444" }} />{"<15%"}</span>
            <span className="flex items-center gap-0.5"><span className="inline-block h-1.5 w-2.5 rounded-sm" style={{ background: "#991b1b" }} />{"15%+"}</span>
          </>)}
          {colorMode === "elevation" && (<>
            <span>{Math.round(Math.min(...points.map(p => p.elevation)))}m</span>
            <span className="inline-block h-1.5 w-16 rounded-sm" style={{ background: "linear-gradient(to right, rgb(0, 200, 50), rgb(255, 200, 50), rgb(255, 0, 50))" }} />
            <span>{Math.round(Math.max(...points.map(p => p.elevation)))}m</span>
          </>)}
          {colorMode === "surface" && surfaces.length > 0 && (<>
            {[...new Set(surfaces)].slice(0, 6).map((s) => (
              <span key={s} className="flex items-center gap-0.5">
                <span className="inline-block h-1.5 w-2.5 rounded-sm" style={{ background: SURFACE_COLORS[s] ?? DEFAULT_SURFACE_COLOR }} />
                {s}
              </span>
            ))}
            {[...new Set(surfaces)].length > 6 && <span>+{[...new Set(surfaces)].length - 6}</span>}
          </>)}
          {colorMode === "highway" && highways.length > 0 && (<>
            {[...new Set(highways)].slice(0, 6).map((h) => (
              <span key={h} className="flex items-center gap-0.5">
                <span className="inline-block h-1.5 w-2.5 rounded-sm" style={{ background: HIGHWAY_COLORS[h] ?? DEFAULT_HIGHWAY_COLOR }} />
                {h}
              </span>
            ))}
            {[...new Set(highways)].length > 6 && <span>+{[...new Set(highways)].length - 6}</span>}
          </>)}
          {colorMode === "maxspeed" && (<>
            <span className="flex items-center gap-0.5"><span className="inline-block h-1.5 w-2.5 rounded-sm" style={{ background: "#22c55e" }} />{"≤30"}</span>
            <span className="flex items-center gap-0.5"><span className="inline-block h-1.5 w-2.5 rounded-sm" style={{ background: "#eab308" }} />{"≤50"}</span>
            <span className="flex items-center gap-0.5"><span className="inline-block h-1.5 w-2.5 rounded-sm" style={{ background: "#f97316" }} />{"≤70"}</span>
            <span className="flex items-center gap-0.5"><span className="inline-block h-1.5 w-2.5 rounded-sm" style={{ background: "#ef4444" }} />{"≤100"}</span>
            <span className="flex items-center gap-0.5"><span className="inline-block h-1.5 w-2.5 rounded-sm" style={{ background: "#991b1b" }} />{"100+"}</span>
          </>)}
          {colorMode === "smoothness" && smoothnesses.length > 0 && (<>
            {[...new Set(smoothnesses)].slice(0, 6).map((s) => (
              <span key={s} className="flex items-center gap-0.5">
                <span className="inline-block h-1.5 w-2.5 rounded-sm" style={{ background: SMOOTHNESS_COLORS[s] ?? DEFAULT_SMOOTHNESS_COLOR }} />
                {s}
              </span>
            ))}
            {[...new Set(smoothnesses)].length > 6 && <span>+{[...new Set(smoothnesses)].length - 6}</span>}
          </>)}
          {colorMode === "tracktype" && (<>
            <span className="flex items-center gap-0.5"><span className="inline-block h-1.5 w-2.5 rounded-sm" style={{ background: "#22c55e" }} />grade1</span>
            <span className="flex items-center gap-0.5"><span className="inline-block h-1.5 w-2.5 rounded-sm" style={{ background: "#84cc16" }} />grade2</span>
            <span className="flex items-center gap-0.5"><span className="inline-block h-1.5 w-2.5 rounded-sm" style={{ background: "#eab308" }} />grade3</span>
            <span className="flex items-center gap-0.5"><span className="inline-block h-1.5 w-2.5 rounded-sm" style={{ background: "#f97316" }} />grade4</span>
            <span className="flex items-center gap-0.5"><span className="inline-block h-1.5 w-2.5 rounded-sm" style={{ background: "#ef4444" }} />grade5</span>
          </>)}
          {colorMode === "cycleway" && cycleways.length > 0 && (<>
            {[...new Set(cycleways)].slice(0, 6).map((c) => (
              <span key={c} className="flex items-center gap-0.5">
                <span className="inline-block h-1.5 w-2.5 rounded-sm" style={{ background: CYCLEWAY_COLORS[c] ?? DEFAULT_CYCLEWAY_COLOR }} />
                {c}
              </span>
            ))}
            {[...new Set(cycleways)].length > 6 && <span>+{[...new Set(cycleways)].length - 6}</span>}
          </>)}
          {colorMode === "bikeroute" && (<>
            <span className="flex items-center gap-0.5"><span className="inline-block h-1.5 w-2.5 rounded-sm" style={{ background: "#7c3aed" }} />International</span>
            <span className="flex items-center gap-0.5"><span className="inline-block h-1.5 w-2.5 rounded-sm" style={{ background: "#2563eb" }} />National</span>
            <span className="flex items-center gap-0.5"><span className="inline-block h-1.5 w-2.5 rounded-sm" style={{ background: "#0891b2" }} />Regional</span>
            <span className="flex items-center gap-0.5"><span className="inline-block h-1.5 w-2.5 rounded-sm" style={{ background: "#059669" }} />Local</span>
            <span className="flex items-center gap-0.5"><span className="inline-block h-1.5 w-2.5 rounded-sm" style={{ background: "#d4d4d8" }} />None</span>
          </>)}
        </div>
        <Select
          size="sm"
          value={colorMode}
          onChange={(e) => setMode(e.target.value)}
          aria-label={t("elevation.profile")}
          className="shrink-0"
        >
          <option value="plain">{t("colorMode.plain")}</option>
          <option value="elevation">{t("colorMode.elevation")}</option>
          <option value="grade">{t("colorMode.grade")}</option>
          <option value="surface">{t("colorMode.surface")}</option>
          <option value="highway">{t("colorMode.highway")}</option>
          <option value="maxspeed">{t("colorMode.maxspeed")}</option>
          <option value="smoothness">{t("colorMode.smoothness")}</option>
          <option value="tracktype">{t("colorMode.tracktype")}</option>
          <option value="cycleway">{t("colorMode.cycleway")}</option>
          <option value="bikeroute">{t("colorMode.bikeroute")}</option>
        </Select>
        <IconButton
          size="sm"
          label={t("elevation.collapse", "Collapse elevation profile")}
          onClick={toggleCollapsed}
          className="shrink-0"
        >
          <ChevronDown />
        </IconButton>
      </div>
      <canvas
        ref={canvasRef}
        className="h-24 w-full cursor-crosshair touch-none"
        onMouseMove={handleMouseMove}
        onMouseLeave={handleMouseLeave}
        onMouseDown={handleMouseDown}
        onTouchStart={handleTouchStart}
        onTouchMove={handleTouchMove}
        onTouchEnd={handleTouchEnd}
      />
    </div>
  );
}
