// Real Umm al-Fahm map (CARTO/OSM tiles stitched, z=15, 1024×1024 ≈ 4km square).
// Pin positions precomputed in pixel coords of the 1024×1024 source.

const MAP_IMG = 'assets/umm-al-fahm-map.png';
const MAP_NATIVE = 1024;

// Pin pixel positions on the 1024×1024 source (computed at z=15)
const PIN_COORDS = {
  CENTER:  { x: 611, y: 513 },
  PICKUP:  { x: 662, y: 504 },
  DROPOFF: { x: 753, y: 712 },
  DRIVER:  { x: 541, y: 402 },
  o1: { x: 662, y: 504 },
  o2: { x: 559, y: 648 },
  o3: { x: 513, y: 557 },
  o4: { x: 765, y: 480 },
  o5: { x: 681, y: 692 },
  o6: { x: 632, y: 601 },
};

const VERTICAL_COLOR = {
  food:    '#E11D48',
  parcel:  '#2563EB',
  grocery: '#16A34A',
};

// ─────────────────────────────────────────────────────────────
// Pin variants
// ─────────────────────────────────────────────────────────────

// Pool pin — vertical-colored pin + payout badge attached. Glove-friendly.
function PoolPin({ x, y, color, payout, bonus, kind, selected = false, onClick }) {
  return (
    <div className="tap" onClick={onClick} style={{
      position: 'absolute',
      left: x, top: y,
      transform: 'translate(-50%, -100%)',
      filter: 'drop-shadow(0 6px 12px rgba(0,0,0,0.25))',
      zIndex: selected ? 5 : 2,
    }}>
      {/* Pin body */}
      <div style={{
        position: 'relative',
        display: 'flex', flexDirection: 'column', alignItems: 'center',
      }}>
        {/* Payout badge attached above pin */}
        <div style={{
          background: color, color: '#fff',
          fontFamily: 'inherit', fontWeight: 800,
          padding: '4px 10px 4px 8px',
          borderRadius: 999,
          fontSize: 14, lineHeight: 1,
          whiteSpace: 'nowrap',
          marginBottom: -2,
          display: 'flex', alignItems: 'center', gap: 4,
          border: '2px solid #fff',
          boxShadow: '0 2px 6px rgba(0,0,0,0.2)',
        }}>
          {kind && <Icon name={{food:'food',parcel:'package',grocery:'cart'}[kind]} size={12} color="#fff" />}
          <span className="num">₪{payout + (bonus || 0)}</span>
          {bonus > 0 && <span style={{
            background: '#FCD34D', color: '#7C2D12',
            fontSize: 9, fontWeight: 900,
            padding: '1px 4px', borderRadius: 4, marginInlineStart: 2,
          }}>+</span>}
        </div>
        {/* Pin teardrop */}
        <svg width={selected ? 36 : 30} height={selected ? 42 : 36} viewBox="0 0 30 36">
          {selected && <circle cx="15" cy="13" r="14" fill={color} fillOpacity="0.22" />}
          <path d="M15 2 C 22 2, 27 7, 27 14 C 27 22, 18 30, 15 34 C 12 30, 3 22, 3 14 C 3 7, 8 2, 15 2 Z"
                fill={color} stroke="#fff" strokeWidth="2.5" />
          <circle cx="15" cy="13" r="5" fill="#fff" />
        </svg>
      </div>
    </div>
  );
}

// Driver "you are here" pin — pulsing teal circle
function DriverPin({ x, y }) {
  return (
    <div style={{
      position: 'absolute', left: x, top: y,
      transform: 'translate(-50%, -50%)', zIndex: 3,
    }}>
      <div style={{ position: 'relative', width: 28, height: 28 }}>
        <div style={{
          position: 'absolute', inset: -10, borderRadius: '50%',
          background: 'var(--primary)', opacity: 0.22,
          animation: 'radar-soft 2.4s ease-out infinite',
        }} />
        <div style={{
          position: 'absolute', inset: 0, borderRadius: '50%',
          background: 'var(--primary)',
          border: '3px solid white',
          boxShadow: '0 2px 10px rgba(0,0,0,0.35)',
        }} />
        <div style={{
          position: 'absolute', inset: 8, borderRadius: '50%', background: 'white',
        }} />
      </div>
    </div>
  );
}

// Route flag (pickup or dropoff) — small flag pin
function RouteFlag({ x, y, color, label, big = false }) {
  const s = big ? 36 : 28;
  return (
    <div style={{
      position: 'absolute', left: x, top: y,
      transform: 'translate(-50%, -100%)', zIndex: 3,
      filter: 'drop-shadow(0 4px 8px rgba(0,0,0,0.25))',
    }}>
      <svg width={s} height={s * 1.2} viewBox="0 0 30 36">
        <path d="M15 2 C 22 2, 27 7, 27 14 C 27 22, 18 30, 15 34 C 12 30, 3 22, 3 14 C 3 7, 8 2, 15 2 Z"
              fill={color} stroke="#fff" strokeWidth="2.5" />
        <circle cx="15" cy="13" r="5" fill="#fff" />
      </svg>
    </div>
  );
}

// ─────────────────────────────────────────────────────────────
// MapView — real Umm al-Fahm static image + pins
// `mode`: 'pool' | 'route' | 'driver-only' | 'empty'
// ─────────────────────────────────────────────────────────────
// Off-screen pin indicator — when a pool pin is outside the visible
// map area, show a smaller marker on the edge with a chevron pointing
// toward its true position and the payout.
function OffScreenPin({ x, y, dir, color, payout, kind, onClick }) {
  // dir: 'top' | 'bottom' | 'left' | 'right' — which edge it's clamped to
  // We point the chevron in the direction of the true pin
  const chevRot = { top: 0, right: 90, bottom: 180, left: 270 }[dir] || 0;
  return (
    <div className="tap" onClick={onClick} style={{
      position: 'absolute',
      left: x, top: y,
      transform: 'translate(-50%, -50%)',
      zIndex: 4,
      filter: 'drop-shadow(0 4px 10px rgba(0,0,0,0.25))',
    }}>
      <div style={{
        background: color, color: '#fff',
        fontFamily: 'inherit', fontWeight: 800,
        padding: '5px 10px',
        borderRadius: 999,
        fontSize: 12, lineHeight: 1,
        whiteSpace: 'nowrap',
        display: 'flex', alignItems: 'center', gap: 5,
        border: '2px solid #fff',
        opacity: 0.92,
      }}>
        {/* chevron rotated to point at off-screen direction */}
        <svg width="10" height="10" viewBox="0 0 24 24" fill="none"
             stroke="#fff" strokeWidth="3" strokeLinecap="round" strokeLinejoin="round"
             style={{ transform: `rotate(${chevRot}deg)` }}>
          <polyline points="6 15 12 9 18 15" />
        </svg>
        {kind && <Icon name={{food:'food',parcel:'package',grocery:'cart'}[kind]} size={11} color="#fff" />}
        <span className="num">₪{payout}</span>
      </div>
    </div>
  );
}

// Map z=15 ground resolution at lat ~32.5°: ~4.03 m/source-px.
// At display scale 0.6 → ~6.72 m/display-px → 1 km ≈ 149 display-px.
const M_PER_SOURCE_PX = 4.03;
function kmToDisplayPx(km, scale) {
  return (km * 1000 / M_PER_SOURCE_PX) * scale;
}

// Image centre lat/lng — defaults match the bundled umm-al-fahm-map.png tile
// (OSM tiles stitched around this point at z=15). Overridden at runtime by the
// server config so the city centre is NOT hardcoded: admins set cityLat/cityLng
// in Settings. If you change the city you also swap the map image to match.
const DEFAULT_CENTRE_LAT = 32.5167;
const DEFAULT_CENTRE_LNG = 35.1500;

function mapCentre() {
  const c = window.RESDRI_CONFIG || {};
  return {
    lat: typeof c.cityLat === 'number' ? c.cityLat : DEFAULT_CENTRE_LAT,
    lng: typeof c.cityLng === 'number' ? c.cityLng : DEFAULT_CENTRE_LNG,
  };
}

// Project a real-world lat/lng to the 1024×1024 source-pixel space.
// Small-area approximation — accurate enough across a 4 km tile.
function latLngToSourcePx(lat, lng) {
  if (typeof lat !== 'number' || typeof lng !== 'number') return null;
  const { lat: cLat, lng: cLng } = mapCentre();
  const cosLat = Math.cos(cLat * Math.PI / 180);
  const dxM = (lng - cLng) * 111320 * cosLat;
  const dyM = -(lat - cLat) * 111320; // y grows downward
  return { x: 512 + dxM / M_PER_SOURCE_PX, y: 512 + dyM / M_PER_SOURCE_PX };
}

// Out-of-radius indicator — pinned to the visible-area edge along the direction
// from the driver. Visually distinct from in-radius off-screen pins (dim/muted).
function OutOfRadiusPin({ x, y, dir, color, payout, distanceKm, onClick }) {
  const chevRot = { top: 0, right: 90, bottom: 180, left: 270 }[dir] || 0;
  return (
    <div className="tap" onClick={onClick} style={{
      position: 'absolute',
      left: x, top: y,
      transform: 'translate(-50%, -50%)',
      zIndex: 4,
      filter: 'drop-shadow(0 4px 8px rgba(0,0,0,0.18))',
    }}>
      <div style={{
        background: 'rgba(255,255,255,0.94)',
        color: '#475569',
        fontFamily: 'inherit', fontWeight: 800,
        padding: '5px 9px 5px 7px',
        borderRadius: 999,
        fontSize: 11, lineHeight: 1,
        whiteSpace: 'nowrap',
        display: 'flex', alignItems: 'center', gap: 5,
        border: `2px solid ${color}`,
        opacity: 0.92,
        backdropFilter: 'blur(4px)',
        WebkitBackdropFilter: 'blur(4px)',
      }}>
        <svg width="10" height="10" viewBox="0 0 24 24" fill="none"
             stroke={color} strokeWidth="3" strokeLinecap="round" strokeLinejoin="round"
             style={{ transform: `rotate(${chevRot}deg)` }}>
          <polyline points="6 15 12 9 18 15" />
        </svg>
        <span style={{
          display: 'inline-flex', alignItems: 'center', gap: 2,
          color: color, fontWeight: 800,
        }}>
          <span className="num">₪{payout}</span>
        </span>
        <span style={{ color: '#94A3B8', fontWeight: 700 }}>·</span>
        <span style={{ color: '#475569', fontWeight: 700 }}>
          <span className="num">{distanceKm.toFixed(1)}</span> كم
        </span>
      </div>
    </div>
  );
}

// Compute where a ray from `from` through `to` exits the rectangle `area`.
// Returns { x, y, dir } — dir is which edge it hit.
function rayToEdge(from, to, area, pad = 22) {
  const dx = to.x - from.x;
  const dy = to.y - from.y;
  if (dx === 0 && dy === 0) return { x: from.x, y: from.y, dir: 'top' };
  const ts = [];
  if (dx > 0) ts.push({ t: (area.right - pad - from.x) / dx, dir: 'right' });
  if (dx < 0) ts.push({ t: (area.left + pad - from.x) / dx, dir: 'left' });
  if (dy > 0) ts.push({ t: (area.bottom - pad - from.y) / dy, dir: 'bottom' });
  if (dy < 0) ts.push({ t: (area.top + pad - from.y) / dy, dir: 'top' });
  const valid = ts.filter(s => s.t > 0).sort((a, b) => a.t - b.t);
  const hit = valid[0] || { t: 0, dir: 'top' };
  return { x: from.x + hit.t * dx, y: from.y + hit.t * dy, dir: hit.dir };
}

function MapView({
  mode = 'pool',
  scale = 0.60,
  offsetX = -125,
  offsetY = -21,
  dim = false,
  selectedOrderId = null,
  onPickPin,
  height = '100%',
  driverPos = 'DRIVER',
  driverLatLng = null,       // {lat, lng} — overrides driverPos when provided
  orders = null,
  visibleArea = null,
  radiusKm = null,
  outOfRadiusOrders = null,
}) {
  // Driver position resolution priority: real lat/lng > named pose > city centre
  const drv = driverLatLng
    ? (latLngToSourcePx(driverLatLng.lat, driverLatLng.lng) || PIN_COORDS.DRIVER)
    : driverPos === 'route-pickup' ? { x: 610, y: 460 }
    : driverPos === 'route-dropoff' ? { x: 710, y: 610 }
    : PIN_COORDS.DRIVER;

  // Pool pins are always supplied by the caller from live orders. No demo pins.
  const poolPins = orders || [];

  const route = mode === 'route' ? {
    from: PIN_COORDS.PICKUP, to: PIN_COORDS.DROPOFF,
  } : null;

  // Project pixel-coord to screen
  const proj = (p) => ({ x: p.x * scale + offsetX, y: p.y * scale + offsetY });

  return (
    <div style={{
      position: 'relative', width: '100%', height,
      overflow: 'hidden', background: '#E8EDDD',
    }}>
      <img src={MAP_IMG} alt="" draggable={false} style={{
        position: 'absolute',
        width: MAP_NATIVE * scale,
        height: MAP_NATIVE * scale,
        left: offsetX, top: offsetY,
        userSelect: 'none', pointerEvents: 'none',
        filter: dim ? 'saturate(0.4) brightness(0.95) opacity(0.65)' : 'none',
        transition: 'filter 0.3s',
      }} />

      {/* Dim overlay for offline */}
      {dim && <div style={{
        position: 'absolute', inset: 0,
        background: 'linear-gradient(180deg, rgba(15,23,42,0.18) 0%, rgba(15,23,42,0.04) 50%, rgba(15,23,42,0.18) 100%)',
        pointerEvents: 'none',
      }} />}

      {/* Route polyline */}
      {route && (() => {
        const a = proj(route.from);
        const b = proj(route.to);
        // simple bezier curve between
        return (
          <svg style={{ position: 'absolute', inset: 0, width: '100%', height: '100%', pointerEvents: 'none' }}>
            <path d={`M ${a.x} ${a.y} Q ${(a.x + b.x)/2 + 30} ${(a.y + b.y)/2 - 40} ${b.x} ${b.y}`}
                  fill="none" stroke="#fff" strokeWidth="9" strokeLinecap="round" />
            <path d={`M ${a.x} ${a.y} Q ${(a.x + b.x)/2 + 30} ${(a.y + b.y)/2 - 40} ${b.x} ${b.y}`}
                  fill="none" stroke="var(--primary)" strokeWidth="5" strokeLinecap="round" strokeDasharray="0 0" />
          </svg>
        );
      })()}

      {/* Route flags */}
      {route && (
        <>
          <RouteFlag {...proj(route.from)} color="var(--primary)" big />
          <RouteFlag {...proj(route.to)}   color="var(--danger)" big />
        </>
      )}

      {/* Working-radius circle around the driver */}
      {radiusKm && mode === 'pool' && !dim && (() => {
        const c = proj(drv);
        const r = kmToDisplayPx(radiusKm, scale);
        return (
          <svg style={{
            position: 'absolute', inset: 0, width: '100%', height: '100%',
            pointerEvents: 'none', zIndex: 1,
          }}>
            {/* Filled translucent circle */}
            <circle cx={c.x} cy={c.y} r={r}
              fill="var(--primary)" fillOpacity="0.08"
              stroke="var(--primary)" strokeOpacity="0.55"
              strokeWidth="2" strokeDasharray="6 5" />
            {/* Label on the radius edge — at the bottom of the circle */}
            <g transform={`translate(${c.x},${c.y + r})`}>
              <rect x="-32" y="-12" width="64" height="22" rx="11"
                fill="var(--primary)" />
              <text x="0" y="3" textAnchor="middle"
                fontFamily="inherit" fontSize="12" fontWeight="800" fill="#fff">
                {radiusKm.toFixed(1).replace(/\.0$/, '')} كم
              </text>
            </g>
          </svg>
        );
      })()}

      {/* Pool pins (with off-screen indicators for pins outside the visible map area) */}
      {poolPins.map((p) => {
        const sp = proj(p.pos);
        // Determine if pin is within visible area (default to whole container if none provided)
        const va = visibleArea || { top: 0, left: 0, right: 9999, bottom: 9999 };
        const PAD = 28; // clamp inset from the edge
        const inside = sp.x >= va.left + PAD && sp.x <= va.right - PAD
                    && sp.y >= va.top + PAD && sp.y <= va.bottom - PAD;
        if (inside) {
          return (
            <PoolPin key={p.id}
              x={sp.x} y={sp.y}
              color={VERTICAL_COLOR[p.kind]}
              payout={p.payout} bonus={p.bonus} kind={p.kind}
              selected={selectedOrderId === p.id}
              onClick={() => onPickPin && onPickPin(p.id)}
            />
          );
        }
        // Out of visible area — clamp to edge, determine direction
        let dir = 'top';
        let cx = Math.max(va.left + PAD, Math.min(va.right - PAD, sp.x));
        let cy = Math.max(va.top + PAD, Math.min(va.bottom - PAD, sp.y));
        // Pick the edge that's most relevant
        const dxR = sp.x - (va.right - PAD);
        const dxL = (va.left + PAD) - sp.x;
        const dyT = (va.top + PAD) - sp.y;
        const dyB = sp.y - (va.bottom - PAD);
        const max = Math.max(dxR, dxL, dyT, dyB);
        if (max === dyB) { dir = 'bottom'; cy = va.bottom - PAD; }
        else if (max === dyT) { dir = 'top'; cy = va.top + PAD; }
        else if (max === dxR) { dir = 'right'; cx = va.right - PAD; }
        else { dir = 'left'; cx = va.left + PAD; }

        return (
          <OffScreenPin key={p.id}
            x={cx} y={cy} dir={dir}
            color={VERTICAL_COLOR[p.kind]}
            payout={p.payout + (p.bonus || 0)}
            kind={p.kind}
            onClick={() => onPickPin && onPickPin(p.id)}
          />
        );
      })}

      {/* Driver */}
      {(mode !== 'empty' || dim) && <DriverPin {...proj(drv)} />}

      {/* OUT-OF-RADIUS edge indicators — for each order outside the working radius,
          show a muted indicator stuck to the visible-area edge along the ray from
          the driver toward the order's true location. */}
      {outOfRadiusOrders && outOfRadiusOrders.length > 0 && (() => {
        const drvScreen = proj(drv);
        const va = visibleArea || { top: 0, left: 0, right: 9999, bottom: 9999 };
        return outOfRadiusOrders.map((p) => {
          const target = proj(p.pos);
          const edge = rayToEdge(drvScreen, target, va, 22);
          return (
            <OutOfRadiusPin key={'oor-' + p.id}
              x={edge.x} y={edge.y} dir={edge.dir}
              color={VERTICAL_COLOR[p.kind]}
              payout={p.payout + (p.bonus || 0)}
              distanceKm={p.distanceKm}
              onClick={() => onPickPin && onPickPin(p.id)}
            />
          );
        });
      })()}
    </div>
  );
}

Object.assign(window, {
  MapView, PIN_COORDS, VERTICAL_COLOR, kmToDisplayPx, latLngToSourcePx,
  mapCentre,
});
