import React, { useState, useEffect, useMemo, useCallback } from 'react';
import { MapContainer, TileLayer, Marker, Popup, Polyline, useMap, ZoomControl } from 'react-leaflet';
import L from 'leaflet';
import 'leaflet/dist/leaflet.css';
import dayjs from 'dayjs';
import { useInfiniteQuery } from '@tanstack/react-query';
import { MdMap, MdDirectionsBike, MdRestaurant, MdPublic } from 'react-icons/md';
import { fetchDeliveries } from '../../api/api';
import './Dispatch.css';
import { RAW_DISPATCH_DATA } from './DispatchData';

// Phosphor "motorcycle" (filled) — clean side-view bike that reads well at small sizes.
const MOTORBIKE_SVG = `<svg viewBox="0 0 256 256" xmlns="http://www.w3.org/2000/svg" aria-hidden="true"><path fill="#fff" d="M200,112a40,40,0,0,0-12.07,1.86L161.6,72H200a8,8,0,0,1,8,8v8a8,8,0,0,0,16,0V80a24,24,0,0,0-24-24H160a8,8,0,0,0-6.79,3.77l-9.34,15.06L130.39,52A8,8,0,0,0,124,48H88a8,8,0,0,0,0,16h31.69l13.34,21.84L107.5,128H56A40,40,0,1,0,96,168.4V160a8,8,0,0,1,16,0v8.4a40.06,40.06,0,0,0,32,31.2V184a8,8,0,0,1,16,0v15.6A40,40,0,1,0,200,112ZM56,184a24,24,0,1,1,24-24A24,24,0,0,1,56,184Zm70.46-44.71h0L141,116.45,156.6,142h0a40,40,0,0,0-14,28h-16A40.16,40.16,0,0,0,126.46,139.29ZM200,184a24,24,0,1,1,24-24A24,24,0,0,1,200,184Z"/></svg>`;

const STATUS_STYLES = {
  created:   { label: 'Created',   bg: '#3b82f6', fg: '#fff' },
  pending:   { label: 'Pending',   bg: '#f59e0b', fg: '#fff' },
  accepted:  { label: 'Accepted',  bg: '#8b5cf6', fg: '#fff' },
  arrived:   { label: 'Arrived',   bg: '#ea580c', fg: '#fff' },
  picked:    { label: 'Picked',    bg: '#0ea5e9', fg: '#fff' },
  active:    { label: 'Active',    bg: '#0ea5e9', fg: '#fff' },
  delivered: { label: 'Delivered', bg: '#22c55e', fg: '#fff' },
  skipped:   { label: 'Skipped',   bg: '#94a3b8', fg: '#fff' },
  cancelled: { label: 'Cancelled', bg: '#ef4444', fg: '#fff' }
};

const getStatusStyle = (status) =>
  STATUS_STYLES[String(status || '').toLowerCase()] || { label: status || 'Unknown', bg: '#64748b', fg: '#fff' };

const toNum = (v) => {
  const n = parseFloat(v);
  return Number.isFinite(n) ? n : NaN;
};

const hasValidDrop = (o) => Number.isFinite(toNum(o.droplat || o.deliverylat)) && Number.isFinite(toNum(o.droplon || o.deliverylong));
const hasValidPickup = (o) => Number.isFinite(toNum(o.pickuplat)) && Number.isFinite(toNum(o.pickuplong));

// Batch buckets by expected delivery time-of-day (operator's mental model — morning rush,
// lunch wave, dinner wave). Anything outside a window OR with no parsable time falls under "all".
const BATCHES = [
  // { id: 'all', label: 'All', icon: '🍽️' }, // hidden for now — restore for an unfiltered view
  { id: 'morning', label: 'Morning', icon: '🌅' },
  { id: 'lunch',   label: 'Lunch',   icon: '🍱' },
  { id: 'dinner',  label: 'Dinner',  icon: '🌙' }
];

const getRowBatch = (r) => {
  const t = r.expecteddeliverytime || r.deliverydate || r.pickupslot;
  if (!t) return null;
  const d = dayjs(t);
  if (!d.isValid()) return null;
  const h = d.hour() + d.minute() / 60;
  if (h < 10.5) return 'morning';
  if (h < 15) return 'lunch';
  return 'dinner';
};

const FINAL_STATUSES = new Set(['delivered']);
const SKIPPED_STATUSES = new Set(['cancelled', 'skipped']);

// Compute one "live position" per rider: midpoint between the last delivered drop and the next non-final drop.
// If nothing delivered yet, midpoint is kitchen pickup → first drop. If all delivered, returns null.
const computeRiderPosition = (r) => {
  const sorted = [...r.orders].sort((a, b) => {
    const tA = a.trip_number || 1;
    const tB = b.trip_number || 1;
    if (tA !== tB) return tA - tB;
    return (a.step || 0) - (b.step || 0);
  });

  const nextIdx = sorted.findIndex((o) => {
    const s = String(o.orderstatus || '').toLowerCase();
    return !FINAL_STATUSES.has(s) && !SKIPPED_STATUSES.has(s);
  });
  if (nextIdx === -1) return null;

  const next = sorted[nextIdx];
  if (!hasValidDrop(next)) return null;
  const nextLat = toNum(next.droplat || next.deliverylat);
  const nextLon = toNum(next.droplon || next.deliverylong);

  // Pick the previous reference point: previous order's drop if available, else this order's pickup (kitchen).
  let prevLat;
  let prevLon;
  const prev = nextIdx > 0 ? sorted[nextIdx - 1] : null;
  if (prev && hasValidDrop(prev)) {
    prevLat = toNum(prev.droplat || prev.deliverylat);
    prevLon = toNum(prev.droplon || prev.deliverylong);
  } else if (hasValidPickup(next)) {
    prevLat = toNum(next.pickuplat);
    prevLon = toNum(next.pickuplong);
  } else {
    return null;
  }

  const aerialLat = (prevLat + nextLat) / 2;
  const aerialLon = (prevLon + nextLon) / 2;

  const completedCount = sorted.filter((o) => FINAL_STATUSES.has(String(o.orderstatus || '').toLowerCase())).length;

  return {
    id: r.id,
    color: r.color,
    riderName: r.riderName,
    aerialLat,
    aerialLon,
    prevLat,
    prevLon,
    nextLat,
    nextLon,
    completedCount,
    totalCount: sorted.length,
    nextStep: next.step || nextIdx + 1,
    nextCustomer: next.deliverycustomer || ''
  };
};

// Walk a polyline and return the [lat,lon] point at half the total length.
// Uses planar distance — fine at city scale and avoids a haversine import.
const polylineMidpoint = (points) => {
  if (!points || points.length < 2) return null;
  const segLens = [];
  let total = 0;
  for (let i = 0; i < points.length - 1; i++) {
    const dx = points[i + 1][0] - points[i][0];
    const dy = points[i + 1][1] - points[i][1];
    const d = Math.sqrt(dx * dx + dy * dy);
    segLens.push(d);
    total += d;
  }
  if (total === 0) return points[0];
  const target = total / 2;
  let acc = 0;
  for (let i = 0; i < segLens.length; i++) {
    if (acc + segLens[i] >= target) {
      const t = (target - acc) / segLens[i];
      return [
        points[i][0] + t * (points[i + 1][0] - points[i][0]),
        points[i][1] + t * (points[i + 1][1] - points[i][1])
      ];
    }
    acc += segLens[i];
  }
  return points[points.length - 1];
};

// Build a polyline-ready point list for a sorted trip:
//   - drop NaN drops
//   - prepend the first valid pickup we can find (so the line starts at the kitchen)
const buildTripPoints = (sorted) => {
  const valid = sorted.filter(hasValidDrop);
  if (!valid.length) return [];
  const pickupSrc = sorted.find(hasValidPickup);
  const pts = [];
  if (pickupSrc) pts.push([toNum(pickupSrc.pickuplat), toNum(pickupSrc.pickuplong)]);
  valid.forEach((o) => pts.push([toNum(o.droplat || o.deliverylat), toNum(o.droplon || o.deliverylong)]));
  return pts;
};

// Fix for default leaflet marker icons
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',
});

const RIDER_COLORS = ['#0055FF', '#00D82C', '#FF6B00', '#9D00FF', '#FF00A8', '#00C2B2', '#FF9900', '#FF0000'];

const MapController = ({ focusedItem, viewMode, orders }) => {
  const map = useMap();

  useEffect(() => {
    let pts = [];
    if (focusedItem) {
      if (focusedItem.orders) {
        pts = focusedItem.orders.map(o => [parseFloat(o.droplat || o.deliverylat), parseFloat(o.droplon || o.deliverylong)]);
        focusedItem.orders.forEach(o => pts.push([parseFloat(o.pickuplat), parseFloat(o.pickuplong)]));
      } else {
        pts = [[focusedItem.lat, focusedItem.lon]];
      }
    } else if (viewMode === 'all') {
      pts = orders.map(o => [parseFloat(o.droplat || o.deliverylat), parseFloat(o.droplon || o.deliverylong)]);
    }

    if (pts.length > 0) {
      const filtered = pts.filter(p => !isNaN(p[0]) && !isNaN(p[1]));
      if (filtered.length > 0) {
        const bounds = L.latLngBounds(filtered);
        if (bounds.isValid()) {
          map.fitBounds(bounds, { padding: [50, 50], animate: true });
        }
      }
    } else {
      map.setView([11.022, 76.982], 12, { animate: true });
    }
  }, [focusedItem, viewMode, orders, map]);

  return null;
};

const Dispatch = ({
  data,
  embedded = false,
  // Controlled focus: when selectedRiderId is defined, the focused rider is derived from prop
  // and clicks inside Dispatch only fire onRiderSelect (parent owns the state). When undefined,
  // Dispatch falls back to its internal focusedRider state (standalone /dispatch behavior).
  selectedRiderId,
  onRiderSelect,
  // Highlight a single marker (e.g. on table-row hover). Adds a `.pulse` class to that cmark.
  pulseOrderId
}) => {
  // Default to "By Zone" when the caller passes pre-zoned data (AI preview); fall back to
  // "By Rider" for the standalone live page where zones are synthesized but riders are primary.
  const initialViewMode = data?.zones && data.zones.length > 0 ? 'zones' : 'riders';
  const [viewMode, setViewMode] = useState(initialViewMode);
  const [activeRiders, setActiveRiders] = useState(new Set());
  const [internalFocusedRider, setInternalFocusedRider] = useState(null);
  const [focusedKitchen, setFocusedKitchen] = useState(null);
  const [focusedZone, setFocusedZone] = useState(null);
  const isControlled = selectedRiderId !== undefined;
  const [clock, setClock] = useState('');
  const [osrmRoutes, setOsrmRoutes] = useState({});
  const [isAnimating, setIsAnimating] = useState(false);
  const [animatedSegments, setAnimatedSegments] = useState([]);
  const [selectedDate, setSelectedDate] = useState(dayjs().format('YYYY-MM-DD'));
  const [selectedBatch, setSelectedBatch] = useState('morning');

  // Live deliveries query — runs only when no `data` prop is passed (i.e., standalone page).
  const shouldFetchLive = !data;
  const liveUserid = typeof window !== 'undefined' ? localStorage.getItem('userid') || 0 : 0;

  const {
    data: livePagesData,
    isFetching: liveIsFetching,
    isError: liveIsError,
    fetchNextPage: liveFetchNextPage,
    hasNextPage: liveHasNextPage,
    isFetchingNextPage: liveIsFetchingNextPage
  } = useInfiniteQuery({
    queryKey: ['dispatchDeliveries', 0, liveUserid, 'all', selectedDate, selectedDate, 50, '', 0, 0, 0],
    queryFn: fetchDeliveries,
    getNextPageParam: (lastPage) => lastPage.nextPage ?? undefined,
    enabled: shouldFetchLive
  });

  // Auto-page through all results for the selected date.
  useEffect(() => {
    if (!shouldFetchLive) return;
    if (liveHasNextPage && !liveIsFetchingNextPage) liveFetchNextPage();
  }, [shouldFetchLive, liveHasNextPage, liveIsFetchingNextPage, liveFetchNextPage]);

  const liveRows = useMemo(
    () => (livePagesData?.pages || []).flatMap((p) => p.rows || []),
    [livePagesData]
  );

  // Per-batch counts shown on the batch selector pills (uses unfiltered rows so counts stay
  // visible even when a single batch is active).
  const batchCounts = useMemo(() => {
    const counts = { all: liveRows.length, morning: 0, lunch: 0, dinner: 0 };
    liveRows.forEach((r) => {
      const b = getRowBatch(r);
      if (b) counts[b] += 1;
    });
    return counts;
  }, [liveRows]);

  // Apply the batch filter before grouping so zones/riders/bikes all reflect the chosen wave.
  const filteredLiveRows = useMemo(() => {
    if (selectedBatch === 'all') return liveRows;
    return liveRows.filter((r) => getRowBatch(r) === selectedBatch);
  }, [liveRows, selectedBatch]);

  // Reshape flat delivery rows into the zones/riders/orders structure Dispatch consumes.
  const liveData = useMemo(() => {
    if (!shouldFetchLive) return null;
    if (!filteredLiveRows.length) return { code: 200, zone_summary: [], zones: [] };

    const zoneBuckets = {};
    filteredLiveRows.forEach((r) => {
      const zoneName = r.zone_name || 'All Orders';
      const riderKey = String(r.userid || r.rider_id || 'unassigned');
      const riderName = r.ridername || r.rider_name || r.username || (riderKey === 'unassigned' ? 'Unassigned' : `Rider ${riderKey}`);

      if (!zoneBuckets[zoneName]) zoneBuckets[zoneName] = { zone_name: zoneName, riders: {} };
      if (!zoneBuckets[zoneName].riders[riderKey]) {
        zoneBuckets[zoneName].riders[riderKey] = { rider_id: riderKey, rider_name: riderName, orders: [] };
      }
      zoneBuckets[zoneName].riders[riderKey].orders.push(r);
    });

    const zones = Object.values(zoneBuckets).map((z) => {
      const riders = Object.values(z.riders).map((rd) => {
        const sorted = [...rd.orders].sort((a, b) =>
          dayjs(a.deliverydate || a.assigntime || 0).valueOf() - dayjs(b.deliverydate || b.assigntime || 0).valueOf()
        );
        return {
          ...rd,
          orders: sorted.map((o, idx) => ({
            ...o,
            trip_number: o.trip_number || 1,
            step: o.step || idx + 1
          }))
        };
      });
      return { zone_name: z.zone_name, riders };
    });

    const zone_summary = zones.map((z) => {
      const allOrds = z.riders.flatMap((r) => r.orders);
      const assigned = allOrds.filter((o) => o.userid || o.rider_id).length;
      return {
        zone_name: z.zone_name,
        total_orders: allOrds.length,
        assigned_orders: assigned,
        unassigned_orders_count: allOrds.length - assigned,
        active_riders_count: z.riders.filter((r) => r.rider_id !== 'unassigned').length,
        total_delivery_kms: allOrds.reduce((s, o) => s + parseFloat(o.actualkms || o.kms || 0), 0),
        total_profit: allOrds.reduce((s, o) => s + parseFloat(o.profit || 0), 0)
      };
    });

    return { code: 200, zone_summary, zones };
  }, [shouldFetchLive, filteredLiveRows]);

  // Merge each zone's per-rider data with its summary metrics for sidebar rendering.
  // Also derive aggregates the AI response doesn't pre-compute: which suburbs the zone
  // delivers to, which kitchens it picks up from, and the order-status breakdown.
  const zoneCards = useMemo(() => {
    const source = data || liveData || RAW_DISPATCH_DATA;
    const zonesArr = source.zones || [];
    const summaryByName = {};
    (source.zone_summary || []).forEach((s) => { summaryByName[s.zone_name] = s; });

    const tally = (arr, keyFn) => {
      const m = {};
      arr.forEach((o) => {
        const k = keyFn(o);
        if (!k) return;
        m[k] = (m[k] || 0) + 1;
      });
      return Object.entries(m)
        .map(([name, count]) => ({ name, count }))
        .sort((a, b) => b.count - a.count);
    };

    return zonesArr.map((z) => {
      const summary = summaryByName[z.zone_name] || {};
      const allOrders = (z.riders || []).flatMap((r) => r.orders || []);
      const activeRiderCount = (z.riders || []).filter((r) => r.rider_id && r.rider_id !== 'unassigned').length;

      const suburbs = tally(allOrders, (o) => o.deliverysuburb || o.locationsuburb);
      const kitchens = tally(allOrders, (o) => o.pickupcustomer || o.kitchen_key);
      const statusCounts = {};
      allOrders.forEach((o) => {
        const s = String(o.orderstatus || 'unknown').toLowerCase();
        statusCounts[s] = (statusCounts[s] || 0) + 1;
      });

      return {
        id: z.zone_name,
        name: z.zone_name,
        riders: z.riders || [],
        orders: allOrders,
        totalOrders: summary.total_orders ?? allOrders.length,
        activeRidersCount: summary.active_riders_count ?? activeRiderCount,
        totalKms: summary.total_delivery_kms ?? allOrders.reduce((s, o) => s + parseFloat(o.actualkms || o.kms || 0), 0),
        totalProfit: summary.total_profit ?? allOrders.reduce((s, o) => s + parseFloat(o.profit || 0), 0),
        suburbs,
        kitchens,
        statusCounts
      };
    });
  }, [data, liveData]);

  // Data processing logic
  const { riders, kitchens, allOrders, stats } = useMemo(() => {
    const source = data || liveData || RAW_DISPATCH_DATA;
    const orders = [];
    (source.zones || []).forEach(z => {
      (z.riders || []).forEach(r => {
        r.orders.forEach(o => {
          orders.push({ ...o, zone_name: z.zone_name, rider_name: r.rider_name, rider_id: r.rider_id });
        });
      });
    });

    const riderMap = {};
    orders.forEach(o => {
      const key = o.rider_id || o.userid || 'unknown';
      if (!riderMap[key]) {
        riderMap[key] = {
          id: key,
          riderName: o.rider_name || o.username || o.rider || key,
          orders: [],
          color: RIDER_COLORS[Object.keys(riderMap).length % RIDER_COLORS.length]
        };
      }
      riderMap[key].orders.push(o);
    });

    const kitchenMap = {};
    orders.forEach(o => {
      const name = o.pickupcustomer || o.kitchen_key || 'Unknown';
      const key = name.toLowerCase().trim();
      if (!kitchenMap[key]) {
        kitchenMap[key] = {
          id: key,
          kitchenName: name,
          lat: toNum(o.pickuplat),
          lon: toNum(o.pickuplong),
          orders: [],
          riders: new Set()
        };
      } else if (!Number.isFinite(kitchenMap[key].lat) && hasValidPickup(o)) {
        // Upgrade to first valid pickup coords we see for this kitchen
        kitchenMap[key].lat = toNum(o.pickuplat);
        kitchenMap[key].lon = toNum(o.pickuplong);
      }
      kitchenMap[key].orders.push(o);
      if (o.rider_id) kitchenMap[key].riders.add(o.rider_id);
    });

    const totalKms = orders.reduce((s, o) => s + parseFloat(o.actualkms || o.kms || 0), 0);
    const totalProfit = orders.reduce((s, o) => s + parseFloat(o.profit || 0), 0);

    // Sort each rider's orders by (trip_number, step) so every downstream view —
    // sidebar step list, step-id badges on the card, OSRM trip points, animation —
    // sees them in delivery order 1→N.
    const sortedRiders = Object.values(riderMap).map((r) => ({
      ...r,
      orders: [...r.orders].sort((a, b) => {
        const tA = a.trip_number || 1;
        const tB = b.trip_number || 1;
        if (tA !== tB) return tA - tB;
        return (a.step || 0) - (b.step || 0);
      })
    }));

    return {
      riders: sortedRiders.sort((a, b) => b.orders.length - a.orders.length),
      kitchens: Object.values(kitchenMap).sort((a, b) => b.orders.length - a.orders.length),
      allOrders: orders,
      stats: {
        totalOrders: orders.length,
        totalKms,
        totalProfit,
        totalRiders: Object.keys(riderMap).length
      }
    };
  }, [data, liveData]);

  // Resolve focusedRider: prop-derived when controlled, local state otherwise.
  const focusedRider = isControlled
    ? (selectedRiderId ? (riders.find((r) => r.id === selectedRiderId) || null) : null)
    : internalFocusedRider;

  // Single setter used by every interactive site in the UI. In uncontrolled mode it
  // updates local state; in controlled mode it only notifies the parent.
  const handleRiderFocus = useCallback(
    (r) => {
      if (onRiderSelect) onRiderSelect(r ? r.id : null);
      if (!isControlled) setInternalFocusedRider(r);
    },
    [isControlled, onRiderSelect]
  );

  const activeStats = useMemo(() => {
    if (focusedRider) {
      return {
        orders: focusedRider.orders.length,
        riders: 1,
        km: focusedRider.orders.reduce((s, o) => s + parseFloat(o.actualkms || o.kms || 0), 0),
        profit: focusedRider.orders.reduce((s, o) => s + parseFloat(o.profit || 0), 0),
        label: 'Focused Rider'
      };
    }
    if (focusedKitchen) {
      return {
        orders: focusedKitchen.orders.length,
        riders: focusedKitchen.riders.size,
        km: focusedKitchen.orders.reduce((s, o) => s + parseFloat(o.actualkms || o.kms || 0), 0),
        profit: focusedKitchen.orders.reduce((s, o) => s + parseFloat(o.profit || 0), 0),
        label: 'Focused Kitchen'
      };
    }
    return {
      orders: stats.totalOrders,
      riders: stats.totalRiders,
      km: stats.totalKms,
      profit: stats.totalProfit,
      label: 'Total Fleet'
    };
  }, [focusedRider, focusedKitchen, stats]);

  // Live rider positions (Rapido-style bikes on the map)
  const riderPositions = useMemo(() => riders.map(computeRiderPosition).filter(Boolean), [riders]);

  const fetchRoute = useCallback(async (riderId, tripKey, points) => {
    const cacheKey = `${riderId}-${tripKey}`;
    if (osrmRoutes[cacheKey]) return;
    if (points.length < 2) return;

    const coords = points.map(p => `${p[1]},${p[0]}`).join(';');
    const url = `https://router.project-osrm.org/route/v1/driving/${coords}?overview=full&geometries=geojson`;

    try {
      const res = await fetch(url);
      const data = await res.json();
      if (data.routes && data.routes[0]) {
        const poly = data.routes[0].geometry.coordinates.map(c => [c[1], c[0]]);
        setOsrmRoutes(prev => ({ ...prev, [cacheKey]: poly }));
      }
    } catch (e) {
      console.error('OSRM Fetch error:', e);
    }
  }, [osrmRoutes]);

  useEffect(() => {
    if (embedded) return undefined;
    const tick = () => {
      const n = new Date();
      setClock([n.getHours(), n.getMinutes(), n.getSeconds()].map(v => String(v).padStart(2, '0')).join(':'));
    };
    const timer = setInterval(tick, 1000);
    tick();
    return () => clearInterval(timer);
  }, [embedded]);

  useEffect(() => {
    setActiveRiders(new Set(riders.map(r => r.id)));
  }, [riders]);

  useEffect(() => {
    riders.forEach(r => {
      const isActive = activeRiders.has(r.id);
      if (!isActive) return;
      if (focusedRider && focusedRider.id !== r.id) return;

      const trips = {};
      r.orders.forEach(o => {
        const t = o.trip_number || 1;
        if (!trips[t]) trips[t] = [];
        trips[t].push(o);
      });

      Object.entries(trips).forEach(([tNum, tOrders]) => {
        const sorted = [...tOrders].sort((a, b) => (a.step || 0) - (b.step || 0));
        const pts = buildTripPoints(sorted);
        if (pts.length >= 2) fetchRoute(r.id, tNum, pts);
      });
    });
  }, [riders, activeRiders, focusedRider, fetchRoute]);

  // Fetch a road route for each rider's CURRENT segment (prev stop → next stop) so the
  // bike can sit on the polyline rather than the aerial midpoint. Cached under a `seg-<step>`
  // trip key so it doesn't collide with the full-trip route under `<tripNum>`.
  useEffect(() => {
    riderPositions.forEach((p) => {
      if (focusedKitchen) return;
      if (focusedRider && focusedRider.id !== p.id) return;
      if (!activeRiders.has(p.id)) return;
      const pts = [[p.prevLat, p.prevLon], [p.nextLat, p.nextLon]];
      fetchRoute(p.id, `seg-${p.nextStep}`, pts);
    });
  }, [riderPositions, focusedRider, focusedKitchen, activeRiders, fetchRoute]);

  const startAnimation = () => {
    if (isAnimating) {
      setIsAnimating(false);
      setAnimatedSegments([]);
      return;
    }

    setIsAnimating(true);
    setAnimatedSegments([]);

    const allSegs = [];
    riders.forEach(r => {
      if (!activeRiders.has(r.id)) return;
      if (focusedRider && focusedRider.id !== r.id) return;
      if (focusedKitchen && !focusedKitchen.riders.has(r.id)) return;

      const trips = {};
      r.orders.forEach(o => {
        const t = o.trip_number || 1;
        if (!trips[t]) trips[t] = [];
        trips[t].push(o);
      });

      Object.entries(trips).forEach(([tNum, tOrders]) => {
        // Filter orders by focused kitchen if active
        const filteredTOrders = focusedKitchen
          ? tOrders.filter(o => (o.pickupcustomer || o.kitchen_key || 'Unknown').toLowerCase().trim() === focusedKitchen.id)
          : tOrders;

        if (filteredTOrders.length === 0) return;

        const cacheKey = `${r.id}-${tNum}`;
        const roadPath = osrmRoutes[cacheKey];
        const sorted = [...filteredTOrders].sort((a, b) => (a.step || 0) - (b.step || 0));

        // Aerial fallback — NaN-safe build
        const aerialPath = buildTripPoints(sorted);

        const isKitchenAerial = (viewMode === 'kitchens' || focusedKitchen);
        const path = roadPath || aerialPath;
        if (path.length < 2) return;

        for (let i = 0; i < path.length - 1; i++) {
          allSegs.push({
            from: path[i],
            to: path[i + 1],
            color: r.color,
            delay: (parseInt(r.id.slice(-3)) || 0) * 0.05 + (parseInt(tNum) * 40) + i * (isKitchenAerial ? 40 : 8)
          });
        }
      });
    });

    allSegs.sort((a, b) => a.delay - b.delay);
    allSegs.forEach((s, idx) => {
      setTimeout(() => {
        setAnimatedSegments(prev => [...prev, s]);
        if (idx === allSegs.length - 1) {
          setTimeout(() => setIsAnimating(false), 1000);
        }
      }, s.delay);
    });
  };

  const createKitchenIcon = (name) => L.divIcon({
    className: '',
    iconSize: [34, 34],
    iconAnchor: [17, 17],
    popupAnchor: [0, -18],
    html: `<div class="kitchen-mark">${(name || 'K').charAt(0).toUpperCase()}</div>`
  });

  const getRiderColor = (rid) => riders.find(r => r.id === rid)?.color || '#475569';

  // Shared rider-card markup, used in the "By Rider" panel and inside the focused-zone detail.
  const renderRiderCard = (r, i) => (
    <div key={r.id} className="rcard" onClick={() => handleRiderFocus(r)} style={{ animationDelay: `${i * 0.05}s` }}>
      <div className="rcard-top">
        <div className="rcard-emo" style={{ background: `${r.color}18`, borderColor: `${r.color}50` }}>🏍</div>
        <div className="rcard-info">
          <div className="rcard-name">{r.riderName}</div>
          <div className="rcard-zone">{r.orders[0]?.zone_name || 'Coimbatore'} · {new Set(r.orders.map(o => o.trip_number || 1)).size} trips</div>
        </div>
        <div className="rcard-badge" style={{ background: `${r.color}18`, color: r.color }}>{r.orders.length}</div>
      </div>
      <div className="bar-bg"><div className="bar-fg" style={{ width: `${Math.min(100, (r.orders.length / 15) * 100)}%`, background: r.color }}></div></div>
      <div className="rcard-meta"><span>📏 {r.orders.reduce((s, o) => s + parseFloat(o.actualkms || o.kms || 0), 0).toFixed(1)} km</span><span>💰 ₹{r.orders.reduce((s, o) => s + parseFloat(o.profit || 0), 0).toFixed(0)}</span></div>
      <div className="step-ids">
        {r.orders.slice(0, 15).map(o => <span key={o.orderid} className="step-id">S{o.step}</span>)}
      </div>
    </div>
  );

  const renderMarkers = () => {
    let ordersToRender = allOrders;
    if (focusedZone) ordersToRender = focusedZone.orders;
    if (focusedRider) ordersToRender = focusedRider.orders;
    if (focusedKitchen) ordersToRender = focusedKitchen.orders;
    ordersToRender = ordersToRender.filter(hasValidDrop);

    return ordersToRender.map((o, idx) => {
      const rid = o.rider_id;
      const active = rid ? activeRiders.has(rid) : true;
      const color = getRiderColor(rid);

      // Use the 'step' field from data, fallback to index
      const seq = o.step || (focusedRider || focusedKitchen ? (ordersToRender.indexOf(o) + 1) : 0);
      const sz = 22;

      const statusStyle = getStatusStyle(o.orderstatus);
      const statusLow = String(o.orderstatus || '').toLowerCase();
      const isDelivered = statusLow === 'delivered';
      const isPulsing = pulseOrderId && String(pulseOrderId) === String(o.orderid);
      // Flag SVG: pole + swallow-tail banner. A check glyph appears on the banner when delivered.
      const flagSvg = o.orderstatus
        ? `<svg class="cmark-flag" viewBox="0 0 18 22" xmlns="http://www.w3.org/2000/svg">
             <line x1="1.5" y1="0" x2="1.5" y2="22" stroke="#0f172a" stroke-width="1.6" stroke-linecap="round"/>
             <polygon points="2,1 17,1 13.5,5.5 17,10 2,10" fill="${statusStyle.bg}" stroke="#0f172a" stroke-width="0.6" stroke-linejoin="round"/>
             ${isDelivered ? '<polyline points="5,5.5 7,7.5 11,3.5" fill="none" stroke="#fff" stroke-width="1.4" stroke-linecap="round" stroke-linejoin="round"/>' : ''}
           </svg>`
        : '';
      const icon = L.divIcon({
        className: '',
        iconSize: [sz, sz],
        iconAnchor: [sz / 2, sz / 2],
        popupAnchor: [0, -22], // Lift popup above the flag, not just the marker
        html: `<div class="cmark${isPulsing ? ' pulse' : ''}" style="background:${color};width:${sz}px;height:${sz}px;font-size:${seq > 9 ? 7 : 8}px;opacity:${active ? 1 : 0.75}">${seq > 0 ? seq : ''}${flagSvg}</div>`
      });

      return (
        <Marker key={o.orderid} position={[parseFloat(o.droplat || o.deliverylat), parseFloat(o.droplon || o.deliverylong)]} icon={icon} zIndexOffset={rid ? 100 : 0}>
          <Popup maxWidth={250}>
            <div className="pu-id">ORDER #{o.orderid}</div>
            <div className="pu-rider" style={{ color }}>{o.rider_name || o.ridername || 'Unassigned'}</div>
            {o.orderstatus && (
              <div className="pu-row">
                <span>Status</span>
                <span className="status-chip" style={{ background: statusStyle.bg, color: statusStyle.fg, marginLeft: 0 }}>{statusStyle.label}</span>
              </div>
            )}
            <div className="pu-row"><span>Customer</span><span>{o.deliverycustomer || '?'}</span></div>
            <div className="pu-row"><span>Kitchen</span><span>{o.pickupcustomer || '?'}</span></div>
            <div className="pu-row"><span>Trip / Step</span><span>T{o.trip_number || '-'} S{o.step || '-'}</span></div>
            <div className="pu-row"><span>Distance</span><span>{o.actualkms || o.kms || 0} km</span></div>
            <div className="pu-row"><span>Profit</span><span>₹{o.profit || 0}</span></div>
          </Popup>
        </Marker>
      );
    });
  };

  const renderRoutes = () => {
    if (isAnimating) {
      return animatedSegments.map((s, i) => (
        <Polyline key={i} positions={[s.from, s.to]} pathOptions={{ color: s.color, weight: 6, opacity: 0.9, lineJoin: 'round', lineCap: 'round' }} />
      ));
    }

    const routes = [];
    const zoneRiderIds = focusedZone ? new Set(focusedZone.riders.map((zr) => String(zr.rider_id))) : null;
    riders.forEach(r => {
      const isActive = activeRiders.has(r.id);
      if (focusedRider && focusedRider.id !== r.id) return;
      if (focusedKitchen && !focusedKitchen.riders.has(r.id)) return;
      if (zoneRiderIds && !zoneRiderIds.has(String(r.id))) return;

      const rOrders = r.orders;
      const trips = {};
      rOrders.forEach(o => {
        const t = o.trip_number || 1;
        if (!trips[t]) trips[t] = [];
        trips[t].push(o);
      });

      Object.entries(trips).forEach(([tNum, tOrders]) => {
        // Filter orders by focused kitchen if active
        const filteredTOrders = focusedKitchen
          ? tOrders.filter(o => (o.pickupcustomer || o.kitchen_key || 'Unknown').toLowerCase().trim() === focusedKitchen.id)
          : tOrders;

        if (filteredTOrders.length === 0) return;

        const cacheKey = `${r.id}-${tNum}`;
        const roadPoints = osrmRoutes[cacheKey];
        const sorted = [...filteredTOrders].sort((a, b) => (a.step || 0) - (b.step || 0));

        // Always render the actual road polyline from OSRM — applies to every view
        // (riders, zones, all routes, kitchens). If OSRM hasn't responded yet we just
        // don't draw, instead of flashing an aerial line that snaps to the road later.
        const finalPoints = roadPoints;
        if (!finalPoints || finalPoints.length < 2) return;

        const isKitchenView = (viewMode === 'kitchens' || focusedKitchen);
        const opacity = isActive ? 1.0 : 0.1;
        const weight = isKitchenView ? 7 : 6;

        routes.push(
          <React.Fragment key={`${r.id}-${tNum}`}>
            <Polyline positions={finalPoints} pathOptions={{ color: '#ffffff', weight: weight + 4, opacity: opacity * 0.5, lineJoin: 'round', lineCap: 'round' }} />
            <Polyline positions={finalPoints} pathOptions={{ color: r.color, weight: weight, opacity: opacity, lineJoin: 'round', lineCap: 'round' }} />
          </React.Fragment>
        );
      });
    });
    return routes;
  };

  const toggleRider = (rid) => {
    const newActive = new Set(activeRiders);
    if (newActive.has(rid)) newActive.delete(rid);
    else newActive.add(rid);
    setActiveRiders(newActive);
  };

  return (
    <div className={`testing-container${embedded ? ' embedded' : ''}`}>
      {!embedded && (
        <div id="hdr">
          <div className="logo">
            <div className="logo-badge">D</div>
            <div className="logo-name">Rider <em>Dispatch</em></div>
            <div className="hdr-sep"></div>
            <div className="hdr-meta">Coimbatore · {activeStats.orders} orders · {activeStats.riders} {activeStats.riders === 1 ? 'rider' : 'riders'} ({activeStats.label})</div>
          </div>
          <div id="clock">{clock}</div>
        </div>
      )}

      <div id="strat-row">
        {zoneCards.length > 0 && (
          <button
            className={`sbt ${viewMode === 'zones' ? 'active' : ''}`}
            onClick={() => { setViewMode('zones'); handleRiderFocus(null); setFocusedKitchen(null); setFocusedZone(null); }}
          ><span className="sbt-icon"><MdMap /></span> By Zone</button>
        )}
        <button className={`sbt ${viewMode === 'riders' ? 'active' : ''}`} onClick={() => { setViewMode('riders'); handleRiderFocus(null); setFocusedKitchen(null); setFocusedZone(null); }}><span className="sbt-icon"><MdDirectionsBike /></span> By Rider</button>
        <button className={`sbt ${viewMode === 'kitchens' ? 'active' : ''}`} onClick={() => { setViewMode('kitchens'); handleRiderFocus(null); setFocusedKitchen(null); setFocusedZone(null); }}><span className="sbt-icon"><MdRestaurant /></span> By Kitchen</button>
        <button className={`sbt ${viewMode === 'all' ? 'active' : ''}`} onClick={() => { setViewMode('all'); handleRiderFocus(null); setFocusedKitchen(null); setFocusedZone(null); }}><span className="sbt-icon"><MdPublic /></span> All Routes</button>

        {shouldFetchLive && (
          <div className="live-controls">
            {liveIsFetching && (
              <span className="live-status">
                <span className="live-dot" /> Loading {liveRows.length ? `· ${liveRows.length} loaded` : ''}
              </span>
            )}
            {!liveIsFetching && !liveIsError && (
              <span className="live-status live-status-ready">
                <span className="live-dot ready" /> {liveRows.length} orders
              </span>
            )}
            {liveIsError && (
              <span className="live-status live-status-error">
                <span className="live-dot error" /> Failed to load
              </span>
            )}
            <label className="live-date-label">
              <span>Date</span>
              <input
                type="date"
                value={selectedDate}
                max={dayjs().format('YYYY-MM-DD')}
                onChange={(e) => {
                  setSelectedDate(e.target.value);
                  handleRiderFocus(null);
                  setFocusedKitchen(null);
                  setFocusedZone(null);
                }}
              />
            </label>
          </div>
        )}
      </div>

      {shouldFetchLive && (
        <div id="batch-row">
          <span className="batch-label">Batch</span>
          {BATCHES.map((b) => (
            <button
              key={b.id}
              className={`batch-btn batch-${b.id} ${selectedBatch === b.id ? 'active' : ''}`}
              onClick={() => {
                setSelectedBatch(b.id);
                handleRiderFocus(null);
                setFocusedKitchen(null);
                setFocusedZone(null);
              }}
              title={`${b.label} batch`}
            >
              <span className="batch-btn-icon">{b.icon}</span>
              <span className="batch-btn-label">{b.label}</span>
              <span className="batch-btn-count">{batchCounts[b.id] ?? 0}</span>
            </button>
          ))}
        </div>
      )}

      <div id="body">
        <div id="sidebar">
          {/* Stats strip hidden for now — restore by removing this comment wrapper.
          <div id="stats-strip">
            <div className="sc"><div className="sc-lbl">Orders</div><div className="sc-val g">{activeStats.orders}</div><div className="sc-sub">{activeStats.label}</div></div>
            <div className="sc"><div className="sc-lbl">Riders</div><div className="sc-val">{activeStats.riders}</div><div className="sc-sub">Active</div></div>
            <div className="sc"><div className="sc-lbl">Distance</div><div className="sc-val">{activeStats.km.toFixed(1)} km</div><div className="sc-sub">Kilometers</div></div>
            <div className="sc"><div className="sc-lbl">Profit</div><div className="sc-val g">₹{activeStats.profit.toFixed(0)}</div><div className="sc-sub">Earned</div></div>
          </div>
          */}

          {(focusedRider || focusedKitchen) ? (
            <div id="route-detail">
              <button className="rd-back" onClick={() => { handleRiderFocus(null); setFocusedKitchen(null); }}>← Back to {focusedZone ? focusedZone.name : 'list'}</button>
              {focusedRider ? (
                <>
                  <div className="rd-rider-name" style={{ color: focusedRider.color }}>{focusedRider.riderName}</div>
                  {(() => {
                    const totalKm = focusedRider.orders.reduce((s, o) => s + parseFloat(o.actualkms || o.kms || 0), 0);
                    const totalProfit = focusedRider.orders.reduce((s, o) => s + parseFloat(o.profit || 0), 0);
                    const isLoss = totalProfit < 0;
                    return (
                      <div className="rd-stats-grid">
                        <div className="rd-stat rd-stat-orders">
                          <div className="rd-stat-icon">📦</div>
                          <div className="rd-stat-value">{focusedRider.orders.length}</div>
                          <div className="rd-stat-label">Orders</div>
                        </div>
                        <div className="rd-stat rd-stat-distance">
                          <div className="rd-stat-icon">📏</div>
                          <div className="rd-stat-value">{totalKm.toFixed(1)}<span className="rd-stat-unit">km</span></div>
                          <div className="rd-stat-label">Distance</div>
                        </div>
                        <div className={`rd-stat rd-stat-profit ${isLoss ? 'is-loss' : 'is-gain'}`}>
                          <div className="rd-stat-icon">{isLoss ? '📉' : '📈'}</div>
                          <div className="rd-stat-value">
                            {isLoss ? '-' : ''}₹{Math.abs(totalProfit).toFixed(0)}
                          </div>
                          <div className="rd-stat-label">{isLoss ? 'Loss' : 'Profit'}</div>
                        </div>
                      </div>
                    );
                  })()}
                  {(() => {
                    const trips = {};
                    focusedRider.orders.forEach(o => {
                      const t = o.trip_number || 1;
                      if (!trips[t]) trips[t] = [];
                      trips[t].push(o);
                    });
                    let prevKitchenKey = null;
                    return Object.entries(trips)
                      .sort(([a], [b]) => Number(a) - Number(b))
                      .map(([tNum, tOrders]) => (
                      <div key={tNum} className="trip-block">
                        <div className="trip-header" style={{ background: `${focusedRider.color}12`, borderColor: `${focusedRider.color}30` }}>
                          <span className="th-badge" style={{ background: focusedRider.color }}>Trip {tNum}</span>
                          <span className="trip-stats">
                            <span>📍 {tOrders.length} stops</span>
                            <span>📏 {tOrders.reduce((s, o) => s + parseFloat(o.actualkms || o.kms || 0), 0).toFixed(1)} km</span>
                          </span>
                        </div>
                        <div className="step-wrap">
                          {tOrders.map((o, idx) => {
                            const kitchenKey = (o.kitchen_key || o.pickupcustomer || 'Unknown').toLowerCase().trim();
                            const showTransition = prevKitchenKey !== null && kitchenKey !== prevKitchenKey;
                            prevKitchenKey = kitchenKey;
                            return (
                              <React.Fragment key={o.orderid}>
                                {showTransition && (
                                  <div className="kitchen-transition"><span className="kt-ico">🔄</span> Switch to <strong>{o.pickupcustomer}</strong></div>
                                )}
                                {idx === 0 && (
                                  <div className="step-row">
                                    <div className="step-col-left"><div className="step-dot kitchen">K</div></div>
                                    <div className="step-col-body">
                                      <div className="step-label"><span className="kitchen-tag">📥 {o.pickupcustomer}</span></div>
                                      <div className="step-dest">Pickup point · Trip {tNum}</div>
                                    </div>
                                  </div>
                                )}
                                <div className="step-row">
                                  <div className="step-col-left"><div className="step-dot delivery">{o.step || idx + 1}</div></div>
                                  <div className="step-col-body">
                                    <div className="step-label" style={{ display: 'flex', alignItems: 'center' }}>
                                      <span style={{ flex: 1, minWidth: 0, overflow: 'hidden', textOverflow: 'ellipsis', whiteSpace: 'nowrap' }}>📬 {o.deliverycustomer}</span>
                                      {o.orderstatus && (() => {
                                        const s = getStatusStyle(o.orderstatus);
                                        const isDel = String(o.orderstatus || '').toLowerCase() === 'delivered';
                                        return (
                                          <span className="step-flag">
                                            <svg className="step-flag-svg" viewBox="0 0 14 18" xmlns="http://www.w3.org/2000/svg" aria-hidden="true">
                                              <line x1="1.5" y1="0" x2="1.5" y2="18" stroke="#0f172a" strokeWidth="1.4" strokeLinecap="round" />
                                              <polygon points="2,1 13,1 10,5 13,9 2,9" fill={s.bg} stroke="#0f172a" strokeWidth="0.5" strokeLinejoin="round" />
                                              {isDel && (
                                                <polyline points="4,5 6,7 9,3" fill="none" stroke="#fff" strokeWidth="1.3" strokeLinecap="round" strokeLinejoin="round" />
                                              )}
                                            </svg>
                                            <span className="step-flag-label" style={{ color: s.bg }}>{s.label}</span>
                                          </span>
                                        );
                                      })()}
                                    </div>
                                    <div className="step-dest">Order #{o.orderid}</div>
                                    {(o.locationname || o.locationsuburb) && (
                                      <div className="step-location">📍 {[o.locationname, o.locationsuburb].filter(Boolean).join(' · ')}</div>
                                    )}
                                    {o.ordernotes && (
                                      <div className="step-notes" title={o.ordernotes}>📝 {o.ordernotes}</div>
                                    )}
                                    <div className="step-detail">
                                      <span>📏 {o.actualkms || o.kms || 0} km</span>
                                      <span className="step-profit">💰 ₹{parseFloat(o.profit || 0).toFixed(0)}</span>
                                      {o.deliverycharge != null && (
                                        <span className="step-charges">₹{parseFloat(o.deliverycharge).toFixed(0)} chg</span>
                                      )}
                                      {o.ordertype && (
                                        <span className={`step-type type-${String(o.ordertype).toLowerCase()}`}>{o.ordertype}</span>
                                      )}
                                    </div>
                                  </div>
                                </div>
                              </React.Fragment>
                            );
                          })}
                        </div>
                      </div>
                    ));
                  })()}
                </>
              ) : (
                <>
                  <div className="rd-rider-name" style={{ color: '#f59e0b' }}>{focusedKitchen.kitchenName}</div>
                  <div className="rd-rider-sub">
                    <span>📦 {focusedKitchen.orders.length} orders</span>
                    <span>🏍 {focusedKitchen.riders.size} riders</span>
                  </div>
                  <div className="step-wrap">
                    {focusedKitchen.orders.map((o, idx) => (
                      <div key={o.orderid} className="step-row">
                        <div className="step-col-left"><div className="step-dot delivery" style={{ background: getRiderColor(o.rider_id) }}>{idx + 1}</div></div>
                        <div className="step-col-body">
                          <div className="step-label" style={{ display: 'flex', alignItems: 'center' }}>
                            <span style={{ flex: 1, minWidth: 0, overflow: 'hidden', textOverflow: 'ellipsis', whiteSpace: 'nowrap' }}>📬 {o.deliverycustomer}</span>
                            {o.orderstatus && (() => {
                              const s = getStatusStyle(o.orderstatus);
                              const isDel = String(o.orderstatus || '').toLowerCase() === 'delivered';
                              return (
                                <span className="step-flag">
                                  <svg className="step-flag-svg" viewBox="0 0 14 18" xmlns="http://www.w3.org/2000/svg" aria-hidden="true">
                                    <line x1="1.5" y1="0" x2="1.5" y2="18" stroke="#0f172a" strokeWidth="1.4" strokeLinecap="round" />
                                    <polygon points="2,1 13,1 10,5 13,9 2,9" fill={s.bg} stroke="#0f172a" strokeWidth="0.5" strokeLinejoin="round" />
                                    {isDel && (
                                      <polyline points="4,5 6,7 9,3" fill="none" stroke="#fff" strokeWidth="1.3" strokeLinecap="round" strokeLinejoin="round" />
                                    )}
                                  </svg>
                                  <span className="step-flag-label" style={{ color: s.bg }}>{s.label}</span>
                                </span>
                              );
                            })()}
                          </div>
                          <div className="step-dest">Order #{o.orderid} · Rider: {o.rider_name || o.ridername}</div>
                          {(o.locationname || o.locationsuburb) && (
                            <div className="step-location">📍 {[o.locationname, o.locationsuburb].filter(Boolean).join(' · ')}</div>
                          )}
                          {o.ordernotes && (
                            <div className="step-notes" title={o.ordernotes}>📝 {o.ordernotes}</div>
                          )}
                          <div className="step-detail">
                            <span>📏 {o.actualkms || o.kms || 0} km</span>
                            <span className="step-profit">💰 ₹{parseFloat(o.profit || 0).toFixed(0)}</span>
                            {o.deliverycharge != null && (
                              <span className="step-charges">₹{parseFloat(o.deliverycharge).toFixed(0)} chg</span>
                            )}
                            {o.ordertype && (
                              <span className={`step-type type-${String(o.ordertype).toLowerCase()}`}>{o.ordertype}</span>
                            )}
                          </div>
                        </div>
                      </div>
                    ))}
                  </div>
                </>
              )}
            </div>
          ) : focusedZone ? (
            <div id="route-detail">
              <button className="rd-back" onClick={() => setFocusedZone(null)}>← Back to zones</button>
              <div className="rd-rider-name" style={{ color: '#3b82f6' }}>{focusedZone.name}</div>
              <div className="rd-rider-sub">
                <span>📦 {focusedZone.totalOrders} orders</span>
                <span>🏍 {focusedZone.activeRidersCount} riders</span>
                <span>📏 {focusedZone.totalKms.toFixed(1)} km</span>
                <span className="step-profit">💰 ₹{focusedZone.totalProfit.toFixed(0)}</span>
              </div>

              {/* Status breakdown */}
              {Object.keys(focusedZone.statusCounts).length > 0 && focusedZone.totalOrders > 0 && (
                <div className="zone-detail-section">
                  <div className="zone-section-label">Status Breakdown</div>
                  <div className="zone-status-bar tall">
                    {Object.entries(focusedZone.statusCounts).map(([status, count]) => {
                      const style = getStatusStyle(status);
                      const pct = (count / focusedZone.totalOrders) * 100;
                      return (
                        <div
                          key={status}
                          className="zone-status-seg"
                          style={{ width: `${pct}%`, background: style.bg }}
                          title={`${style.label}: ${count}`}
                        >
                          {pct > 7 && <span className="zone-status-seg-label">{count}</span>}
                        </div>
                      );
                    })}
                  </div>
                  <div className="zone-status-legend">
                    {Object.entries(focusedZone.statusCounts).map(([status, count]) => {
                      const style = getStatusStyle(status);
                      return (
                        <span key={status} className="legend-item">
                          <span className="legend-dot" style={{ background: style.bg }} />
                          {style.label} <strong>{count}</strong>
                        </span>
                      );
                    })}
                  </div>
                </div>
              )}

              {/* Areas covered (delivery suburbs) */}
              {focusedZone.suburbs.length > 0 && (
                <div className="zone-detail-section">
                  <div className="zone-section-label">Areas Covered <span className="section-count">({focusedZone.suburbs.length})</span></div>
                  <div className="zone-chips">
                    {focusedZone.suburbs.map((s) => (
                      <span key={s.name} className="zone-chip">
                        <span className="zone-chip-name">{s.name}</span>
                        <span className="zone-chip-count">{s.count}</span>
                      </span>
                    ))}
                  </div>
                </div>
              )}

              {/* Pickup kitchens */}
              {focusedZone.kitchens.length > 0 && (
                <div className="zone-detail-section">
                  <div className="zone-section-label">Kitchens <span className="section-count">({focusedZone.kitchens.length})</span></div>
                  <div className="zone-chips">
                    {focusedZone.kitchens.map((k) => (
                      <span key={k.name} className="zone-chip kitchen">
                        <span className="zone-chip-name">🍳 {k.name}</span>
                        <span className="zone-chip-count kitchen">{k.count}</span>
                      </span>
                    ))}
                  </div>
                </div>
              )}

              {/* Riders */}
              <div className="zone-detail-section">
                <div className="zone-section-label">Riders <span className="section-count">({focusedZone.activeRidersCount})</span></div>
                {focusedZone.riders
                  .map((zr) => riders.find((rd) => String(rd.id) === String(zr.rider_id)))
                  .filter(Boolean)
                  .map(renderRiderCard)}
              </div>
            </div>
          ) : (
            <div id="riders-panel">
              <div className="ph">{
                viewMode === 'zones' ? 'Zone dispatch' :
                viewMode === 'kitchens' ? 'Kitchen dispatch' :
                'Rider dispatch'
              }</div>
              <div id="rider-cards">
                {viewMode === 'zones' ? (
                  zoneCards.map((z, i) => {
                    const delivered = z.statusCounts.delivered || 0;
                    const profitNeg = z.totalProfit < 0;
                    return (
                      <div key={z.id} className="rcard zone-card" onClick={() => setFocusedZone(z)} style={{ animationDelay: `${i * 0.05}s` }}>
                        <div className="zone-card-header">
                          <div className="zone-card-emoji">🗺️</div>
                          <div className="zone-card-titles">
                            <div className="zone-card-name">{z.name}</div>
                            <div className="zone-card-sub">
                              {z.activeRidersCount} {z.activeRidersCount === 1 ? 'rider' : 'riders'} · {z.totalOrders} {z.totalOrders === 1 ? 'order' : 'orders'}
                            </div>
                          </div>
                          <span className="zone-card-arrow" aria-hidden="true">→</span>
                        </div>

                        {/* Status segments + delivered counter */}
                        {z.totalOrders > 0 && (
                          <div className="zone-progress-row">
                            <div
                              className="zone-status-bar"
                              title={Object.entries(z.statusCounts)
                                .map(([k, v]) => `${getStatusStyle(k).label}: ${v}`)
                                .join(' · ')}
                            >
                              {Object.entries(z.statusCounts).map(([status, count]) => {
                                const style = getStatusStyle(status);
                                const pct = (count / z.totalOrders) * 100;
                                return (
                                  <div
                                    key={status}
                                    className="zone-status-seg"
                                    style={{ width: `${pct}%`, background: style.bg }}
                                  />
                                );
                              })}
                            </div>
                            <div className="zone-progress-label">
                              {delivered}/{z.totalOrders}
                            </div>
                          </div>
                        )}

                        {/* Stat pills */}
                        <div className="zone-stat-pills">
                          <span className="zone-stat-pill" title="Areas covered">
                            <span className="zone-stat-icon">📍</span>
                            <span className="zone-stat-value">{z.suburbs.length}</span>
                            <span className="zone-stat-label">{z.suburbs.length === 1 ? 'area' : 'areas'}</span>
                          </span>
                          <span className="zone-stat-pill" title="Total distance">
                            <span className="zone-stat-icon">📏</span>
                            <span className="zone-stat-value">{z.totalKms.toFixed(1)}</span>
                            <span className="zone-stat-label">km</span>
                          </span>
                          <span className="zone-stat-pill" title="Kitchens">
                            <span className="zone-stat-icon">🍳</span>
                            <span className="zone-stat-value">{z.kitchens.length}</span>
                            <span className="zone-stat-label">{z.kitchens.length === 1 ? 'kitchen' : 'kitchens'}</span>
                          </span>
                          <span className={`zone-stat-pill ${profitNeg ? 'profit-negative' : 'profit-positive'}`} title="Total profit">
                            <span className="zone-stat-icon">💰</span>
                            <span className="zone-stat-value">
                              {profitNeg ? `-₹${Math.abs(z.totalProfit).toFixed(0)}` : `₹${z.totalProfit.toFixed(0)}`}
                            </span>
                          </span>
                        </div>

                        {z.suburbs.length > 0 && (
                          <div className="zone-card-suburbs">
                            <span className="zone-card-suburbs-text">
                              {z.suburbs.slice(0, 3).map((s) => s.name).join(' · ')}
                            </span>
                            {z.suburbs.length > 3 && (
                              <span className="zone-card-suburbs-more">+{z.suburbs.length - 3}</span>
                            )}
                          </div>
                        )}
                      </div>
                    );
                  })
                ) : viewMode === 'kitchens' ? (
                  kitchens.map((k, i) => (
                    <div key={k.id} className="rcard" onClick={() => setFocusedKitchen(k)} style={{ animationDelay: `${i * 0.05}s` }}>
                      <div className="rcard-top">
                        <div className="rcard-emo" style={{ background: '#f59e0b18', borderColor: '#f59e0b50' }}>🍳</div>
                        <div className="rcard-info">
                          <div className="rcard-name">{k.kitchenName}</div>
                          <div className="rcard-zone">{k.riders.size} riders · 💰 ₹{k.orders.reduce((s, o) => s + parseFloat(o.profit || 0), 0).toFixed(0)}</div>
                        </div>
                        <div className="rcard-badge" style={{ background: '#f59e0b18', color: '#f59e0b' }}>{k.orders.length}</div>
                      </div>
                      <div className="bar-bg"><div className="bar-fg" style={{ width: `${Math.min(100, (k.orders.length / 20) * 100)}%`, background: '#f59e0b' }}></div></div>
                      <div className="rcard-meta"><span>📏 {k.orders.reduce((s, o) => s + parseFloat(o.actualkms || o.kms || 0), 0).toFixed(1)} km</span><span>{k.riders.size} riders</span></div>
                      <div className="step-ids">
                        {Array.from(k.riders).slice(0, 10).map(rid => (
                          <span key={rid} className="step-id" style={{ color: getRiderColor(rid) }}>{riders.find(r => r.id === rid)?.riderName.split(' ')[0]}</span>
                        ))}
                      </div>
                    </div>
                  ))
                ) : (
                  riders.map(renderRiderCard)
                )}
              </div>
            </div>
          )}
          <div id="desc">
            {(focusedRider || focusedKitchen) ? 'Detailed breakdown' : focusedZone ? `${focusedZone.activeRidersCount} riders in ${focusedZone.name} — click one to drill in` : '💡 Click a card to view detailed route breakdown'}
          </div>
        </div>

        <div id="map-wrap" className={viewMode === 'kitchens' ? 'view-mode-kitchens' : ''}>
          <MapContainer center={[11.022, 76.982]} zoom={12} scrollWheelZoom style={{ height: '100%', width: '100%' }} zoomControl={false}>
            <TileLayer url="https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png" attribution='&copy; OpenStreetMap contributors' />
            <ZoomControl position="bottomright" />
            <MapController focusedItem={focusedRider || focusedKitchen || focusedZone} viewMode={viewMode} orders={allOrders} />
            {kitchens
              .filter(k => Number.isFinite(k.lat) && Number.isFinite(k.lon))
              .filter(k => !focusedRider || k.riders.has(focusedRider.id))
              .map((k, i) => (
                <Marker
                  key={`k-${i}`}
                  position={[k.lat, k.lon]}
                  icon={createKitchenIcon(k.kitchenName)}
                  zIndexOffset={2000}
                  eventHandlers={{
                    click: () => setFocusedKitchen(k),
                    mouseover: (e) => e.target.openPopup(),
                    mouseout: (e) => e.target.closePopup()
                  }}
                >
                  <Popup className="kitchen-popup" maxWidth={220} minWidth={200}>
                    <div className="kp-header">KITCHEN</div>
                    <div className="kp-name">{k.kitchenName}</div>
                    <div className="kp-stat">
                      <span className="kp-stat-lbl">Orders</span>
                      <span className="kp-stat-val">{k.orders.length}</span>
                    </div>
                  </Popup>
                </Marker>
              ))
            }
            {renderMarkers()}
            {renderRoutes()}
            {!focusedKitchen && riderPositions
              .filter(p => activeRiders.has(p.id))
              .filter(p => !focusedRider || focusedRider.id === p.id)
              .map(p => {
                // Prefer the road polyline midpoint; fall back to aerial midpoint until OSRM responds.
                const segPolyline = osrmRoutes[`${p.id}-seg-${p.nextStep}`];
                const roadMid = polylineMidpoint(segPolyline);
                const pos = roadMid || [p.aerialLat, p.aerialLon];
                const onRoad = Boolean(roadMid);
                const bikeIcon = L.divIcon({
                  className: '',
                  iconSize: [44, 44],
                  iconAnchor: [22, 22],
                  popupAnchor: [0, -22],
                  html: `<div class="rider-bike${onRoad ? ' on-road' : ''}" style="--rider-color:${p.color}">
                           <div class="rider-bike-ring"></div>
                           <div class="rider-bike-svg">${MOTORBIKE_SVG}</div>
                           <div class="rider-bike-progress">${p.completedCount}/${p.totalCount}</div>
                         </div>`
                });
                return (
                  <Marker
                    key={`bike-${p.id}`}
                    position={pos}
                    icon={bikeIcon}
                    zIndexOffset={3000}
                    eventHandlers={{ click: () => handleRiderFocus(riders.find((r) => r.id === p.id) || null) }}
                  >
                    <Popup maxWidth={220}>
                      <div className="pu-id">RIDER</div>
                      <div className="pu-rider" style={{ color: p.color }}>{p.riderName}</div>
                      <div className="pu-row"><span>Progress</span><span>{p.completedCount} / {p.totalCount} delivered</span></div>
                      <div className="pu-row"><span>Next stop</span><span>#{p.nextStep} · {p.nextCustomer || '—'}</span></div>
                      <div className="pu-row"><span>Position</span><span>{onRoad ? 'on road' : 'estimating…'}</span></div>
                    </Popup>
                  </Marker>
                );
              })}
          </MapContainer>

          <div id="ov-tl">
            {/* <div className="ov-card">
              <div className="ov-stats">
                <div><div className="osv g">{activeStats.orders}</div><div className="osl">Orders</div></div>
                <div><div className="osv">{activeStats.riders}</div><div className="osl">Riders</div></div>
                <div><div className="osv g">₹{activeStats.profit.toFixed(0)}</div><div className="osl">Profit</div></div>
              </div>
            </div> */}
          </div>

          <div id="ov-tr">
            {viewMode === 'kitchens' ? (
              kitchens.slice(0, 10).map(k => (
                <div key={k.id} className={`rchip ${focusedKitchen?.id === k.id ? 'active' : ''}`} onClick={() => setFocusedKitchen(k)}>
                  <div className="rchip-dot" style={{ background: '#f59e0b' }}></div>
                  <span style={{ maxWidth: '100px', overflow: 'hidden', textOverflow: 'ellipsis', whiteSpace: 'nowrap' }}>{k.kitchenName}</span>
                  <span className="rchip-n">{k.orders.length}</span>
                </div>
              ))
            ) : (
              riders.slice(0, 10).map(r => (
                <div key={r.id} className={`rchip ${focusedRider?.id === r.id ? 'active' : ''}`} onClick={() => handleRiderFocus(r)}>
                  <div className="rchip-dot" style={{ background: r.color }}></div>
                  <span style={{ maxWidth: '100px', overflow: 'hidden', textOverflow: 'ellipsis', whiteSpace: 'nowrap' }}>{r.riderName}</span>
                  <span className="rchip-n">{r.orders.length}</span>
                </div>
              ))
            )}
          </div>

          <div id="ov-br">
            <button className={`sbt ${isAnimating ? 'active' : ''}`} onClick={startAnimation} style={{ boxShadow: 'var(--shadow-lg)', background: isAnimating ? 'var(--accent)' : '#fff' }}>
              <span>{isAnimating ? '⏹' : '▶'}</span> {isAnimating ? 'Stop' : 'Animate Routes'}
            </button>
          </div>
        </div>
      </div>
    </div>
  );
};

export default Dispatch;
