import React, { useEffect, useMemo, useState } from 'react';
import { MapContainer, TileLayer, Polyline, Marker, Popup, useMap } from 'react-leaflet';
import L from 'leaflet';
import 'leaflet/dist/leaflet.css';
import { Box, IconButton, Stack, Typography, CircularProgress } from '@mui/material';
import { MdClose, MdRoute } from 'react-icons/md';

const containerStyle = { width: '100%', height: '100%' };

// Numbered step icon — brand red to match the planned-route polyline below.
// Drawn fresh per render as a data URL so the step number can be baked into
// the SVG without juggling external marker assets.
const stepIcon = (n, isFocused) => {
  const size = isFocused ? 38 : 32;
  const color = isFocused ? '#910E1D' : '#C01227';
  const svg = encodeURIComponent(
    `<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 32 32" width="${size}" height="${size}">` +
      `<circle cx="16" cy="16" r="14" fill="${color}" stroke="white" stroke-width="3"/>` +
      `<text x="16" y="21" text-anchor="middle" font-family="Arial,sans-serif" font-size="14" font-weight="700" fill="white">${n}</text>` +
      `</svg>`
  );
  return new L.Icon({
    iconUrl: `data:image/svg+xml;charset=UTF-8,${svg}`,
    iconSize: [size, size],
    iconAnchor: [size / 2, size / 2]
  });
};

// Fits the map to the planned path once both the map and data are ready.
// Re-runs whenever the route changes (different rider / date).
const FitBoundsController = ({ dropPath }) => {
  const map = useMap();
  useEffect(() => {
    if (!dropPath.length) return;
    if (dropPath.length === 1) {
      map.setView(dropPath[0], 14);
    } else {
      map.fitBounds(dropPath, { padding: [48, 48] });
    }
  }, [dropPath, map]);
  return null;
};

// Renders a single rider's PLANNED route for the date range chosen on the
// Riders Summary page. `details` is an ordered array of waypoints (sorted by
// the planning step number) shaped as:
//   { step, orderid, deliveryid, customer, address,
//     dropLat, dropLng, pickLat, pickLng, expectedTime }
// `dropLat/dropLng` are required; pickup coords are optional and rendered as
// faded pre-stops if present.
export default function RidersRoutes({ details, loading, riderName, dateRange, onClose }) {
  const [focusedStep, setFocusedStep] = useState(null);
  const [routePath, setRoutePath] = useState([]);
  const [routeLoading, setRouteLoading] = useState(false);

  // Step-pin coordinates in planning order — what the polyline connects.
  const dropPath = useMemo(() => (details || []).map((d) => [d.dropLat, d.dropLng]), [details]);

  // Resolve the rider's planned waypoints into an actual road-following path
  // via OSRM. Without this, the polyline would cut across buildings / aerial
  // lines — operators have no way to read the real route.
  useEffect(() => {
    if (dropPath.length < 2) {
      setRoutePath([]);
      return;
    }
    let cancelled = false;

    (async () => {
      setRouteLoading(true);
      try {
        const coords = dropPath.map(([lat, lng]) => `${lng},${lat}`).join(';');
        const url = `https://router.project-osrm.org/route/v1/driving/${coords}?overview=full&geometries=geojson`;
        const res = await fetch(url);
        const data = await res.json();
        if (!cancelled && data.routes?.length) {
          const points = data.routes[0].geometry.coordinates.map(([lng, lat]) => [lat, lng]);
          setRoutePath(points);
        } else if (!cancelled) {
          setRoutePath([]);
        }
      } catch (e) {
        console.warn('OSRM route error:', e);
        if (!cancelled) setRoutePath([]);
      } finally {
        if (!cancelled) setRouteLoading(false);
      }
    })();

    return () => {
      cancelled = true;
    };
  }, [dropPath]);

  const headerBar = (
    <Stack
      direction="row"
      alignItems="center"
      spacing={1.5}
      sx={{
        px: 2,
        py: 1.25,
        borderBottom: '1px solid rgba(15, 23, 42, 0.08)',
        background: 'linear-gradient(135deg, #C01227 0%, #D25463 100%)',
        color: '#fff',
        flexShrink: 0
      }}
    >
      <MdRoute size={20} />
      <Stack sx={{ flex: 1, minWidth: 0 }}>
        <Typography sx={{ fontWeight: 700, fontSize: 15, lineHeight: 1.2 }}>Planned route{riderName ? ` — ${riderName}` : ''}</Typography>
        {dateRange && <Typography sx={{ fontSize: 12, opacity: 0.85 }}>{dateRange}</Typography>}
      </Stack>
      {details && details.length > 0 && (
        <Typography sx={{ fontSize: 12, opacity: 0.9, fontWeight: 600 }}>
          {details.length} {details.length === 1 ? 'stop' : 'stops'}
          {routeLoading ? ' · resolving route…' : ''}
        </Typography>
      )}
      {onClose && (
        <IconButton size="small" onClick={onClose} sx={{ color: '#fff' }} aria-label="Close">
          <MdClose />
        </IconButton>
      )}
    </Stack>
  );

  // Loading state — parent is still fetching the planned route data.
  if (loading) {
    return (
      <Box sx={{ display: 'flex', flexDirection: 'column', height: '100%' }}>
        {headerBar}
        <Stack alignItems="center" justifyContent="center" sx={{ flex: 1, gap: 1.5 }}>
          <CircularProgress size={32} />
          <Typography sx={{ color: '#64748b', fontSize: 13 }}>Loading planned route…</Typography>
        </Stack>
      </Box>
    );
  }

  // Empty state — fetched but rider has no deliveries with drop coords in the
  // selected window.
  if (!details || details.length === 0) {
    return (
      <Box sx={{ display: 'flex', flexDirection: 'column', height: '100%' }}>
        {headerBar}
        <Stack alignItems="center" justifyContent="center" sx={{ flex: 1, gap: 1, p: 3 }}>
          <Typography sx={{ color: '#1e293b', fontWeight: 700, fontSize: 16 }}>No planned route for this rider</Typography>
          <Typography sx={{ color: '#64748b', fontSize: 13, textAlign: 'center', maxWidth: 360 }}>
            There are no deliveries with drop coordinates assigned to this rider for the selected date range.
          </Typography>
        </Stack>
      </Box>
    );
  }

  return (
    <Box sx={{ display: 'flex', flexDirection: 'column', height: '100%' }}>
      {headerBar}
      <Box sx={{ flex: 1, minHeight: 0 }}>
        <MapContainer center={dropPath[0]} zoom={14} style={containerStyle} zoomControl={false}>
          <TileLayer url="https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png" attribution="&copy; OpenStreetMap contributors" />
          <FitBoundsController dropPath={dropPath} />

          {routePath.length > 0 ? (
            <>
              {/* Translucent backdrop so the route stays legible on busy tiles. */}
              <Polyline positions={routePath} pathOptions={{ color: '#C01227', opacity: 0.25, weight: 8 }} />
              {/* Road-following planned route from OSRM. */}
              <Polyline positions={routePath} pathOptions={{ color: '#C01227', opacity: 0.95, weight: 4 }} />
            </>
          ) : (
            // Fallback while OSRM is in flight (or if it fails) — dashed
            // straight-line skeleton between drop pins in step order.
            <Polyline positions={dropPath} pathOptions={{ color: '#C01227', opacity: 0.6, weight: 3, dashArray: '2 10', lineCap: 'round' }} />
          )}

          {details.map((d, i) => {
            const stepNum = d.step || i + 1;
            const isFocused = focusedStep === d.deliveryid;
            return (
              <Marker
                key={`step-${d.deliveryid || d.orderid || i}`}
                position={[d.dropLat, d.dropLng]}
                icon={stepIcon(stepNum, isFocused)}
                eventHandlers={{
                  click: () => setFocusedStep(isFocused ? null : d.deliveryid)
                }}
                zIndexOffset={isFocused ? 1000 : stepNum}
              >
                <Popup onClose={() => setFocusedStep(null)}>
                  <Box sx={{ minWidth: 180, fontFamily: 'inherit' }}>
                    <Typography sx={{ fontWeight: 800, fontSize: 13, color: '#0f172a' }}>
                      Step {stepNum} · {d.customer}
                    </Typography>
                    {d.address && <Typography sx={{ fontSize: 12, color: '#475569', mt: 0.5 }}>{d.address}</Typography>}
                    {d.expectedTime && (
                      <Typography sx={{ fontSize: 12, color: '#64748b', mt: 0.5 }}>ETA {String(d.expectedTime).slice(11, 16) || d.expectedTime}</Typography>
                    )}
                    {d.orderid && <Typography sx={{ fontSize: 11, color: '#94a3b8', mt: 0.5 }}>Order #{d.orderid}</Typography>}
                  </Box>
                </Popup>
              </Marker>
            );
          })}
        </MapContainer>
      </Box>
    </Box>
  );
}
