import React, { useEffect, useMemo, useRef, useState, useCallback } from 'react';
import {
  Box, Typography, Card, CardContent, Avatar, Chip, Stack, Button, Grid,
  IconButton, List, ListItemButton, ListItemText, Collapse, Tooltip, Divider,
  LinearProgress, Menu, MenuItem, Drawer, Paper
} from '@mui/material';
import { alpha } from '@mui/material/styles';
import { MapContainer, TileLayer, Marker, Popup, Polyline, Tooltip as LTooltip, useMap } from 'react-leaflet';
import L from 'leaflet';
import 'leaflet/dist/leaflet.css';

import RouteOutlinedIcon from '@mui/icons-material/RouteOutlined';
import PlayArrowRoundedIcon from '@mui/icons-material/PlayArrowRounded';
import PauseRoundedIcon from '@mui/icons-material/PauseRounded';
import ReplayRoundedIcon from '@mui/icons-material/ReplayRounded';
import SpeedRoundedIcon from '@mui/icons-material/SpeedRounded';
import VisibilityOutlinedIcon from '@mui/icons-material/VisibilityOutlined';
import VisibilityOffOutlinedIcon from '@mui/icons-material/VisibilityOffOutlined';
import ExpandMoreRoundedIcon from '@mui/icons-material/ExpandMoreRounded';
import ExpandLessRoundedIcon from '@mui/icons-material/ExpandLessRounded';
import WarehouseRoundedIcon from '@mui/icons-material/WarehouseRounded';
import FlagRoundedIcon from '@mui/icons-material/FlagRounded';
import Inventory2OutlinedIcon from '@mui/icons-material/Inventory2Outlined';
import CheckCircleRoundedIcon from '@mui/icons-material/CheckCircleRounded';
import CancelRoundedIcon from '@mui/icons-material/CancelRounded';
import DeliveryDiningRoundedIcon from '@mui/icons-material/DeliveryDiningRounded';
import StorefrontOutlinedIcon from '@mui/icons-material/StorefrontOutlined';
import GroupsOutlinedIcon from '@mui/icons-material/GroupsOutlined';
import StraightenRoundedIcon from '@mui/icons-material/StraightenRounded';
import PaymentsOutlinedIcon from '@mui/icons-material/PaymentsOutlined';
import PhoneOutlinedIcon from '@mui/icons-material/PhoneOutlined';
import PlaceOutlinedIcon from '@mui/icons-material/PlaceOutlined';
import AccessTimeOutlinedIcon from '@mui/icons-material/AccessTimeOutlined';
import PersonOutlineOutlinedIcon from '@mui/icons-material/PersonOutlineOutlined';
import ArrowBackRoundedIcon from '@mui/icons-material/ArrowBackRounded';
import ScaleOutlinedIcon from '@mui/icons-material/ScaleOutlined';
import ScheduleOutlinedIcon from '@mui/icons-material/ScheduleOutlined';
import NotesOutlinedIcon from '@mui/icons-material/NotesOutlined';
import CallOutlinedIcon from '@mui/icons-material/CallOutlined';
import MyLocationOutlinedIcon from '@mui/icons-material/MyLocationOutlined';

// ════════════════════════════════════════════════════════════════════════════════
//  Leaflet base-icon fix (same approach as TrackingMap.jsx)
// ════════════════════════════════════════════════════════════════════════════════
delete L.Icon.Default.prototype._getIconUrl;
L.Icon.Default.mergeOptions({
  iconRetinaUrl: 'https://cdnjs.cloudflare.com/ajax/libs/leaflet/1.7.1/images/marker-icon-2x.png',
  iconUrl: 'https://cdnjs.cloudflare.com/ajax/libs/leaflet/1.7.1/images/marker-icon.png',
  shadowUrl: 'https://cdnjs.cloudflare.com/ajax/libs/leaflet/1.7.1/images/marker-shadow.png',
});

// Keeps Leaflet's canvas sized correctly inside a flex layout / on sidebar toggle.
function MapResizeHandler() {
  const map = useMap();
  useEffect(() => {
    const fix = () => map.invalidateSize();
    const t = setTimeout(fix, 250);
    window.addEventListener('resize', fix);
    const ro = new ResizeObserver(fix);
    ro.observe(map.getContainer());
    return () => { clearTimeout(t); window.removeEventListener('resize', fix); ro.disconnect(); };
  }, [map]);
  return null;
}

// Imperatively fits the map to a set of latlng points whenever they change.
function FitBounds({ points }) {
  const map = useMap();
  useEffect(() => {
    if (!points || points.length === 0) return;
    const bounds = L.latLngBounds(points.map((p) => [p.lat, p.lng]));
    if (bounds.isValid()) map.fitBounds(bounds, { padding: [60, 60], maxZoom: 15 });
  }, [points, map]);
  return null;
}

// Pans/zooms to a single point when an order is focused (clicked).
function FlyTo({ target }) {
  const map = useMap();
  useEffect(() => {
    if (target) map.flyTo([target.lat, target.lng], Math.max(map.getZoom(), 14), { duration: 0.6 });
  }, [target, map]);
  return null;
}

// ════════════════════════════════════════════════════════════════════════════════
//  Leaflet DivIcons
// ════════════════════════════════════════════════════════════════════════════════
const hubIcon = new L.DivIcon({
  className: 'rr-icon',
  html: `<div style="background:#C01227;width:34px;height:34px;border-radius:10px;border:3px solid #fff;box-shadow:0 4px 12px rgba(0,0,0,.25);display:flex;align-items:center;justify-content:center;">
    <svg fill="#fff" width="18" height="18" viewBox="0 0 24 24"><path d="M12 3 2 8l10 5 10-5-10-5Zm0 7L4.21 6.11 12 2.22l7.79 3.89L12 10Z"/><path d="M2 12l10 5 10-5M2 16l10 5 10-5" stroke="#fff" stroke-width="1.6" fill="none"/></svg>
  </div>`,
  iconSize: [34, 34],
  iconAnchor: [17, 17],
});

const flagIcon = new L.DivIcon({
  className: 'rr-icon',
  html: `<div style="background:#1E8E3E;width:30px;height:30px;border-radius:50%;border:3px solid #fff;box-shadow:0 4px 10px rgba(0,0,0,.25);display:flex;align-items:center;justify-content:center;">
    <svg fill="#fff" width="15" height="15" viewBox="0 0 24 24"><path d="M14.4 6 14 4H5v17h2v-7h5.6l.4 2h7V6z"/></svg>
  </div>`,
  iconSize: [30, 30],
  iconAnchor: [15, 15],
});

// Numbered stop pin in the rider's colour. Pickups get a square pin, deliveries a
// round one — so the two journey types are distinguishable at a glance on the map.
const stopIcon = (n, color, focused, isPickup) => new L.DivIcon({
  className: 'rr-icon',
  html: `<div style="background:${color};width:${focused ? 30 : 24}px;height:${focused ? 30 : 24}px;border-radius:${isPickup ? '6px' : '50%'};border:2.5px solid #fff;box-shadow:0 3px 8px rgba(0,0,0,.3);display:flex;align-items:center;justify-content:center;color:#fff;font-family:Arial,sans-serif;font-weight:700;font-size:${focused ? 14 : 12}px;">${n}</div>`,
  iconSize: focused ? [30, 30] : [24, 24],
  iconAnchor: focused ? [15, 15] : [12, 12],
});

// The animated "moving rider" puck in the rider's colour.
const moverIcon = (color) => new L.DivIcon({
  className: 'rr-icon rr-mover',
  html: `<div style="background:${color};width:30px;height:30px;border-radius:50%;border:3px solid #fff;box-shadow:0 0 0 6px ${color}33, 0 4px 12px rgba(0,0,0,.35);display:flex;align-items:center;justify-content:center;">
    <svg fill="#fff" width="17" height="17" viewBox="0 0 24 24"><path d="M19 7c0-1.1-.9-2-2-2h-3v2h3v2.65L13.52 14H10V9H6c-2.21 0-4 1.79-4 4v3h2c0 1.66 1.34 3 3 3s3-1.34 3-3h4.48L19 10.35V7ZM7 17c-.55 0-1-.45-1-1h2c0 .55-.45 1-1 1Z"/></svg>
  </div>`,
  iconSize: [30, 30],
  iconAnchor: [15, 15],
});

// ════════════════════════════════════════════════════════════════════════════════
//  Mock data — every rider has a DELIVERY trip and a PICKUP trip for the day, each
//  with its own ordered stops, timings and distance. Every order stop carries the
//  full detail shown in the side drawer when clicked.
//
//  Delivery: hub → customer drops.   Pickup: merchant collections → hub.
// ════════════════════════════════════════════════════════════════════════════════
const HUB = { lat: 28.6139, lng: 77.2090, label: 'Delhi Operations Hub' };
const hubStop = (time) => ({ kind: 'hub', label: HUB.label, lat: HUB.lat, lng: HUB.lng, time });

const RIDERS = [
  {
    id: 'RDR-8012', name: 'Muthu Kumar', color: '#1A73E8', vehicle: 'Electric Bike', vehicleNo: 'DL-04-EB-1234', phone: '+91 98765 43210',
    delivery: {
      startTime: '08:12', endTime: '13:40', distanceKm: 18.4,
      stops: [
        hubStop('08:12'),
        { kind: 'order', orderId: 'ORD-100231', customer: 'Aarav Mehta', phone: '+91 90011 22334', address: 'Flat 402, Dwarka Sector 12, New Delhi', lat: 28.5921, lng: 77.0460, time: '08:48', status: 'Picked', items: 2, weight: '1.4 kg', slot: '08:00–10:00', cod: 0, payment: 'Prepaid', legKm: 5.2, instructions: 'Leave at reception if not home.' },
        { kind: 'order', orderId: 'ORD-100244', customer: 'Priya Nair', phone: '+91 90022 33445', address: 'House 18, Janakpuri B-Block, New Delhi', lat: 28.6219, lng: 77.0878, time: '09:36', status: 'Picked', items: 1, weight: '0.6 kg', slot: '09:00–11:00', cod: 1200, payment: 'COP', legKm: 4.1, instructions: 'Call on arrival.' },
        { kind: 'order', orderId: 'ORD-100258', customer: 'Rohit Sethi', phone: '+91 90033 44556', address: 'Shop 7, Rajouri Garden Market, New Delhi', lat: 28.6492, lng: 77.1207, time: '10:25', status: 'Failed', items: 3, weight: '2.8 kg', slot: '10:00–12:00', cod: 0, payment: 'Prepaid', legKm: 4.6, instructions: 'Customer unreachable — reattempt tomorrow.' },
        { kind: 'order', orderId: 'ORD-100269', customer: 'Sana Kapoor', phone: '+91 90044 55667', address: 'A-22, Karol Bagh, New Delhi', lat: 28.6512, lng: 77.1907, time: '11:30', status: 'Picked', items: 1, weight: '0.9 kg', slot: '11:00–13:00', cod: 850, payment: 'COP', legKm: 4.5, instructions: '' },
      ],
    },
    pickup: {
      startTime: '14:10', endTime: '16:50', distanceKm: 11.2,
      stops: [
        { kind: 'order', orderId: 'PCK-50118', customer: 'TrendKart Store', phone: '+91 98801 11222', address: 'Tilak Nagar Main Rd, New Delhi', lat: 28.6363, lng: 77.0945, time: '14:35', status: 'Picked', items: 6, weight: '4.2 kg', slot: '14:00–16:00', cod: 0, payment: 'Merchant', legKm: 6.0, instructions: 'Collect from back gate.' },
        { kind: 'order', orderId: 'PCK-50126', customer: 'FreshLeaf Organics', phone: '+91 98802 22333', address: 'Subhash Nagar, New Delhi', lat: 28.6404, lng: 77.1199, time: '15:30', status: 'Picked', items: 3, weight: '5.5 kg', slot: '15:00–17:00', cod: 0, payment: 'Merchant', legKm: 3.0, instructions: '' },
        { kind: 'order', orderId: 'PCK-50131', customer: 'GadgetHub', phone: '+91 98803 33444', address: 'Moti Nagar, New Delhi', lat: 28.6580, lng: 77.1450, time: '16:15', status: 'Missed', items: 2, weight: '1.1 kg', slot: '16:00–18:00', cod: 0, payment: 'Merchant', legKm: 2.2, instructions: 'Shop was closed at pickup time.' },
        hubStop('16:50'),
      ],
    },
  },
  {
    id: 'RDR-8041', name: 'Sana Sheikh', color: '#8E24AA', vehicle: 'Motorcycle', vehicleNo: 'DL-02-MC-1199', phone: '+91 98765 43214',
    delivery: {
      startTime: '08:00', endTime: '14:05', distanceKm: 22.9,
      stops: [
        hubStop('08:00'),
        { kind: 'order', orderId: 'ORD-100277', customer: 'Imran Qureshi', phone: '+91 90055 66778', address: 'N-Block, Connaught Place, New Delhi', lat: 28.6315, lng: 77.2167, time: '08:30', status: 'Picked', items: 1, weight: '0.4 kg', slot: '08:00–10:00', cod: 0, payment: 'Prepaid', legKm: 2.1, instructions: '' },
        { kind: 'order', orderId: 'ORD-100283', customer: 'Neha Gupta', phone: '+91 90066 77889', address: 'C-44, Lajpat Nagar II, New Delhi', lat: 28.5677, lng: 77.2433, time: '09:20', status: 'Picked', items: 2, weight: '1.7 kg', slot: '09:00–11:00', cod: 1450, payment: 'COP', legKm: 7.4, instructions: 'Ring twice.' },
        { kind: 'order', orderId: 'ORD-100291', customer: 'Vikas Rao', phone: '+91 90077 88990', address: 'J-Block, Saket, New Delhi', lat: 28.5245, lng: 77.2066, time: '10:40', status: 'Picked', items: 1, weight: '0.8 kg', slot: '10:00–12:00', cod: 0, payment: 'Prepaid', legKm: 6.2, instructions: '' },
        { kind: 'order', orderId: 'ORD-100305', customer: 'Diya Shah', phone: '+91 90088 99001', address: 'Malviya Nagar Main Market, New Delhi', lat: 28.5355, lng: 77.2110, time: '11:55', status: 'Picked', items: 4, weight: '3.1 kg', slot: '11:00–13:00', cod: 2300, payment: 'COP', legKm: 1.4, instructions: 'Heavy parcel — handle with care.' },
      ],
    },
    pickup: {
      startTime: '14:30', endTime: '17:20', distanceKm: 14.6,
      stops: [
        { kind: 'order', orderId: 'PCK-50140', customer: 'Bloom & Co Florists', phone: '+91 98804 44555', address: 'Greater Kailash I, New Delhi', lat: 28.5494, lng: 77.2426, time: '15:00', status: 'Picked', items: 4, weight: '2.0 kg', slot: '14:30–16:30', cod: 0, payment: 'Merchant', legKm: 8.1, instructions: '' },
        { kind: 'order', orderId: 'PCK-50147', customer: 'BookNook', phone: '+91 98805 55666', address: 'Hauz Khas Village, New Delhi', lat: 28.5535, lng: 77.1944, time: '16:05', status: 'Picked', items: 9, weight: '7.8 kg', slot: '15:30–17:30', cod: 0, payment: 'Merchant', legKm: 4.5, instructions: 'Multiple boxes.' },
        hubStop('17:20'),
      ],
    },
  },
  {
    id: 'RDR-8015', name: 'Rajesh Sharma', color: '#1E8E3E', vehicle: 'Cargo Van', vehicleNo: 'DL-01-CV-9876', phone: '+91 98765 43211',
    delivery: {
      startTime: '07:50', endTime: '15:10', distanceKm: 31.2,
      stops: [
        hubStop('07:50'),
        { kind: 'order', orderId: 'ORD-100312', customer: 'Anil Verma', phone: '+91 90099 00112', address: 'Sector 7, Rohini, New Delhi', lat: 28.7042, lng: 77.1025, time: '08:55', status: 'Picked', items: 5, weight: '6.2 kg', slot: '08:00–10:00', cod: 0, payment: 'Prepaid', legKm: 12.4, instructions: '' },
        { kind: 'order', orderId: 'ORD-100320', customer: 'Meera Iyer', phone: '+91 90100 11223', address: 'NSP, Pitampura, New Delhi', lat: 28.6996, lng: 77.1314, time: '09:50', status: 'Picked', items: 2, weight: '2.0 kg', slot: '09:00–11:00', cod: 990, payment: 'COP', legKm: 3.2, instructions: '' },
        { kind: 'order', orderId: 'ORD-100334', customer: 'Sahil Khan', phone: '+91 90111 22334', address: 'Model Town III, New Delhi', lat: 28.7158, lng: 77.1910, time: '11:10', status: 'Failed', items: 1, weight: '0.7 kg', slot: '10:00–12:00', cod: 0, payment: 'Prepaid', legKm: 6.1, instructions: 'Wrong address provided.' },
        { kind: 'order', orderId: 'ORD-100349', customer: 'Tara Bose', phone: '+91 90122 33445', address: 'Civil Lines, New Delhi', lat: 28.6796, lng: 77.2240, time: '12:30', status: 'Picked', items: 3, weight: '4.4 kg', slot: '12:00–14:00', cod: 3100, payment: 'COP', legKm: 5.0, instructions: '' },
      ],
    },
    pickup: {
      startTime: '15:40', endTime: '18:30', distanceKm: 19.8,
      stops: [
        { kind: 'order', orderId: 'PCK-50155', customer: 'MegaMart Warehouse', phone: '+91 98806 66777', address: 'Wazirpur Industrial Area, New Delhi', lat: 28.6991, lng: 77.1612, time: '16:20', status: 'Picked', items: 24, weight: '38.0 kg', slot: '16:00–18:00', cod: 0, payment: 'Merchant', legKm: 11.0, instructions: 'Use loading dock 4.' },
        { kind: 'order', orderId: 'PCK-50163', customer: 'HomeStyle Furnishings', phone: '+91 98807 77888', address: 'Ashok Vihar, New Delhi', lat: 28.6924, lng: 77.1760, time: '17:25', status: 'Picked', items: 8, weight: '22.5 kg', slot: '17:00–19:00', cod: 0, payment: 'Merchant', legKm: 3.0, instructions: '' },
        hubStop('18:30'),
      ],
    },
  },
  {
    id: 'RDR-8044', name: 'Harpreet Gill', color: '#E8710A', vehicle: 'Cycle', vehicleNo: '—', phone: '+91 98765 43215',
    delivery: {
      startTime: '09:20', endTime: '13:15', distanceKm: 9.7,
      stops: [
        hubStop('09:20'),
        { kind: 'order', orderId: 'ORD-100356', customer: 'Kabir Anand', phone: '+91 90133 44556', address: 'Mayur Vihar Phase I, New Delhi', lat: 28.6090, lng: 77.2920, time: '10:05', status: 'Picked', items: 1, weight: '0.5 kg', slot: '10:00–12:00', cod: 600, payment: 'COP', legKm: 9.0, instructions: '' },
        { kind: 'order', orderId: 'ORD-100361', customer: 'Ritu Saxena', phone: '+91 90144 55667', address: 'Mayur Vihar Phase III, New Delhi', lat: 28.6135, lng: 77.3215, time: '11:10', status: 'Picked', items: 2, weight: '1.2 kg', slot: '11:00–13:00', cod: 0, payment: 'Prepaid', legKm: 3.0, instructions: '' },
        { kind: 'order', orderId: 'ORD-100370', customer: 'Farhan Ali', phone: '+91 90155 66778', address: 'Patparganj, New Delhi', lat: 28.6280, lng: 77.2960, time: '12:20', status: 'Picked', items: 1, weight: '0.8 kg', slot: '12:00–14:00', cod: 450, payment: 'COP', legKm: 2.9, instructions: '' },
      ],
    },
    pickup: {
      startTime: '13:40', endTime: '15:30', distanceKm: 6.4,
      stops: [
        { kind: 'order', orderId: 'PCK-50170', customer: 'Cafe Mosaic', phone: '+91 98808 88999', address: 'Mayur Vihar Phase I Market, New Delhi', lat: 28.6055, lng: 77.2985, time: '14:10', status: 'Picked', items: 2, weight: '1.5 kg', slot: '14:00–16:00', cod: 0, payment: 'Merchant', legKm: 4.0, instructions: '' },
        hubStop('15:30'),
      ],
    },
  },
];

// ── helpers ────────────────────────────────────────────────────────────────────
const initials = (n) => n.split(' ').map((w) => w[0]).slice(0, 2).join('').toUpperCase();
const inr = (n) => `₹${(Number(n) || 0).toLocaleString('en-IN')}`;
const lerpPoint = (a, b, t) => ({ lat: a.lat + (b.lat - a.lat) * t, lng: a.lng + (b.lng - a.lng) * t });

const STATUS_META = {
  Picked: { color: '#1A73E8', icon: CheckCircleRoundedIcon, label: 'Picked up' },
  Missed: { color: '#D93025', icon: CancelRoundedIcon, label: 'Missed' },
};

const MODES = {
  pickup: { label: 'Pickups', icon: StorefrontOutlinedIcon, doneLabel: 'Picked up', doneStatus: 'Picked', failStatus: 'Missed', pointLabel: 'Pickup', dash: '8 8' },
};

// ════════════════════════════════════════════════════════════════════════════════
//  Route resolution — OSRM road geometry (free, no API key); straight-line fallback.
// ════════════════════════════════════════════════════════════════════════════════
async function fetchRoadRoute(stops) {
  const coords = stops.map((s) => `${s.lng},${s.lat}`).join(';');
  const url = `https://router.project-osrm.org/route/v1/driving/${coords}?overview=full&geometries=geojson`;
  const res = await fetch(url);
  const json = await res.json();
  if (json.routes && json.routes[0]) {
    return json.routes[0].geometry.coordinates.map(([lng, lat]) => ({ lat, lng }));
  }
  throw new Error('No route');
}

// ════════════════════════════════════════════════════════════════════════════════
//  Small presentational pieces
// ════════════════════════════════════════════════════════════════════════════════
function KpiCard({ icon: Icon, label, value, sub, color, bg }) {
  return (
    <Card elevation={0} sx={{ borderRadius: 2, border: '1px solid #ECEEF1', height: '100%' }}>
      <CardContent sx={{ p: 2, '&:last-child': { pb: 2 } }}>
        <Stack direction="row" alignItems="center" spacing={1.25} sx={{ mb: 1 }}>
          <Avatar variant="rounded" sx={{ bgcolor: bg, color, width: 34, height: 34, borderRadius: 2 }}>
            <Icon sx={{ fontSize: 18 }} />
          </Avatar>
          <Typography sx={{ fontSize: '0.68rem', color: '#6C757D', fontWeight: 700, letterSpacing: 0.5, textTransform: 'uppercase' }}>
            {label}
          </Typography>
        </Stack>
        <Typography sx={{ fontSize: '1.5rem', fontWeight: 800, color: '#1A1A2E', lineHeight: 1.1 }}>{value}</Typography>
        {sub && <Typography variant="caption" color="text.secondary">{sub}</Typography>}
      </CardContent>
    </Card>
  );
}

function DetailRow({ icon: Icon, label, value, valueColor }) {
  if (value === undefined || value === null || value === '') return null;
  return (
    <Stack direction="row" spacing={2} alignItems="flex-start">
      <Icon sx={{ fontSize: 20, color: '#9AA0A6', mt: 0.25 }} />
      <Box sx={{ flex: 1, minWidth: 0 }}>
        <Typography variant="caption" color="text.secondary" sx={{ display: 'block' }}>{label}</Typography>
        <Typography sx={{ fontWeight: 600, color: valueColor || '#343A40', wordBreak: 'break-word' }}>{value}</Typography>
      </Box>
    </Stack>
  );
}

// Full order/pickup detail panel — rendered INLINE in the left column (not a modal)
// so the map stays visible and zoomed to the stop while these details are read.
function OrderDetailPanel({ data, onBack }) {
  const { order, rider, mode, index } = data;
  const meta = STATUS_META[order.status] || {};
  const StatusIcon = meta.icon || CheckCircleRoundedIcon;
  const isPickup = mode === 'pickup';

  return (
    <Box sx={{ display: 'flex', flexDirection: 'column', height: '100%', bgcolor: '#fff' }}>
      {/* Header */}
      <Box sx={{ background: `linear-gradient(135deg, ${rider.color} 0%, ${alpha(rider.color, 0.82)} 100%)`, px: 2.75, py: 2.25, color: '#fff', flexShrink: 0 }}>
        <Button onClick={onBack} startIcon={<ArrowBackRoundedIcon />} size="small"
          sx={{ color: 'rgba(255,255,255,0.95)', textTransform: 'none', fontWeight: 600, mb: 1.25, ml: -0.5, '&:hover': { bgcolor: 'rgba(255,255,255,0.12)' } }}>
          Close
        </Button>
        <Stack direction="row" alignItems="center" spacing={0.75} mb={1} flexWrap="wrap" useFlexGap>
          <Chip size="small" icon={(isPickup ? <StorefrontOutlinedIcon /> : <DeliveryDiningRoundedIcon />)} label={isPickup ? 'Pickup' : 'Delivery'}
            sx={{ bgcolor: 'rgba(255,255,255,0.18)', color: '#fff', fontWeight: 700, '& .MuiChip-icon': { color: '#fff' } }} />
          <Chip size="small" icon={<StatusIcon sx={{ color: '#fff !important' }} />} label={meta.label || order.status}
            sx={{ bgcolor: 'rgba(255,255,255,0.18)', color: '#fff', fontWeight: 700 }} />
        </Stack>
        <Typography variant="h6" sx={{ fontWeight: 800, lineHeight: 1.25 }}>{order.customer}</Typography>
        <Typography variant="body2" sx={{ opacity: 0.9, fontFamily: 'monospace', mt: 0.25 }}>#{order.orderId}</Typography>
      </Box>

      {/* Body */}
      <Box sx={{ p: 2, bgcolor: '#F8F9FB', flex: 1, overflow: 'auto' }}>
        <Stack spacing={1.75}>

          {/* Contact */}
          <Paper elevation={0} sx={{ p: 2, borderRadius: 2, border: '1px solid #E2E8F0', bgcolor: '#fff' }}>
            <Typography variant="overline" sx={{ color: '#6C757D', fontWeight: 700, letterSpacing: 1, fontSize: '0.7rem', display: 'block', mb: 1.5 }}>
              {isPickup ? 'MERCHANT / SENDER' : 'CUSTOMER'}
            </Typography>
            <Stack spacing={1.75}>
              <DetailRow icon={isPickup ? StorefrontOutlinedIcon : PersonOutlineOutlinedIcon} label="Name" value={order.customer} />
              <DetailRow icon={PhoneOutlinedIcon} label="Phone" value={order.phone} />
              <DetailRow icon={PlaceOutlinedIcon} label="Pickup address" value={order.address} />
            </Stack>
          </Paper>

          {/* Pickup summary */}
          <Paper elevation={0} sx={{ p: 2, borderRadius: 2, border: '1px solid #E2E8F0', bgcolor: '#fff' }}>
            <Typography variant="overline" sx={{ color: '#6C757D', fontWeight: 700, letterSpacing: 1, fontSize: '0.7rem', display: 'block', mb: 1.5 }}>
              PICKUP SUMMARY
            </Typography>
            <Grid container rowSpacing={2} columnSpacing={1.5}>
              <Grid item xs={6}><DetailRow icon={AccessTimeOutlinedIcon} label="Picked at" value={order.time} /></Grid>
              <Grid item xs={6}><DetailRow icon={ScheduleOutlinedIcon} label="Time slot" value={order.slot} /></Grid>
              <Grid item xs={6}><DetailRow icon={Inventory2OutlinedIcon} label="Items" value={`${order.items} ${order.items === 1 ? 'parcel' : 'parcels'}`} /></Grid>
              <Grid item xs={6}><DetailRow icon={ScaleOutlinedIcon} label="Weight" value={order.weight} /></Grid>
              <Grid item xs={6}><DetailRow icon={StraightenRoundedIcon} label="Leg distance" value={`${order.legKm} km`} /></Grid>
              <Grid item xs={6}><DetailRow icon={PaymentsOutlinedIcon} label="Payment" value={order.payment} /></Grid>
            </Grid>
          </Paper>

          {order.cod > 0 && (
            <Box sx={{ p: 2, borderRadius: 2, bgcolor: alpha('#F29900', 0.1), border: `1px solid ${alpha('#F29900', 0.3)}` }}>
              <Stack direction="row" alignItems="center" spacing={1.5}>
                <PaymentsOutlinedIcon sx={{ color: '#B06000' }} />
                <Box>
                  <Typography variant="caption" sx={{ color: '#B06000', fontWeight: 700 }}>CASH ON PICKUP</Typography>
                  <Typography sx={{ fontWeight: 800, color: '#B06000' }}>{inr(order.cod)}</Typography>
                </Box>
              </Stack>
            </Box>
          )}

          {/* Route & location */}
          <Paper elevation={0} sx={{ p: 2, borderRadius: 2, border: '1px solid #E2E8F0', bgcolor: '#fff' }}>
            <Typography variant="overline" sx={{ color: '#6C757D', fontWeight: 700, letterSpacing: 1, fontSize: '0.7rem', display: 'block', mb: 1.5 }}>
              ROUTE &amp; LOCATION
            </Typography>
            <Stack spacing={1.75}>
              <DetailRow icon={isPickup ? StorefrontOutlinedIcon : WarehouseRoundedIcon} label="Route leg"
                value={isPickup ? `${order.customer} → ${HUB.label}` : `${HUB.label} → ${order.customer}`} />
              <DetailRow icon={MyLocationOutlinedIcon} label="Coordinates" value={`${order.lat.toFixed(4)}, ${order.lng.toFixed(4)}`} />
              {order.instructions && <DetailRow icon={NotesOutlinedIcon} label="Instructions" value={order.instructions} valueColor="#5F6368" />}
            </Stack>
          </Paper>

          {/* Assigned miler */}
          <Paper elevation={0} sx={{ p: 2, borderRadius: 2, border: '1px solid #E2E8F0', bgcolor: '#fff' }}>
            <Typography variant="overline" sx={{ color: '#6C757D', fontWeight: 700, letterSpacing: 1, fontSize: '0.7rem', display: 'block', mb: 1.5 }}>
              ASSIGNED MILER
            </Typography>
            <Stack direction="row" alignItems="center" spacing={1.5}>
              <Avatar sx={{ width: 40, height: 40, bgcolor: alpha(rider.color, 0.14), color: rider.color, fontWeight: 700 }}>{initials(rider.name)}</Avatar>
              <Box sx={{ flex: 1, minWidth: 0 }}>
                <Typography sx={{ fontWeight: 700 }} noWrap>{rider.name}</Typography>
                <Typography variant="caption" color="text.secondary">{rider.vehicle} · {rider.vehicleNo} · Stop {index}</Typography>
              </Box>
            </Stack>
          </Paper>

        </Stack>
      </Box>

      {/* Footer */}
      <Box sx={{ p: 2, borderTop: '1px solid #E9ECEF', bgcolor: '#fff', display: 'flex', gap: 1.25, flexShrink: 0 }}>
        <Button fullWidth variant="outlined" startIcon={<CallOutlinedIcon />} href={`tel:${order.phone}`} sx={{ borderRadius: 2 }}>Call</Button>
        <Button fullWidth variant="contained" startIcon={<CheckCircleRoundedIcon />} onClick={onBack} sx={{ borderRadius: 2, bgcolor: rider.color, '&:hover': { bgcolor: rider.color } }}>Done</Button>
      </Box>
    </Box>
  );
}

// ════════════════════════════════════════════════════════════════════════════════
//  MAIN COMPONENT
// ════════════════════════════════════════════════════════════════════════════════
export default function RiderRoutes() {
  const [mode] = useState('pickup'); // pickups only
  const [visible, setVisible] = useState(() => Object.fromEntries(RIDERS.map((r) => [r.id, true])));
  const [routes, setRoutes] = useState({}); // keyed `${id}__${mode}`
  const [expanded, setExpanded] = useState(RIDERS[0].id);
  const [focusedStop, setFocusedStop] = useState(null); // `${riderId}-${index}`
  const [detail, setDetail] = useState(null);            // { order, rider, mode, index }
  const [flyTarget, setFlyTarget] = useState(null);

  // Animation state.
  const [playing, setPlaying] = useState(null);
  const [progress, setProgress] = useState(0);
  const [speed, setSpeed] = useState(1);
  const [speedAnchor, setSpeedAnchor] = useState(null);
  const rafRef = useRef(null);
  const lastTsRef = useRef(0);
  const resolvedRef = useRef({}); // keys we've already fetched/attempted

  const modeCfg = MODES[mode];

  // Resolve road routes for the active mode (cached per id+mode). A ref guards
  // against re-fetching keys we've already resolved when the tab is revisited.
  useEffect(() => {
    let cancelled = false;
    (async () => {
      await Promise.all(
        RIDERS.map(async (r) => {
          const key = `${r.id}__${mode}`;
          if (resolvedRef.current[key]) return;
          resolvedRef.current[key] = true;
          const stops = r[mode].stops;
          let path;
          try { path = await fetchRoadRoute(stops); }
          catch { path = stops.map((s) => ({ lat: s.lat, lng: s.lng })); }
          if (!cancelled) setRoutes((prev) => ({ ...prev, [key]: path }));
        })
      );
    })();
    return () => { cancelled = true; };
  }, [mode]);

  const pathFor = useCallback(
    (r) => routes[`${r.id}__${mode}`] || r[mode].stops.map((s) => ({ lat: s.lat, lng: s.lng })),
    [routes, mode]
  );

  const stopsOf = useCallback((r) => r[mode].stops, [mode]);

  // Auto-fit points = visible riders' stops for the active mode.
  const fitPoints = useMemo(() => {
    const pts = [];
    RIDERS.forEach((r) => { if (visible[r.id]) stopsOf(r).forEach((s) => pts.push(s)); });
    return pts;
  }, [visible, stopsOf]);

  // ── Analysis KPIs for the active mode ─────────────────────────────────────────
  const kpi = useMemo(() => {
    let orders = 0, done = 0, fail = 0, km = 0, cod = 0, activeRiders = 0;
    RIDERS.forEach((r) => {
      const trip = r[mode];
      const orderStops = trip.stops.filter((s) => s.kind === 'order');
      if (orderStops.length) activeRiders += 1;
      orders += orderStops.length;
      done += orderStops.filter((s) => s.status === modeCfg.doneStatus).length;
      fail += orderStops.filter((s) => s.status === modeCfg.failStatus).length;
      km += trip.distanceKm;
      cod += orderStops.reduce((s, o) => s + (o.cod || 0), 0);
    });
    return { orders, done, fail, km: km.toFixed(1), cod, activeRiders };
  }, [mode, modeCfg]);

  // ── Animation driver ──────────────────────────────────────────────────────────
  useEffect(() => {
    if (!playing) { if (rafRef.current) cancelAnimationFrame(rafRef.current); return; }
    lastTsRef.current = 0;
    const DURATION = 14000;
    const tick = (ts) => {
      if (!lastTsRef.current) lastTsRef.current = ts;
      const dt = ts - lastTsRef.current;
      lastTsRef.current = ts;
      setProgress((p) => {
        const nextP = p + (dt * speed) / DURATION;
        if (nextP >= 1) { setPlaying(null); return 1; }
        return nextP;
      });
      rafRef.current = requestAnimationFrame(tick);
    };
    rafRef.current = requestAnimationFrame(tick);
    return () => { if (rafRef.current) cancelAnimationFrame(rafRef.current); };
  }, [playing, speed]);

  // Stop any animation when switching tabs.
  useEffect(() => { setPlaying(null); setProgress(0); }, [mode]);

  const startAnim = (riderId) => {
    setVisible((v) => ({ ...v, [riderId]: true }));
    if (playing === riderId) { setPlaying(null); return; }
    if (playing !== riderId) setProgress(0);
    setPlaying(riderId);
  };
  const resetAnim = () => { setPlaying(null); setProgress(0); };
  const toggleVisible = (id) => setVisible((v) => ({ ...v, [id]: !v[id] }));

  const openDetail = (rider, order, index) => {
    setDetail({ order, rider, mode, index });
    setExpanded(rider.id);
    setFocusedStop(`${rider.id}-${index}`);
    setFlyTarget({ lat: order.lat, lng: order.lng });
  };
  const closeDetail = () => { setDetail(null); setFlyTarget(null); setFocusedStop(null); };

  const playState = useMemo(() => {
    if (!playing) return null;
    const rider = RIDERS.find((r) => r.id === playing);
    const path = pathFor(rider);
    if (path.length < 2) return null;
    const totalSegs = path.length - 1;
    const exact = progress * totalSegs;
    const i = Math.min(Math.floor(exact), totalSegs - 1);
    const frac = exact - i;
    const pos = lerpPoint(path[i], path[i + 1], frac);
    const travelled = [...path.slice(0, i + 1), pos];
    return { rider, path, travelled, pos };
  }, [playing, progress, pathFor]);

  return (
    <Box sx={{ pt: { xs: 1, md: 1 }, pb: 1 }}>
      {/* ── Header ── */}
      <Stack direction={{ xs: 'column', md: 'row' }} justifyContent="space-between" alignItems={{ md: 'center' }} gap={1} mb={2} sx={{ mb: 2 }}>
        <Stack direction="row" alignItems="center" spacing={2.5}>
          <Avatar sx={{ bgcolor: alpha('#C01227', 0.1), color: '#C01227', width: 56, height: 56, borderRadius: 2 }}>
            <RouteOutlinedIcon sx={{ fontSize: 30 }} />
          </Avatar>
          <Box>
            <Typography variant="h4" sx={{ fontWeight: 800, letterSpacing: '-0.4px', lineHeight: 1.2 }}>Rider Routes</Typography>
            <Typography variant="body1" color="text.secondary" sx={{ fontWeight: 500 }}>
              Pickups each miler covered today open any order for full details, or press play to replay the trip.
            </Typography>
          </Box>
        </Stack>
        
      </Stack>

      {/* ── Analysis KPI strip ── */}
      <Grid container spacing={2.5} mt={4} sx={{ mb: 2 }}>
        {[
          { icon: GroupsOutlinedIcon, label: 'Active Milers', value: kpi.activeRiders, sub: `of ${RIDERS.length}`, color: '#1A73E8', bg: '#E8F0FE' },
          { icon: modeCfg.icon, label: modeCfg.label, value: kpi.orders, sub: 'pickups covered', color: '#C01227', bg: alpha('#C01227', 0.1) },
          { icon: CheckCircleRoundedIcon, label: modeCfg.doneLabel, value: kpi.done, sub: `${kpi.fail} missed`, color: '#1E8E3E', bg: '#E6F4EA' },
          { icon: StraightenRoundedIcon, label: 'Distance', value: `${kpi.km} km`, sub: 'fleet total today', color: '#8E24AA', bg: '#F3E5F5' },
        ].map((k, i) => (
          <Grid item xs={6} sm={6} md={3} key={i}><KpiCard {...k} /></Grid>
        ))}
      </Grid>

      <Box sx={{ display: 'flex', flexDirection: { xs: 'column', lg: 'row' }, gap: 3, pb: 4 }}>
        {/* ── Left control panel — the milers list; clicking an order opens the
               full detail in a right-side drawer (below). ── */}
        <Box sx={{ width: { xs: '100%', lg: 380 }, flexShrink: 0 }}>
          <Card sx={{ borderRadius: 2, border: '1px solid #ECEEF1', boxShadow: '0 4px 20px rgba(0,0,0,0.04)' }}>
            <Box sx={{ px: 3, py: 2.25, borderBottom: '1px solid #F1F3F5', display: 'flex', alignItems: 'center', justifyContent: 'space-between' }}>
              <Typography sx={{ fontWeight: 700 }}>Milers &amp; their {modeCfg.label.toLowerCase()}</Typography>
              {(playing || progress > 0) && (
                <Button size="small" startIcon={<ReplayRoundedIcon />} onClick={resetAnim} sx={{ textTransform: 'none', color: '#5F6368' }}>Reset</Button>
              )}
            </Box>

            <List disablePadding sx={{ maxHeight: { lg: 620 }, overflow: 'auto' }}>
              {RIDERS.map((rider) => {
                const trip = rider[mode];
                const orders = trip.stops.filter((s) => s.kind === 'order');
                const done = orders.filter((o) => o.status === modeCfg.doneStatus).length;
                const isOpen = expanded === rider.id;
                const isPlaying = playing === rider.id;
                const isVisible = visible[rider.id];
                return (
                  <Box key={rider.id} sx={{ borderBottom: '1px solid #F4F5F7' }}>
                    <Box sx={{ display: 'flex', alignItems: 'center', px: 2, py: 1.5, gap: 1, opacity: isVisible ? 1 : 0.5 }}>
                      <Box sx={{ width: 6, height: 40, borderRadius: 2, bgcolor: rider.color, flexShrink: 0 }} />
                      <Avatar sx={{ width: 38, height: 38, bgcolor: alpha(rider.color, 0.12), color: rider.color, fontWeight: 700, fontSize: 14 }}>{initials(rider.name)}</Avatar>
                      <ListItemButton disableGutters onClick={() => setExpanded(isOpen ? null : rider.id)} sx={{ flex: 1, borderRadius: 2, px: 1, py: 0.5, minWidth: 0 }}>
                        <ListItemText
                          primary={<Typography sx={{ fontWeight: 700, fontSize: '0.92rem' }} noWrap>{rider.name}</Typography>}
                          secondary={<Typography variant="caption" color="text.secondary" noWrap>{done}/{orders.length} {modeCfg.doneLabel.toLowerCase()} · {trip.distanceKm} km</Typography>}
                        />
                        {isOpen ? <ExpandLessRoundedIcon sx={{ color: '#9AA0A6' }} /> : <ExpandMoreRoundedIcon sx={{ color: '#9AA0A6' }} />}
                      </ListItemButton>
                    </Box>

                    {/* per-rider stat chips (analysis) */}
                    <Stack direction="row" gap={1} flexWrap="wrap" sx={{ px: 2, pb: 1.5 }}>
                      <Chip size="small" icon={<Inventory2OutlinedIcon sx={{ fontSize: '14px !important' }} />} label={`${orders.length} ${modeCfg.label.toLowerCase()}`} sx={{ height: 24, fontWeight: 600, bgcolor: '#F1F3F5' }} />
                      <Chip size="small" icon={<CheckCircleRoundedIcon sx={{ fontSize: '14px !important', color: '#1E8E3E !important' }} />} label={done} sx={{ height: 24, fontWeight: 600, bgcolor: alpha('#1E8E3E', 0.1), color: '#1E8E3E' }} />
                      <Chip size="small" icon={<StraightenRoundedIcon sx={{ fontSize: '14px !important' }} />} label={`${trip.distanceKm} km`} sx={{ height: 24, fontWeight: 600, bgcolor: '#F1F3F5' }} />
                      <Chip size="small" icon={<AccessTimeOutlinedIcon sx={{ fontSize: '14px !important' }} />} label={`${trip.startTime}–${trip.endTime}`} sx={{ height: 24, fontWeight: 600, bgcolor: '#F1F3F5' }} />
                    </Stack>

                    {/* action row */}
                    <Stack direction="row" gap={1.25} sx={{ px: 2, pb: 2 }}>
                      <Button
                        size="small"
                        variant={isPlaying ? 'contained' : 'outlined'}
                        startIcon={isPlaying ? <PauseRoundedIcon /> : <PlayArrowRoundedIcon />}
                        onClick={() => startAnim(rider.id)}
                        sx={{
                          textTransform: 'none', fontWeight: 600, borderRadius: 2, flex: 1,
                          ...(isPlaying
                            ? { bgcolor: rider.color, '&:hover': { bgcolor: rider.color } }
                            : { color: rider.color, borderColor: alpha(rider.color, 0.5), '&:hover': { borderColor: rider.color, bgcolor: alpha(rider.color, 0.06) } }),
                        }}
                      >
                        {isPlaying ? 'Playing…' : 'Animate route'}
                      </Button>
                      <Tooltip title={isVisible ? 'Hide route' : 'Show route'}>
                        <IconButton size="small" onClick={() => toggleVisible(rider.id)} sx={{ border: '1px solid #E9ECEF', borderRadius: 2 }}>
                          {isVisible ? <VisibilityOutlinedIcon fontSize="small" /> : <VisibilityOffOutlinedIcon fontSize="small" />}
                        </IconButton>
                      </Tooltip>
                    </Stack>

                    {isPlaying && (
                      <Box sx={{ px: 2, pb: 1.5 }}>
                        <LinearProgress variant="determinate" value={progress * 100} sx={{ height: 6, borderRadius: 2, bgcolor: '#EDEFF2', '& .MuiLinearProgress-bar': { bgcolor: rider.color, borderRadius: 2 } }} />
                      </Box>
                    )}

                    {/* expandable stops — rich order cards; click to open detail */}
                    <Collapse in={isOpen} unmountOnExit>
                      <Box sx={{ px: 2, pb: 2, pt: 0.5 }}>
                        <Stack spacing={1.25}>
                          {trip.stops.map((s, i) => {
                            const key = `${rider.id}-${i}`;
                            const isHub = s.kind === 'hub';
                            const meta = STATUS_META[s.status];
                            const StatusIcon = meta?.icon;

                            // Hub return — compact row, not a card.
                            if (isHub) {
                              return (
                                <Stack key={key} direction="row" alignItems="center" gap={1.25} sx={{ px: 0.5, py: 0.5 }}>
                                  <Box sx={{ width: 28, height: 28, borderRadius: 2, flexShrink: 0, bgcolor: alpha('#C01227', 0.12), color: '#C01227', display: 'flex', alignItems: 'center', justifyContent: 'center' }}>
                                    <WarehouseRoundedIcon sx={{ fontSize: 16 }} />
                                  </Box>
                                  <Box sx={{ minWidth: 0 }}>
                                    <Typography sx={{ fontWeight: 700, fontSize: '0.82rem' }} noWrap>{s.label}</Typography>
                                    <Typography variant="caption" color="text.secondary">Back to hub · {s.time}</Typography>
                                  </Box>
                                </Stack>
                              );
                            }

                            return (
                              <Box
                                key={key}
                                onMouseEnter={() => setFocusedStop(key)}
                                onMouseLeave={() => setFocusedStop((f) => (f === key ? null : f))}
                                onClick={() => openDetail(rider, s, i)}
                                sx={{
                                  p: 1.5, borderRadius: 2, cursor: 'pointer', transition: 'all .15s',
                                  border: '1px solid', borderColor: focusedStop === key ? alpha(rider.color, 0.55) : '#ECEEF1',
                                  bgcolor: focusedStop === key ? alpha(rider.color, 0.04) : '#fff',
                                  boxShadow: '0 1px 3px rgba(0,0,0,0.03)',
                                  '&:hover': { borderColor: alpha(rider.color, 0.55), boxShadow: '0 4px 14px rgba(0,0,0,0.07)' },
                                }}
                              >
                                {/* order id + status */}
                                <Stack direction="row" alignItems="center" justifyContent="space-between" gap={1}>
                                  <Stack direction="row" alignItems="center" gap={1} sx={{ minWidth: 0 }}>
                                    <Box sx={{ width: 26, height: 26, borderRadius: 2, flexShrink: 0, bgcolor: alpha(rider.color, 0.14), color: rider.color, display: 'flex', alignItems: 'center', justifyContent: 'center', fontWeight: 800, fontSize: 12 }}>{i}</Box>
                                    <Typography sx={{ fontWeight: 700, fontSize: '0.82rem' }} noWrap>
                                      <Box component="span" sx={{ color: '#9AA0A6', fontWeight: 600 }}>Order </Box>#{s.orderId}
                                    </Typography>
                                  </Stack>
                                  {meta && (
                                    <Chip size="small" icon={<StatusIcon sx={{ fontSize: '14px !important', color: `${meta.color} !important` }} />} label={meta.label}
                                      sx={{ height: 22, fontSize: '0.68rem', fontWeight: 700, color: meta.color, bgcolor: alpha(meta.color, 0.1), flexShrink: 0 }} />
                                  )}
                                </Stack>

                                {/* rider + time */}
                                <Stack direction="row" alignItems="center" justifyContent="space-between" gap={1} sx={{ mt: 1 }}>
                                  <Stack direction="row" alignItems="center" gap={0.75} sx={{ minWidth: 0 }}>
                                    <DeliveryDiningRoundedIcon sx={{ fontSize: 16, color: '#9AA0A6', flexShrink: 0 }} />
                                    <Typography variant="caption" sx={{ fontWeight: 600, color: '#5F6368' }} noWrap>{rider.name}</Typography>
                                  </Stack>
                                  <Stack direction="row" alignItems="center" gap={0.5} sx={{ flexShrink: 0 }}>
                                    <AccessTimeOutlinedIcon sx={{ fontSize: 14, color: '#9AA0A6' }} />
                                    <Typography variant="caption" sx={{ fontWeight: 600, color: '#5F6368' }}>{s.time}</Typography>
                                  </Stack>
                                </Stack>

                                <Divider sx={{ my: 1.25 }} />

                                {/* merchant + address */}
                                <Stack direction="row" alignItems="center" gap={0.75}>
                                  <StorefrontOutlinedIcon sx={{ fontSize: 16, color: rider.color, flexShrink: 0 }} />
                                  <Typography sx={{ fontWeight: 700, fontSize: '0.82rem' }} noWrap>{s.customer}</Typography>
                                </Stack>
                                <Stack direction="row" alignItems="flex-start" gap={0.75} sx={{ mt: 0.5 }}>
                                  <PlaceOutlinedIcon sx={{ fontSize: 16, color: '#9AA0A6', flexShrink: 0, mt: '1px' }} />
                                  <Typography variant="caption" color="text.secondary" noWrap sx={{ flex: 1, minWidth: 0 }}>{s.address}</Typography>
                                </Stack>

                                {/* metric chips */}
                                <Stack direction="row" gap={0.75} flexWrap="wrap" sx={{ mt: 1.25 }}>
                                  <Chip size="small" icon={<StraightenRoundedIcon sx={{ fontSize: '13px !important' }} />} label={`${s.legKm} km`} sx={{ height: 22, fontSize: '0.68rem', fontWeight: 600, bgcolor: '#F1F3F5' }} />
                                  <Chip size="small" icon={<ScaleOutlinedIcon sx={{ fontSize: '13px !important' }} />} label={s.weight} sx={{ height: 22, fontSize: '0.68rem', fontWeight: 600, bgcolor: '#F1F3F5' }} />
                                  <Chip size="small" icon={<Inventory2OutlinedIcon sx={{ fontSize: '13px !important' }} />} label={`${s.items} ${s.items === 1 ? 'parcel' : 'parcels'}`} sx={{ height: 22, fontSize: '0.68rem', fontWeight: 600, bgcolor: '#F1F3F5' }} />
                                </Stack>
                              </Box>
                            );
                          })}
                        </Stack>
                      </Box>
                    </Collapse>
                  </Box>
                );
              })}
            </List>
          </Card>
        </Box>

        {/* ── Map ── */}
        <Box sx={{ flex: 1, minWidth: 0 }}>
          <Card sx={{ height: { xs: 460, sm: 560, lg: 700 }, borderRadius: 2, border: '1px solid #ECEEF1', overflow: 'hidden', position: 'relative', boxShadow: '0 4px 20px rgba(0,0,0,0.04)' }}>
            {playState && (
              <Box sx={{ position: 'absolute', top: 14, left: 14, zIndex: 1000, minWidth: 230, bgcolor: 'rgba(255,255,255,0.97)', borderRadius: 2, p: 1.75, boxShadow: '0 8px 28px rgba(0,0,0,0.14)', border: `1px solid ${alpha(playState.rider.color, 0.3)}` }}>
                <Stack direction="row" alignItems="center" spacing={1.25} mb={1}>
                  <Avatar sx={{ width: 30, height: 30, bgcolor: playState.rider.color, fontSize: 12, fontWeight: 700 }}>{initials(playState.rider.name)}</Avatar>
                  <Box sx={{ flex: 1, minWidth: 0 }}>
                    <Typography sx={{ fontWeight: 700, fontSize: '0.85rem' }} noWrap>{playState.rider.name}</Typography>
                    <Typography variant="caption" color="text.secondary">Replaying {modeCfg.label.toLowerCase().replace(/s$/, '')} · {Math.round(progress * 100)}%</Typography>
                  </Box>
                  <IconButton size="small" onClick={() => setPlaying(null)}><PauseRoundedIcon fontSize="small" /></IconButton>
                  <Tooltip title="Speed"><IconButton size="small" onClick={(e) => setSpeedAnchor(e.currentTarget)}><SpeedRoundedIcon fontSize="small" /></IconButton></Tooltip>
                </Stack>
                <LinearProgress variant="determinate" value={progress * 100} sx={{ height: 6, borderRadius: 2, bgcolor: '#EDEFF2', '& .MuiLinearProgress-bar': { bgcolor: playState.rider.color, borderRadius: 2 } }} />
              </Box>
            )}
            <Menu anchorEl={speedAnchor} open={Boolean(speedAnchor)} onClose={() => setSpeedAnchor(null)}>
              {[0.5, 1, 2, 4].map((s) => (<MenuItem key={s} selected={speed === s} onClick={() => { setSpeed(s); setSpeedAnchor(null); }}>{s}× speed</MenuItem>))}
            </Menu>

            <MapContainer center={[HUB.lat, HUB.lng]} zoom={11} scrollWheelZoom style={{ height: '100%', width: '100%' }}>
              <MapResizeHandler />
              {!playing && !flyTarget && <FitBounds points={fitPoints} />}
              <FlyTo target={flyTarget} />
              <TileLayer
                url="https://{s}.basemaps.cartocdn.com/rastertiles/voyager/{z}/{x}/{y}{r}.png"
                attribution='&copy; <a href="https://www.openstreetmap.org/copyright">OpenStreetMap</a> contributors &copy; <a href="https://carto.com/attributions">CARTO</a>'
              />

              <Marker position={[HUB.lat, HUB.lng]} icon={hubIcon}>
                <Popup><b>{HUB.label}</b><br />Pickups return here</Popup>
              </Marker>

              {RIDERS.map((rider) => {
                if (!visible[rider.id]) return null;
                const path = pathFor(rider);
                const stops = stopsOf(rider);
                const dimmed = playing && playing !== rider.id;
                const endStop = stops[stops.length - 1];
                return (
                  <React.Fragment key={rider.id}>
                    <Polyline positions={path.map((p) => [p.lat, p.lng])} pathOptions={{ color: rider.color, weight: 5, opacity: dimmed ? 0.15 : 0.85, dashArray: modeCfg.dash }} />
                    {stops.map((s, i) => {
                      if (s.kind === 'hub') return null;
                      const key = `${rider.id}-${i}`;
                      return (
                        <Marker
                          key={key}
                          position={[s.lat, s.lng]}
                          icon={stopIcon(i, rider.color, focusedStop === key, mode === 'pickup')}
                          opacity={dimmed ? 0.3 : 1}
                          zIndexOffset={focusedStop === key ? 1000 : 0}
                          eventHandlers={{ click: () => openDetail(rider, s, i) }}
                        >
                          <Popup>
                            <Typography variant="subtitle2" sx={{ fontWeight: 700 }}>{modeCfg.pointLabel} {i} · {s.customer}</Typography>
                            <Typography variant="caption" display="block">{s.address}</Typography>
                            <Typography variant="caption" display="block">#{s.orderId} · {s.time} · {STATUS_META[s.status]?.label}</Typography>
                            <Typography variant="caption" display="block" sx={{ color: rider.color, fontWeight: 700, cursor: 'pointer' }} onClick={() => openDetail(rider, s, i)}>View full details →</Typography>
                          </Popup>
                        </Marker>
                      );
                    })}
                    {!dimmed && (
                      <Marker position={[endStop.lat, endStop.lng]} icon={flagIcon} zIndexOffset={-100}>
                        <LTooltip direction="top" offset={[0, -14]}>{mode === 'pickup' ? 'Returned to hub' : 'Trip end'} · {rider[mode].endTime}</LTooltip>
                      </Marker>
                    )}
                  </React.Fragment>
                );
              })}

              {playState && (
                <>
                  <Polyline positions={playState.travelled.map((p) => [p.lat, p.lng])} pathOptions={{ color: playState.rider.color, weight: 7, opacity: 1 }} />
                  <Marker position={[playState.pos.lat, playState.pos.lng]} icon={moverIcon(playState.rider.color)} zIndexOffset={2000}>
                    <LTooltip direction="top" offset={[0, -16]} permanent>{playState.rider.name}</LTooltip>
                  </Marker>
                </>
              )}
            </MapContainer>
          </Card>

          {/* Legend */}
          <Stack direction="row" flexWrap="wrap" gap={2} sx={{ mt: 2 }}>
            {RIDERS.map((r) => (
              <Stack key={r.id} direction="row" alignItems="center" gap={0.75} sx={{ opacity: visible[r.id] ? 1 : 0.4, cursor: 'pointer' }} onClick={() => toggleVisible(r.id)}>
                <Box sx={{ width: 18, height: 4, borderRadius: 2, bgcolor: r.color }} />
                <Typography variant="caption" sx={{ fontWeight: 600, color: '#5F6368' }}>{r.name}</Typography>
              </Stack>
            ))}
            <Box sx={{ flex: 1 }} />
            <Stack direction="row" alignItems="center" gap={0.75}>
              <FlagRoundedIcon sx={{ fontSize: 16, color: '#1E8E3E' }} />
              <Typography variant="caption" sx={{ fontWeight: 600, color: '#5F6368' }}>{mode === 'pickup' ? 'Hub return' : 'Trip end'}</Typography>
            </Stack>
            <Stack direction="row" alignItems="center" gap={0.75}>
              <WarehouseRoundedIcon sx={{ fontSize: 16, color: '#C01227' }} />
              <Typography variant="caption" sx={{ fontWeight: 600, color: '#5F6368' }}>Hub</Typography>
            </Stack>
          </Stack>
        </Box>
      </Box>

      {/* ── Order detail — right-side drawer ── */}
      <Drawer
        anchor="right"
        open={Boolean(detail)}
        onClose={closeDetail}
        sx={{
          '& .MuiDrawer-paper': {
            width: { xs: '100%', sm: 360 },
            maxWidth: '100%',
            top: { xs: 0, sm: 64 },
            height: { xs: '100%', sm: 'calc(100% - 64px)' },
            borderTopLeftRadius: { sm: 16 },
            overflow: 'hidden',
            boxShadow: '-8px 0 30px rgba(0,0,0,0.12)',
          },
        }}
      >
        {detail && <OrderDetailPanel data={detail} onBack={closeDetail} />}
      </Drawer>
    </Box>
  );
}
