/* Me2You - Real Leaflet/OpenStreetMap integration */
/* global React, L, Icon, panelStyle, btnPrimary, btnGhost, btnSmall, PRODUCTS */

const { useState, useEffect, useRef } = React;

/* South Africa cities for sample data */
const CITY_COORDS = {
  'Soweto':         [-26.2678, 27.8585],
  'Pretoria':       [-25.7479, 28.2293],
  'Khayelitsha':    [-34.0399, 18.6776],
  'Sandton':        [-26.1076, 28.0567],
  'Mamelodi':       [-25.7234, 28.3848],
  'Durban':         [-29.8587, 31.0218],
  'Polokwane':      [-23.9045, 29.4689],
  'Cape Town':      [-33.9249, 18.4241],
  'Bloemfontein':   [-29.0852, 26.1596],
  'Johannesburg':   [-26.2041, 28.0473],
  'Germiston':      [-26.2179, 28.1665],
  'East London':    [-33.0153, 27.9116],
  'Stellenbosch':   [-33.9322, 18.8602],
  'Centurion':      [-25.8601, 28.1881],
  'Port Elizabeth': [-33.9608, 25.6022],
  'Alexandra':      [-26.1015, 28.0937],
  'Rustenburg':     [-25.6672, 27.2424],
  'Nelspruit':      [-25.4753, 30.9694],
  'Tembisa':        [-25.9961, 28.2272],
  'Midrand':        [-25.9893, 28.1263],
  'Roodepoort':     [-26.1625, 27.8725],
  'Kempton Park':   [-26.1015, 28.2293],
};

/* Pickup-point partners across SA */
const PICKUP_POINTS = [
  { name:'PEP Maponya Mall',      partner:'PEP',  lat:-26.2734, lng:27.8941 },
  { name:'Pargo Menlyn Park',     partner:'Pargo',lat:-25.7838, lng:28.2774 },
  { name:'Paxi Sandton City',     partner:'Paxi', lat:-26.1085, lng:28.0568 },
  { name:'PEP Mitchells Plain',   partner:'PEP',  lat:-34.0466, lng:18.6172 },
  { name:'Pargo Gateway Theatre', partner:'Pargo',lat:-29.7239, lng:31.0689 },
  { name:'Paxi Cresta Mall',      partner:'Paxi', lat:-26.1334, lng:27.9744 },
];

/* --- LeafletMap - generic wrapper --- */
function LeafletMap({ center, zoom = 12, height = 400, markers = [], radius, routeFrom, routeTo, onMarkerClick }) {
  const mapRef = useRef(null);
  const mapInstanceRef = useRef(null);
  const layersRef = useRef([]);

  useEffect(() => {
    if (!mapRef.current || mapInstanceRef.current) return;
    const map = L.map(mapRef.current, { zoomControl: true, scrollWheelZoom: false }).setView(center, zoom);
    L.tileLayer('https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png', {
      attribution: '(c) OpenStreetMap', maxZoom: 19
    }).addTo(map);
    mapInstanceRef.current = map;
    return () => { map.remove(); mapInstanceRef.current = null; };
  }, []);

  useEffect(() => {
    const map = mapInstanceRef.current;
    if (!map) return;
    map.setView(center, zoom);
  }, [center, zoom]);

  // Update markers, radius, route on changes
  useEffect(() => {
    const map = mapInstanceRef.current;
    if (!map) return;
    layersRef.current.forEach(l => map.removeLayer(l));
    layersRef.current = [];

    // Radius circle
    if (radius) {
      const circle = L.circle(center, {
        radius: radius * 1000, color:'#F89A1F', fillColor:'#F89A1F',
        fillOpacity: 0.12, weight: 2, dashArray:'6, 6'
      }).addTo(map);
      layersRef.current.push(circle);
    }

    // Markers with custom orange icons
    markers.forEach(m => {
      const color = m.color || '#F89A1F';
      const html = `<div style="background:${color};width:24px;height:24px;border-radius:50% 50% 50% 0;
        transform:rotate(-45deg);border:2px solid #fff;box-shadow:0 2px 4px rgba(0,0,0,.3);
        display:flex;align-items:center;justify-content:center;">
        <span style="transform:rotate(45deg);color:#fff;font-size:11px;font-weight:700;font-family:sans-serif;">${m.label || ''}</span>
      </div>`;
      const icon = L.divIcon({ html, className:'', iconSize:[24,24], iconAnchor:[12,24] });
      const marker = L.marker([m.lat, m.lng], { icon }).addTo(map);
      if (m.popup) marker.bindPopup(m.popup);
      if (onMarkerClick) marker.on('click', () => onMarkerClick(m));
      layersRef.current.push(marker);
    });

    // Route polyline
    if (routeFrom && routeTo) {
      const line = L.polyline([routeFrom, routeTo], {
        color:'#F89A1F', weight:4, opacity:0.7, dashArray:'8, 8'
      }).addTo(map);
      layersRef.current.push(line);
      // Auto-fit bounds
      map.fitBounds(line.getBounds(), { padding:[40,40] });
    }
  }, [markers, radius, center, routeFrom, routeTo, onMarkerClick]);

  return (
    <div ref={mapRef} style={{ height, width:'100%', borderRadius:'var(--radius-md)', overflow:'hidden', zIndex:1 }}/>
  );
}

/* --- MapSearch - browse with radius --- */
function MapSearch({ onSelect }) {
  const [center, setCenter] = useState([-26.2041, 28.0473]); // Joburg default
  const [radius, setRadius] = useState(15);
  const [selectedCity, setSelectedCity] = useState('Johannesburg');

  // Filter listings within radius
  const haversine = (a, b) => {
    const R = 6371;
    const dLat = (b[0]-a[0]) * Math.PI / 180;
    const dLng = (b[1]-a[1]) * Math.PI / 180;
    const lat1 = a[0] * Math.PI / 180, lat2 = b[0] * Math.PI / 180;
    const x = Math.sin(dLat/2)**2 + Math.cos(lat1)*Math.cos(lat2)*Math.sin(dLng/2)**2;
    return 2 * R * Math.asin(Math.sqrt(x));
  };

  const nearbyListings = PRODUCTS
    .map(p => ({ ...p, coords: CITY_COORDS[p.location] }))
    .filter(p => p.coords && haversine(center, p.coords) <= radius);

  const markers = [
    ...nearbyListings.map((p, i) => ({
      lat: p.coords[0] + (Math.random()-0.5)*0.02, // jitter so they don't overlap
      lng: p.coords[1] + (Math.random()-0.5)*0.02,
      label: 'R',
      color: '#F89A1F',
      popup: `<b>${p.title}</b><br/>R ${p.price.toLocaleString('en-ZA')} - ${p.location}<br/>${p.seller}`,
    })),
    ...PICKUP_POINTS
      .filter(pt => haversine(center, [pt.lat, pt.lng]) <= radius * 1.5)
      .map(pt => ({
        lat: pt.lat, lng: pt.lng, label:'P', color:'#2D7AC7',
        popup: `<b>${pt.name}</b><br/>Pickup partner: ${pt.partner}`,
      })),
  ];

  return (
    <div>
      <div style={{display:'flex',justifyContent:'space-between',alignItems:'center',marginBottom:16,gap:12,flexWrap:'wrap'}}>
        <div>
          <h2 style={{margin:0}}>Browse on map</h2>
          <p style={{color:'var(--ink-500)',fontSize:13,margin:'4px 0 0'}}>
            {nearbyListings.length} listings within {radius} km of {selectedCity}
          </p>
        </div>
        <div style={{display:'flex',gap:8,alignItems:'center'}}>
          <select value={selectedCity} onChange={e => {
            const city = e.target.value;
            setSelectedCity(city);
            setCenter(CITY_COORDS[city]);
          }} style={{padding:'8px 12px',border:'1.5px solid var(--ink-200)',borderRadius:'var(--radius-sm)',
            fontFamily:'var(--font-body)',fontSize:13,background:'var(--paper)'}}>
            {Object.keys(CITY_COORDS).slice(0,12).map(c => <option key={c} value={c}>{c}</option>)}
          </select>
          <div style={{display:'flex',alignItems:'center',gap:8,fontSize:13,fontFamily:'var(--font-body)'}}>
            <Icon name="map-pin" size={14}/>
            <input type="range" min={2} max={50} step={1} value={radius}
              onChange={e => setRadius(+e.target.value)}
              style={{accentColor:'var(--brand-orange)',width:140}}/>
            <span style={{fontFamily:'var(--font-mono)',fontWeight:700,minWidth:48}}>{radius} km</span>
          </div>
        </div>
      </div>

      <div style={{...panelStyle,padding:0,overflow:'hidden'}}>
        <LeafletMap center={center} zoom={radius > 25 ? 9 : radius > 10 ? 10 : 11}
          height={420} markers={markers} radius={radius}/>
      </div>

      <div style={{display:'flex',gap:16,marginTop:12,fontSize:12,color:'var(--ink-500)'}}>
        <div style={{display:'flex',alignItems:'center',gap:6}}>
          <div style={{width:12,height:12,borderRadius:'50% 50% 50% 0',transform:'rotate(-45deg)',background:'#F89A1F'}}/>
          Listings
        </div>
        <div style={{display:'flex',alignItems:'center',gap:6}}>
          <div style={{width:12,height:12,borderRadius:'50% 50% 50% 0',transform:'rotate(-45deg)',background:'#2D7AC7'}}/>
          Pickup points (PEP / Pargo / Paxi)
        </div>
        <div style={{display:'flex',alignItems:'center',gap:6}}>
          <div style={{width:16,height:4,background:'#F89A1F',opacity:.3,borderRadius:2}}/>
          {radius} km search radius
        </div>
      </div>
    </div>
  );
}

/* --- DriverLiveMap - live tracking for orders --- */
function DriverLiveMap({ pickup, dropoff, driver, height = 220 }) {
  const [driverPos, setDriverPos] = useState(pickup);
  const stepRef = useRef(0);

  // Animate driver position from pickup -> dropoff
  useEffect(() => {
    if (!pickup || !dropoff) return;
    const id = setInterval(() => {
      stepRef.current = (stepRef.current + 0.02) % 1;
      const t = stepRef.current;
      setDriverPos([
        pickup[0] + (dropoff[0] - pickup[0]) * t,
        pickup[1] + (dropoff[1] - pickup[1]) * t,
      ]);
    }, 1500);
    return () => clearInterval(id);
  }, [pickup, dropoff]);

  const markers = [
    { lat: pickup[0], lng: pickup[1], label:'A', color:'#1F1A17', popup:'Pickup' },
    { lat: dropoff[0], lng: dropoff[1], label:'B', color:'#2F9E5A', popup:'Delivery' },
    { lat: driverPos[0], lng: driverPos[1], label:'D', color:'#F89A1F', popup:`Driver: ${driver || 'Bongani K.'}` },
  ];

  return (
    <LeafletMap center={driverPos} zoom={12} height={height}
      markers={markers} routeFrom={pickup} routeTo={dropoff}/>
  );
}

Object.assign(window, { LeafletMap, MapSearch, DriverLiveMap, CITY_COORDS, PICKUP_POINTS });
