// Direction-C extras: per-model car SVGs, Hanoi map with real landmarks,
// animation hooks, gesture helpers, glass shimmer, micro-interactions.

// ─────────────────────────────────────────────────────────────
// Per-model top-down car (proportions reflect actual silhouettes).
// width is total render width; the SVG keeps its aspect ratio.
// ─────────────────────────────────────────────────────────────
const CAR_VARIANTS = {
  cx5:   { aspect: 100 / 220, kind: 'suv',     // taller, more upright SUV
           roofTop: 60, roofBot: 156, hood: 24, tail: 192 },
  cx30:  { aspect: 100 / 200, kind: 'compact', // shorter crossover
           roofTop: 56, roofBot: 138, hood: 22, tail: 172 },
  mazda3:{ aspect: 100 / 210, kind: 'sedan',   // sedan — sloped roof, longer rear
           roofTop: 58, roofBot: 132, hood: 24, tail: 186 },
};

function CarTopdownModel({ model = 'cx5', width = 140, color = '#7B1B1B' }) {
  // Photo override: CX-30 has a real top-down render. Other models fall back
  // to the schematic SVG below.
  if (model === 'cx30') {
    return (
      <img src="assets/cars/cx30-top.png" alt="Mazda CX-30 top view"
           style={{ width, height: 'auto', display: 'block', filter: 'drop-shadow(0 12px 24px rgba(0,0,0,0.4))' }}/>
    );
  }
  const v = CAR_VARIANTS[model] || CAR_VARIANTS.cx5;
  const totalH = width / v.aspect;
  const stroke = 'rgba(255,255,255,0.08)';
  return (
    <svg width={width} viewBox={`0 0 100 ${100 / v.aspect}`} fill="none" style={{ display: 'block' }}>
      <defs>
        <linearGradient id={`body-${model}`} x1="0" x2="0" y1="0" y2="1">
          <stop offset="0%" stopColor={color} stopOpacity="0.95"/>
          <stop offset="100%" stopColor={color} stopOpacity="0.7"/>
        </linearGradient>
      </defs>
      {/* body */}
      <path d={`M20 30 Q22 18 35 14 L65 14 Q78 18 80 30 L82 80 L82 ${100/v.aspect - 50} Q80 ${100/v.aspect - 20} 65 ${100/v.aspect - 14} L35 ${100/v.aspect - 14} Q20 ${100/v.aspect - 20} 18 ${100/v.aspect - 50} L18 80 Z`}
            fill={`url(#body-${model})`} stroke={stroke}/>
      {/* hood crease */}
      <path d="M30 32 L40 24 L60 24 L70 32" stroke="rgba(0,0,0,0.25)" strokeWidth="1.2" fill="none"/>
      {/* windshield */}
      <path d={`M28 ${v.roofTop} L30 ${v.hood + 16} L70 ${v.hood + 16} L72 ${v.roofTop} Z`} fill="rgba(0,0,0,0.55)"/>
      {/* roof glass — sedans have a slope */}
      {v.kind === 'sedan' ? (
        <path d={`M28 ${v.roofTop + 2} L72 ${v.roofTop + 2} L74 ${v.roofBot - 6} L26 ${v.roofBot - 6} Z`} fill="rgba(0,0,0,0.4)"/>
      ) : (
        <rect x="28" y={v.roofTop + 2} width="44" height={v.roofBot - v.roofTop - 2} rx="6" fill="rgba(0,0,0,0.4)"/>
      )}
      {/* rear window */}
      <path d={`M28 ${v.roofBot} L30 ${v.tail - 28} L70 ${v.tail - 28} L72 ${v.roofBot} Z`} fill="rgba(0,0,0,0.5)"/>
      {/* mirrors */}
      <ellipse cx="16" cy={v.roofTop - 10} rx="4" ry="6" fill={color}/>
      <ellipse cx="84" cy={v.roofTop - 10} rx="4" ry="6" fill={color}/>
      {/* headlights */}
      <path d={`M22 22 L30 18 L30 24 L22 28 Z`} fill="rgba(255,240,200,0.85)"/>
      <path d={`M78 22 L70 18 L70 24 L78 28 Z`} fill="rgba(255,240,200,0.85)"/>
      {/* signature LED line — Mazda's lower DRL */}
      <path d="M32 28 L46 27.4" stroke="rgba(255,235,180,0.9)" strokeWidth="1" strokeLinecap="round"/>
      <path d="M68 28 L54 27.4" stroke="rgba(255,235,180,0.9)" strokeWidth="1" strokeLinecap="round"/>
      {/* tail lights */}
      <rect x="22" y={v.tail - 8} width="9" height="6" rx="1" fill="rgba(220,60,60,0.7)"/>
      <rect x="69" y={v.tail - 8} width="9" height="6" rx="1" fill="rgba(220,60,60,0.7)"/>
    </svg>
  );
}

// Side-view per model — keeps existing CarSide as fallback but adjusts proportions.
function CarSideModel({ model = 'cx5', width = 240, color = '#7B1B1B' }) {
  // Photo override: CX-30 uses a 3/4 front render in place of the side
  // silhouette across the app's hero cards.
  if (model === 'cx30') {
    return (
      <img src="assets/cars/cx30-front.png" alt="Mazda CX-30"
           style={{ width, height: 'auto', display: 'block', filter: 'drop-shadow(0 14px 28px rgba(0,0,0,0.45))' }}/>
    );
  }
  const m = {
    cx5:    { ratio: 240/82, roof: 36 },
    cx30:   { ratio: 240/82, roof: 36 },
    mazda3: { ratio: 240/72, roof: 30 },
  }[model] || { ratio: 240/82, roof: 36 };
  const h = width / m.ratio;
  return (
    <svg width={width} height={h} viewBox="0 0 240 90" preserveAspectRatio="xMidYMax meet" fill="none" style={{ display: 'block' }}>
      <path d={model === 'mazda3'
        ? "M10 70 Q10 60 18 58 L40 56 Q56 30 92 28 L138 28 Q176 30 196 50 L220 56 Q232 58 232 68 L232 74 L10 74 Z"
        : "M10 70 Q10 60 18 58 L40 56 Q52 38 78 36 L150 36 Q180 36 200 52 L220 56 Q232 58 232 68 L232 74 L10 74 Z"
      } fill={color}/>
      <path d={model === 'mazda3'
        ? "M58 56 Q72 34 96 32 L140 32 Q166 32 184 56 Z"
        : "M60 56 Q72 42 90 42 L140 42 Q160 42 174 56 Z"
      } fill="rgba(0,0,0,0.6)"/>
      <path d="M118 36 L118 56" stroke="rgba(255,255,255,0.08)" strokeWidth="1"/>
      <circle cx="60" cy="74" r="14" fill="#111"/><circle cx="60" cy="74" r="6" fill="#2a2a2e"/>
      <circle cx="190" cy="74" r="14" fill="#111"/><circle cx="190" cy="74" r="6" fill="#2a2a2e"/>
    </svg>
  );
}

// ─────────────────────────────────────────────────────────────
// Hanoi map — Hồ Gươm, Old Quarter, Hồ Tây hint, Văn Miếu, etc.
// ─────────────────────────────────────────────────────────────
function HanoiMap({ width = '100%', height = '100%' }) {
  const land  = '#0E1318';
  const road  = 'rgba(255,255,255,0.045)';
  const major = 'rgba(255,255,255,0.09)';
  const water = '#0C2434';
  const park  = '#11221A';
  return (
    <svg width={width} height={height} viewBox="0 0 400 700" preserveAspectRatio="xMidYMid slice"
         style={{ position: 'absolute', inset: 0 }}>
      <rect width="400" height="700" fill={land}/>
      {/* Hồ Tây (partial, top-left) */}
      <path d="M-40 -20 Q60 30 100 110 Q120 180 60 220 Q-20 240 -40 180 Z" fill={water}/>
      <text x="20" y="120" fill="rgba(200,220,240,0.35)" fontSize="9" fontFamily="ui-monospace, monospace" letterSpacing="1">HỒ TÂY</text>

      {/* River faint to east */}
      <path d="M380 0 Q360 200 380 400 Q400 600 380 700 L420 700 L420 0 Z" fill={water} opacity="0.6"/>

      {/* Văn Miếu park (lower left) */}
      <rect x="40" y="500" width="80" height="60" rx="4" fill={park}/>
      <text x="46" y="538" fill="rgba(180,220,180,0.45)" fontSize="7" fontFamily="ui-monospace, monospace">VĂN MIẾU</text>

      {/* Lenin park */}
      <rect x="200" y="540" width="120" height="80" rx="6" fill={park}/>
      <text x="208" y="588" fill="rgba(180,220,180,0.45)" fontSize="7" fontFamily="ui-monospace, monospace">CV LÊ NIN</text>

      {/* Old Quarter dense grid (top center-right) */}
      {Array.from({ length: 9 }).map((_, i) => (
        <line key={'oq-h'+i} x1="140" y1={140 + i*16} x2="300" y2={140 + i*16} stroke={road} strokeWidth="6"/>
      ))}
      {Array.from({ length: 8 }).map((_, i) => (
        <line key={'oq-v'+i} x1={150 + i*18} y1="140" x2={150 + i*18} y2="280" stroke={road} strokeWidth="6"/>
      ))}

      {/* Hồ Gươm (central oval, slightly NW-tilted) */}
      <ellipse cx="240" cy="320" rx="48" ry="22" fill={water} transform="rotate(-8 240 320)"/>
      <circle cx="240" cy="318" r="3" fill="rgba(180,200,220,0.4)"/>
      <text x="222" y="358" fill="rgba(200,220,240,0.55)" fontSize="9" fontFamily="ui-monospace, monospace" letterSpacing="0.5">HỒ GƯƠM</text>

      {/* Major arteries */}
      {/* Phố Huế / Bà Triệu (N-S) */}
      <line x1="220" y1="0" x2="220" y2="700" stroke={major} strokeWidth="11"/>
      <text x="226" y="450" fill="rgba(255,255,255,0.35)" fontSize="8" fontFamily="ui-monospace, monospace" letterSpacing="1">BÀ TRIỆU</text>
      {/* Trần Hưng Đạo / Lê Duẩn (E-W) */}
      <line x1="0" y1="410" x2="400" y2="410" stroke={major} strokeWidth="11"/>
      <text x="20" y="404" fill="rgba(255,255,255,0.35)" fontSize="8" fontFamily="ui-monospace, monospace" letterSpacing="1">TRẦN HƯNG ĐẠO</text>
      {/* Hai Bà Trưng (E-W upper) */}
      <line x1="0" y1="290" x2="400" y2="290" stroke={major} strokeWidth="9"/>
      {/* Lê Duẩn lower */}
      <line x1="80" y1="500" x2="400" y2="500" stroke={major} strokeWidth="9"/>

      {/* Secondary grid */}
      {[80, 140, 180, 360, 460, 560, 640].map((y) => (
        <line key={'h'+y} x1="-30" y1={y} x2="430" y2={y} stroke={road} strokeWidth="3"/>
      ))}
      {[60, 100, 280, 330].map((x) => (
        <line key={'v'+x} x1={x} y1="-30" x2={x} y2="730" stroke={road} strokeWidth="3"/>
      ))}

      {/* Building blocks scattered */}
      {[
        [50,170,30,20],[90,170,28,16],[50,200,24,20],[80,200,28,18],
        [40,330,40,30],[40,370,32,20],[280,170,18,16],[310,170,22,18],[340,170,16,16],
        [280,200,18,16],[310,200,22,18],[340,200,16,16],
        [140,330,28,20],[174,330,24,18],[260,330,22,18],
        [120,440,40,30],[260,440,30,24],[310,440,40,24],
        [40,620,40,40],[100,620,60,40],[200,640,60,40],[280,640,80,40],
      ].map(([x,y,w,h], i) => (
        <rect key={i} x={x} y={y} width={w} height={h} fill="rgba(255,255,255,0.035)" rx="1"/>
      ))}
    </svg>
  );
}

// POI marker (cafés, gas stations, dealers)
function POI({ left, top, kind = 'fuel', color = '#7CB7FF', label }) {
  return (
    <div style={{ position: 'absolute', left, top, transform: 'translate(-50%, -50%)', display: 'flex', alignItems: 'center', gap: 6, pointerEvents: 'none' }}>
      <div style={{ width: 22, height: 22, borderRadius: 11, background: 'rgba(10,15,20,0.85)',
                    border: `1.5px solid ${color}`, display: 'flex', alignItems: 'center', justifyContent: 'center', color }}>
        {kind === 'fuel' && <Icons.fuel size={12} stroke={2}/>}
        {kind === 'service' && <Icons.wrench size={12} stroke={2}/>}
        {kind === 'park' && <Icons.car size={12} stroke={2}/>}
      </div>
      {label && <span style={{ fontSize: 9, fontFamily: 'ui-monospace, monospace', color: 'rgba(255,255,255,0.55)', whiteSpace: 'nowrap', letterSpacing: 0.5 }}>{label}</span>}
    </div>
  );
}

// ─────────────────────────────────────────────────────────────
// Glass surface — central component for direction C.
// `intensity` 0→1 controls blur/saturation; respects tweaks.
// ─────────────────────────────────────────────────────────────
function GlassC({ children, style = {}, padding = 16, radius = 24, intensity = 1, shimmer = false, accentLine = false, onClick }) {
  const blur = Math.round(8 + 24 * intensity);
  const sat = Math.round(110 + 50 * intensity);
  const a1 = 0.04 + 0.06 * intensity;
  const a2 = 0.015 + 0.025 * intensity;
  return (
    <div onClick={onClick} style={{
      background: `linear-gradient(140deg, rgba(255,255,255,${a1}) 0%, rgba(255,255,255,${a2}) 100%)`,
      backdropFilter: `blur(${blur}px) saturate(${sat}%)`,
      WebkitBackdropFilter: `blur(${blur}px) saturate(${sat}%)`,
      border: '1px solid rgba(255,255,255,0.08)',
      borderRadius: radius,
      padding,
      position: 'relative',
      overflow: 'hidden',
      ...style,
    }}>
      {accentLine && <div style={{ position: 'absolute', top: 0, left: 16, right: 16, height: 1, background: 'linear-gradient(90deg, transparent, rgba(212,165,116,0.5), transparent)' }}/>}
      {shimmer && <Shimmer/>}
      {children}
    </div>
  );
}

// One-shot shimmer sweep — used on cards updating fresh data.
function Shimmer() {
  return (
    <div style={{
      position: 'absolute', inset: 0, pointerEvents: 'none',
      background: 'linear-gradient(110deg, transparent 30%, rgba(212,165,116,0.18) 50%, transparent 70%)',
      animation: 'shimmer-sweep 1.4s ease-in-out infinite',
    }}/>
  );
}

// Inject keyframes once.
if (typeof document !== 'undefined' && !document.getElementById('c-anims')) {
  const s = document.createElement('style');
  s.id = 'c-anims';
  s.textContent = `
    @keyframes shimmer-sweep { 0% { transform: translateX(-60%); } 100% { transform: translateX(60%); } }
    @keyframes c-fade-in { from { transform: translateY(-8px); opacity: 0; } to { transform: none; opacity: 1; } }
    @keyframes c-slide-up { from { transform: translateY(20px); opacity: 0; } to { transform: none; opacity: 1; } }
    @keyframes c-slide-down { from { transform: translateY(-20px); opacity: 0; } to { transform: none; opacity: 1; } }
    @keyframes c-pop { from { transform: scale(0.98); opacity: 0; } to { transform: scale(1); opacity: 1; } }
    @keyframes c-pulse { 0%,100% { transform: scale(1); opacity: 0.5; } 50% { transform: scale(1.4); opacity: 0; } }
    @keyframes c-pulse-strong { 0% { transform: scale(0.9); opacity: 1; } 100% { transform: scale(2); opacity: 0; } }
    @keyframes c-bar-grow { from { transform: scaleX(0); } to { transform: scaleX(1); } }
    @keyframes c-spin { to { transform: rotate(360deg); } }
    @keyframes c-bounce-x { 0%, 100% { transform: translateX(0); } 50% { transform: translateX(2px); } }
    @keyframes c-flash { 0%, 100% { opacity: 0; } 50% { opacity: 0.5; } }
    @keyframes c-fall { from { transform: translateY(-10px); opacity: 0; } to { transform: none; opacity: 1; } }

    /* One-shot reveals use both backwards+forwards fill so the from-state
       applies during delay and the to-state sticks after. Easing is ease-out
       (no overshoot) for a calm, non-bouncy feel. */
    [style*="c-fade-in"], [style*="c-slide-up"], [style*="c-slide-down"],
    [style*="c-pop"], [style*="c-bar-grow"], [style*="c-fall"] {
      animation-fill-mode: both !important;
      animation-timing-function: cubic-bezier(0.16, 1, 0.3, 1) !important;
    }

    .c-stagger > * { animation: c-fade-in 0.5s cubic-bezier(0.16, 1, 0.3, 1) both; }
    .c-stagger > *:nth-child(1) { animation-delay: 0.02s; }
    .c-stagger > *:nth-child(2) { animation-delay: 0.07s; }
    .c-stagger > *:nth-child(3) { animation-delay: 0.12s; }
    .c-stagger > *:nth-child(4) { animation-delay: 0.17s; }
    .c-stagger > *:nth-child(5) { animation-delay: 0.22s; }
    .c-stagger > *:nth-child(6) { animation-delay: 0.27s; }
    .c-stagger > *:nth-child(7) { animation-delay: 0.32s; }
    .c-stagger > *:nth-child(8) { animation-delay: 0.37s; }
    .c-stagger > *:nth-child(9) { animation-delay: 0.42s; }
    .c-stagger > *:nth-child(10) { animation-delay: 0.47s; }
  `;
  document.head.appendChild(s);
}

// ─────────────────────────────────────────────────────────────
// Hooks
// ─────────────────────────────────────────────────────────────
// Tween a value toward target over a duration. Re-runs on target change.
function useTween(target, ms = 600) {
  const [v, setV] = React.useState(target);
  const startV = React.useRef(target);
  React.useEffect(() => {
    const from = v;
    startV.current = from;
    const t0 = performance.now();
    let raf;
    const loop = (t) => {
      const k = Math.min(1, (t - t0) / ms);
      const e = 1 - Math.pow(1 - k, 3);
      setV(from + (target - from) * e);
      if (k < 1) raf = requestAnimationFrame(loop);
    };
    raf = requestAnimationFrame(loop);
    return () => cancelAnimationFrame(raf);
  }, [target]);
  return v;
}

// Pull-to-refresh hook. Returns props to spread on a scroll container,
// plus state for the indicator.
function usePullToRefresh(onRefresh) {
  const [pull, setPull] = React.useState(0);    // 0..1+ where >1 is committed
  const [refreshing, setRefreshing] = React.useState(false);
  const startY = React.useRef(null);
  const containerRef = React.useRef(null);

  const onTouchStart = (e) => {
    if (!containerRef.current) return;
    if (containerRef.current.scrollTop > 0) return;
    startY.current = e.touches ? e.touches[0].clientY : e.clientY;
  };
  const onTouchMove = (e) => {
    if (startY.current == null || refreshing) return;
    const y = e.touches ? e.touches[0].clientY : e.clientY;
    const dy = Math.max(0, y - startY.current);
    if (dy > 0 && containerRef.current.scrollTop <= 0) {
      e.preventDefault?.();
      setPull(Math.min(1.3, dy / 100));
    }
  };
  const onTouchEnd = async () => {
    if (startY.current == null) return;
    startY.current = null;
    if (pull >= 1) {
      setRefreshing(true);
      setPull(1);
      await onRefresh?.();
      setRefreshing(false);
      setPull(0);
    } else {
      setPull(0);
    }
  };

  return {
    bind: {
      ref: containerRef,
      onTouchStart, onTouchMove, onTouchEnd,
      onMouseDown: onTouchStart, onMouseMove: (e) => e.buttons && onTouchMove(e), onMouseUp: onTouchEnd, onMouseLeave: onTouchEnd,
    },
    pull, refreshing,
  };
}

// Swipe-to-dismiss for list items. Returns transform style + handlers + dismissed state.
function useSwipeDismiss(threshold = 100, onDismiss) {
  const [dx, setDx] = React.useState(0);
  const [dismissed, setDismissed] = React.useState(false);
  const startX = React.useRef(null);

  const onStart = (e) => {
    const x = e.touches ? e.touches[0].clientX : e.clientX;
    startX.current = x;
  };
  const onMove = (e) => {
    if (startX.current == null) return;
    const x = e.touches ? e.touches[0].clientX : e.clientX;
    const d = x - startX.current;
    if (d < 0) setDx(d);
  };
  const onEnd = () => {
    if (startX.current == null) return;
    startX.current = null;
    if (dx < -threshold) {
      setDx(-360);
      setDismissed(true);
      setTimeout(() => onDismiss?.(), 250);
    } else {
      setDx(0);
    }
  };
  return {
    bind: {
      onTouchStart: onStart, onTouchMove: onMove, onTouchEnd: onEnd,
      onMouseDown: onStart, onMouseMove: (e) => e.buttons && onMove(e), onMouseUp: onEnd, onMouseLeave: onEnd,
      style: {
        transform: `translateX(${dx}px)`,
        opacity: 1 - Math.min(0.7, Math.abs(dx) / 300),
        transition: startX.current ? 'none' : 'transform .25s, opacity .25s',
      },
    },
    dismissed,
    dx,
  };
}

// ─────────────────────────────────────────────────────────────
// Aurora — animated background gradient. Intensity 0..1.5
// ─────────────────────────────────────────────────────────────
function Aurora({ intensity = 1 }) {
  if (intensity <= 0) return null;
  const a = Math.min(1, intensity);
  return (
    <div style={{
      position: 'absolute', inset: 0, pointerEvents: 'none', zIndex: 0,
      background: `
        radial-gradient(60% 40% at 80% 0%, rgba(212,165,116,${0.20 * a}), transparent 70%),
        radial-gradient(50% 40% at 0% 35%, rgba(124,183,255,${0.16 * a}), transparent 70%),
        radial-gradient(60% 30% at 50% 100%, rgba(212,165,116,${0.10 * a}), transparent 70%)`,
    }}/>
  );
}

Object.assign(window, {
  CarTopdownModel, CarSideModel, HanoiMap, POI, GlassC, Shimmer, Aurora,
  useTween, usePullToRefresh, useSwipeDismiss, CAR_VARIANTS,
});
