'use client'

import { useMemo, useRef, useEffect, useState, forwardRef } from 'react'
import { Canvas, useFrame, useThree } from '@react-three/fiber'
import * as THREE from 'three'

const DEEP = '#683285'
const PRIMARY = '#A467B7'
const LAVENDER = '#E0CDEB'
const BUILDING_LIGHT = '#C8CBD2'
const BUILDING_MID = '#A8ACB4'
const WINDOW_DARK = '#4B5563'
const SIDEWALK = '#F1F2F4'
const ROAD = '#10131C'
const GRID_LINE = '#FFFFFF'
const SKY = '#EEF0F4'
const AWNING = '#DC2626'

const BACKGROUND_SCROLL_SPEED = 4.0

function Windows({ size, glow = false }: { size: [number, number, number]; glow?: boolean }) {
  const cols = 3
  const rows = Math.max(3, Math.floor(size[1] * 0.55))
  const items: Array<{ x: number; y: number }> = []
  for (let r = 0; r < rows; r++) {
    for (let c = 0; c < cols; c++) {
      items.push({
        x: (c - (cols - 1) / 2) * (size[2] * 0.22),
        y: (r - (rows - 1) / 2) * (size[1] * 0.22) + 0.4,
      })
    }
  }

  return (
    <group>
      {/* Front/Right Face Windows */}
      <group position={[size[0] / 2 + 0.012, 0, 0]} rotation={[0, Math.PI / 2, 0]}>
        {items.map((p, i) => (
          <group key={i} position={[p.x, p.y, 0]}>
            {/* Realistic Window Frame */}
            <mesh>
              <planeGeometry args={[size[2] * 0.13, size[1] * 0.12]} />
              <meshStandardMaterial color="#334155" roughness={0.5} />
            </mesh>
            {/* Glowing glass plane */}
            <mesh position={[0, 0, 0.005]}>
              <planeGeometry args={[size[2] * 0.11, size[1] * 0.10]} />
              <meshBasicMaterial color={glow && i % 4 === 0 ? "#FCD34D" : "#1E293B"} toneMapped={false} />
            </mesh>
          </group>
        ))}
      </group>
      {/* Back/Left Face Windows */}
      <group position={[-size[0] / 2 - 0.012, 0, 0]} rotation={[0, -Math.PI / 2, 0]}>
        {items.map((p, i) => (
          <group key={i} position={[p.x, p.y, 0]}>
            <mesh>
              <planeGeometry args={[size[2] * 0.13, size[1] * 0.12]} />
              <meshStandardMaterial color="#334155" roughness={0.5} />
            </mesh>
            <mesh position={[0, 0, 0.005]}>
              <planeGeometry args={[size[2] * 0.11, size[1] * 0.10]} />
              <meshBasicMaterial color={glow && i % 4 === 0 ? "#FCD34D" : "#1E293B"} toneMapped={false} />
            </mesh>
          </group>
        ))}
      </group>
    </group>
  )
}

function Skyscraper({
  position,
  size,
  color = "#1E293B",
}: {
  position: [number, number, number]
  size: [number, number, number]
  color?: string
}) {
  const colWidth = 0.16

  const billboardTexture = useMemo(() => {
    if (typeof window === 'undefined') return null
    const canvas = document.createElement('canvas')
    canvas.width = 128
    canvas.height = 256
    const ctx = canvas.getContext('2d')
    if (ctx) {
      // Dark cyber background
      ctx.fillStyle = '#0F172A'
      ctx.fillRect(0, 0, 128, 256)
      // Neon glow border
      ctx.strokeStyle = '#A78BFA'
      ctx.lineWidth = 8
      ctx.strokeRect(4, 4, 120, 248)
      // Text "NEARLE"
      ctx.fillStyle = '#FFFFFF'
      ctx.font = 'bold 24px sans-serif'
      ctx.textAlign = 'center'
      ctx.textBaseline = 'middle'
      ctx.fillText('NEARLE', 64, 50)
      
      // Neon graphics
      ctx.strokeStyle = '#F472B6'
      ctx.lineWidth = 4
      ctx.strokeRect(39, 90, 50, 50)
      ctx.beginPath()
      ctx.arc(64, 90, 15, Math.PI, 0)
      ctx.stroke()

      ctx.fillStyle = '#10B981'
      ctx.font = 'bold 20px sans-serif'
      ctx.fillText('LIVE', 64, 180)
      ctx.fillStyle = '#FEF3C7'
      ctx.font = 'bold 16px sans-serif'
      ctx.fillText('24/7', 64, 210)
    }
    return new THREE.CanvasTexture(canvas)
  }, [])

  return (
    <group position={position}>
      {/* Skyscraper Core Glass Facade */}
      <mesh castShadow receiveShadow>
        <boxGeometry args={size} />
        <meshStandardMaterial color="#0B0F19" roughness={0.15} metalness={0.85} />
      </mesh>

      {/* Structural Corner Columns (creates highly realistic 3D depth) */}
      <mesh position={[-size[0]/2, 0, -size[2]/2]} castShadow>
        <boxGeometry args={[colWidth, size[1] + 0.1, colWidth]} />
        <meshStandardMaterial color={color} roughness={0.6} />
      </mesh>
      <mesh position={[size[0]/2, 0, -size[2]/2]} castShadow>
        <boxGeometry args={[colWidth, size[1] + 0.1, colWidth]} />
        <meshStandardMaterial color={color} roughness={0.6} />
      </mesh>
      <mesh position={[-size[0]/2, 0, size[2]/2]} castShadow>
        <boxGeometry args={[colWidth, size[1] + 0.1, colWidth]} />
        <meshStandardMaterial color={color} roughness={0.6} />
      </mesh>
      <mesh position={[size[0]/2, 0, size[2]/2]} castShadow>
        <boxGeometry args={[colWidth, size[1] + 0.1, colWidth]} />
        <meshStandardMaterial color={color} roughness={0.6} />
      </mesh>

      {/* Horizontal banding rings */}
      {Array.from({ length: 4 }).map((_, i) => (
        <mesh key={i} position={[0, -size[1]/2 + (i + 1) * (size[1] / 5), 0]}>
          <boxGeometry args={[size[0] + 0.03, 0.08, size[2] + 0.03]} />
          <meshStandardMaterial color={color} roughness={0.5} />
        </mesh>
      ))}

      {/* Modern windows */}
      <Windows size={size} glow={true} />

      {/* Roof Terrace with HVAC units and structural ledge */}
      <mesh position={[0, size[1]/2 + 0.05, 0]}>
        <boxGeometry args={[size[0] + 0.05, 0.1, size[2] + 0.05]} />
        <meshStandardMaterial color={color} />
      </mesh>
      <mesh position={[0, size[1]/2 + 0.25, 0]} castShadow>
        <boxGeometry args={[1.0, 0.4, 1.0]} />
        <meshStandardMaterial color="#475569" roughness={0.7} />
      </mesh>
      <mesh position={[0.4, size[1]/2 + 0.15, -0.4]} castShadow>
        <cylinderGeometry args={[0.02, 0.02, 0.8]} />
        <meshStandardMaterial color="#64748B" metalness={0.9} />
      </mesh>

      {/* Glowing Neon Billboard mounted on the street facade */}
      {billboardTexture && (
        <group>
          {/* Left facing billboard (for left side buildings) */}
          <group position={[size[0]/2 + 0.06, size[1]/3, 0]} rotation={[0, Math.PI / 2, 0]}>
            <mesh castShadow>
              <planeGeometry args={[1.5, 2.5]} />
              <meshBasicMaterial map={billboardTexture} toneMapped={false} />
            </mesh>
            {/* Supporting brackets */}
            <mesh position={[-0.7, 0, -0.1]} rotation={[0, -Math.PI/6, 0]}>
              <boxGeometry args={[0.04, 0.04, 0.25]} />
              <meshStandardMaterial color="#334155" />
            </mesh>
            <mesh position={[0.7, 0, -0.1]} rotation={[0, Math.PI/6, 0]}>
              <boxGeometry args={[0.04, 0.04, 0.25]} />
              <meshStandardMaterial color="#334155" />
            </mesh>
          </group>
          {/* Right facing billboard (for right side buildings) */}
          <group position={[-size[0]/2 - 0.06, size[1]/3, 0]} rotation={[0, -Math.PI / 2, 0]}>
            <mesh castShadow>
              <planeGeometry args={[1.5, 2.5]} />
              <meshBasicMaterial map={billboardTexture} toneMapped={false} />
            </mesh>
            <mesh position={[-0.7, 0, -0.1]} rotation={[0, -Math.PI/6, 0]}>
              <boxGeometry args={[0.04, 0.04, 0.25]} />
              <meshStandardMaterial color="#334155" />
            </mesh>
            <mesh position={[0.7, 0, -0.1]} rotation={[0, Math.PI/6, 0]}>
              <boxGeometry args={[0.04, 0.04, 0.25]} />
              <meshStandardMaterial color="#334155" />
            </mesh>
          </group>
        </group>
      )}
    </group>
  )
}

function ApartmentBuilding({
  position,
  size,
  color = "#A8ACB4",
  awningColor = "#A467B7",
}: {
  position: [number, number, number]
  size: [number, number, number]
  color?: string
  awningColor?: string
}) {
  return (
    <group position={position}>
      {/* Ground Floor Base Block */}
      <mesh castShadow receiveShadow>
        <boxGeometry args={size} />
        <meshStandardMaterial color={color} roughness={0.8} />
      </mesh>

      {/* Decorative window ledges under each window row */}
      {Array.from({ length: 2 }).map((_, i) => (
        <mesh key={i} position={[0, -size[1]/2 + (i + 1) * (size[1] / 3) + 0.3, size[2]/2 + 0.03]}>
          <boxGeometry args={[size[0] * 0.85, 0.06, 0.08]} />
          <meshStandardMaterial color="#334155" />
        </mesh>
      ))}

      {/* Windows with glowing frames */}
      <Windows size={size} glow={true} />

      {/* Storefront Canopy / Awning on positive X (left side) and negative X (right side) */}
      <group>
        {/* Positive X (Left street side storefront awning) */}
        <mesh position={[size[0] / 2 + 0.22, -size[1] / 2 + 0.9, 0]} rotation={[0, 0, -0.2]} castShadow>
          <boxGeometry args={[0.45, 0.08, size[2] * 0.85]} />
          <meshStandardMaterial color={awningColor} roughness={0.6} />
        </mesh>
        {/* Support brackets */}
        <mesh position={[size[0] / 2 + 0.1, -size[1] / 2 + 0.6, -size[2] * 0.4]} rotation={[0, 0, -0.4]}>
          <cylinderGeometry args={[0.015, 0.015, 0.6]} />
          <meshStandardMaterial color="#475569" />
        </mesh>
        <mesh position={[size[0] / 2 + 0.1, -size[1] / 2 + 0.6, size[2] * 0.4]} rotation={[0, 0, -0.4]}>
          <cylinderGeometry args={[0.015, 0.015, 0.6]} />
          <meshStandardMaterial color="#475569" />
        </mesh>

        {/* Negative X (Right street side storefront awning) */}
        <mesh position={[-size[0] / 2 - 0.22, -size[1] / 2 + 0.9, 0]} rotation={[0, 0, 0.2]} castShadow>
          <boxGeometry args={[0.45, 0.08, size[2] * 0.85]} />
          <meshStandardMaterial color={awningColor} roughness={0.6} />
        </mesh>
        <mesh position={[-size[0] / 2 - 0.1, -size[1] / 2 + 0.6, -size[2] * 0.4]} rotation={[0, 0, 0.4]}>
          <cylinderGeometry args={[0.015, 0.015, 0.6]} />
          <meshStandardMaterial color="#475569" />
        </mesh>
        <mesh position={[-size[0] / 2 - 0.1, -size[1] / 2 + 0.6, size[2] * 0.4]} rotation={[0, 0, 0.4]}>
          <cylinderGeometry args={[0.015, 0.015, 0.6]} />
          <meshStandardMaterial color="#475569" />
        </mesh>
      </group>

      {/* Slanted Tile Roof (Pitched triangular prism roof top) */}
      <mesh position={[0, size[1]/2 + 0.4, 0]} rotation={[0, 0, Math.PI / 4]} castShadow>
        <boxGeometry args={[size[0] * 0.72, size[0] * 0.72, size[2] + 0.1]} />
        <meshStandardMaterial color="#1E293B" roughness={0.9} />
      </mesh>
    </group>
  )
}

function Building({
  position,
  size,
  color = BUILDING_LIGHT,
  windows = true,
  awning = false,
}: {
  position: [number, number, number]
  size: [number, number, number]
  color?: string
  windows?: boolean
  awning?: boolean
}) {
  return (
    <ApartmentBuilding position={position} size={size} color={color} awningColor={awning ? PRIMARY : DEEP} />
  )
}

function Lamp() {
  return (
    <group>
      <mesh position={[0, 1.1, 0]} castShadow>
        <cylinderGeometry args={[0.04, 0.04, 2.2, 8]} />
        <meshStandardMaterial color="#2A2F3A" />
      </mesh>
      <mesh position={[0.18, 2.05, 0]} rotation={[0, 0, Math.PI / 2.4]}>
        <cylinderGeometry args={[0.025, 0.025, 0.4, 8]} />
        <meshStandardMaterial color="#2A2F3A" />
      </mesh>
      <mesh position={[0.36, 1.95, 0]}>
        <sphereGeometry args={[0.08, 16, 16]} />
        <meshBasicMaterial color="#FEF3C7" toneMapped={false} />
      </mesh>
      <mesh position={[0.36, 0.7, 0]}>
        <coneGeometry args={[0.55, 2.3, 24, 1, true]} />
        <meshBasicMaterial
          color="#FDE68A"
          transparent
          opacity={0.08}
          side={THREE.DoubleSide}
          depthWrite={false}
        />
      </mesh>
    </group>
  )
}

function ScrollingLamps({ x, rotationY = 0 }: { x: number; rotationY?: number }) {
  const ref = useRef<THREE.Group>(null)
  const startZs = useMemo(() => [-10, -5, 0, 5, 10, 15], [])
  const loopLength = 30

  useFrame((_, dt) => {
    if (!ref.current) return
    ref.current.children.forEach((child) => {
      child.position.z += BACKGROUND_SCROLL_SPEED * dt
      if (child.position.z > 15) {
        child.position.z -= loopLength
      }
    })
  })

  return (
    <group ref={ref}>
      {startZs.map((z, i) => (
        <group key={i} position={[x, 0, z]} rotation={[0, rotationY, 0]}>
          <Lamp />
        </group>
      ))}
    </group>
  )
}

interface OncomingCarProps {
  color?: string
  neonColor?: string
  speed?: number
}

function OncomingCar({ color = "#F1F5F9", neonColor = "#22D3EE", speed = 8.5 }: OncomingCarProps) {
  const frontLeftWheelGroup = useRef<THREE.Group>(null)
  const frontRightWheelGroup = useRef<THREE.Group>(null)
  const backLeftWheelGroup = useRef<THREE.Group>(null)
  const backRightWheelGroup = useRef<THREE.Group>(null)

  useFrame((state, delta) => {
    const dt = Math.max(delta, 1 / 144)
    const spinSpeed = speed * 4.5
    if (frontLeftWheelGroup.current) frontLeftWheelGroup.current.rotation.x += spinSpeed * dt
    if (frontRightWheelGroup.current) frontRightWheelGroup.current.rotation.x += spinSpeed * dt
    if (backLeftWheelGroup.current) backLeftWheelGroup.current.rotation.x += spinSpeed * dt
    if (backRightWheelGroup.current) backRightWheelGroup.current.rotation.x += spinSpeed * dt
  })

  return (
    <group>
      {/* Car Main Metallic Chassis */}
      <mesh castShadow receiveShadow position={[0, 0.15, 0]}>
        <boxGeometry args={[0.95, 0.32, 1.8]} />
        <meshStandardMaterial color={color} roughness={0.15} metalness={0.85} />
      </mesh>
      
      {/* Sleek Aerodynamic Cabin / Windshield (painted body color for ultra-high visibility) */}
      <mesh position={[0, 0.42, -0.1]} castShadow>
        <boxGeometry args={[0.82, 0.26, 1.0]} />
        <meshStandardMaterial color={color} roughness={0.15} metalness={0.85} />
      </mesh>

      {/* Glowing Cyber Windows / Windshield (front windshield is a glowing cyber visor!) */}
      <mesh position={[0, 0.44, 0.41]} rotation={[-0.2, 0, 0]}>
        <planeGeometry args={[0.74, 0.22]} />
        <meshBasicMaterial color={neonColor} transparent opacity={0.9} toneMapped={false} />
      </mesh>

      {/* Glowing Neon Side Accent Trims */}
      <mesh position={[0.485, 0.18, 0]}>
        <boxGeometry args={[0.015, 0.06, 1.4]} />
        <meshBasicMaterial color={neonColor} toneMapped={false} />
      </mesh>
      <mesh position={[-0.485, 0.18, 0]}>
        <boxGeometry args={[0.015, 0.06, 1.4]} />
        <meshBasicMaterial color={neonColor} toneMapped={false} />
      </mesh>

      {/* Glowing Headlights facing positive Z (camera!) */}
      <mesh position={[0.32, 0.18, 0.91]}>
        <boxGeometry args={[0.16, 0.08, 0.02]} />
        <meshBasicMaterial color="#FFFFFF" toneMapped={false} />
      </mesh>
      <mesh position={[-0.32, 0.18, 0.91]}>
        <boxGeometry args={[0.16, 0.08, 0.02]} />
        <meshBasicMaterial color="#FFFFFF" toneMapped={false} />
      </mesh>

      {/* Volumetric Headlight Cones projecting forward (towards the camera) - scaled up and boosted opacity */}
      <mesh position={[0.32, 0.18, 2.5]} rotation={[Math.PI / 2, 0, 0]}>
        <coneGeometry args={[0.55, 3.2, 16, 1, true]} />
        <meshBasicMaterial
          color="#FEF3C7"
          transparent
          opacity={0.35}
          side={THREE.DoubleSide}
          depthWrite={false}
        />
      </mesh>
      <mesh position={[-0.32, 0.18, 2.5]} rotation={[Math.PI / 2, 0, 0]}>
        <coneGeometry args={[0.55, 3.2, 16, 1, true]} />
        <meshBasicMaterial
          color="#FEF3C7"
          transparent
          opacity={0.35}
          side={THREE.DoubleSide}
          depthWrite={false}
        />
      </mesh>

      {/* Red Tail lights facing negative Z */}
      <mesh position={[0.32, 0.22, -0.91]}>
        <boxGeometry args={[0.16, 0.06, 0.02]} />
        <meshBasicMaterial color="#EF4444" toneMapped={false} />
      </mesh>
      <mesh position={[-0.32, 0.22, -0.91]}>
        <boxGeometry args={[0.16, 0.06, 0.02]} />
        <meshBasicMaterial color="#EF4444" toneMapped={false} />
      </mesh>

      {/* 4 Wheels that Spin! */}
      {/* Front Left */}
      <group ref={frontLeftWheelGroup} position={[0.5, 0.08, 0.58]}>
        <group rotation={[0, 0, Math.PI / 2]}>
          <mesh castShadow>
            <cylinderGeometry args={[0.22, 0.22, 0.12, 16]} />
            <meshStandardMaterial color="#111827" roughness={0.9} />
          </mesh>
          {/* Wheel Spokes for spin visibility */}
          <mesh position={[0, 0.07, 0]}>
            <boxGeometry args={[0.03, 0.02, 0.2]} />
            <meshBasicMaterial color={neonColor} toneMapped={false} />
          </mesh>
        </group>
      </group>
      {/* Front Right */}
      <group ref={frontRightWheelGroup} position={[-0.5, 0.08, 0.58]}>
        <group rotation={[0, 0, Math.PI / 2]}>
          <mesh castShadow>
            <cylinderGeometry args={[0.22, 0.22, 0.12, 16]} />
            <meshStandardMaterial color="#111827" roughness={0.9} />
          </mesh>
          <mesh position={[0, 0.07, 0]}>
            <boxGeometry args={[0.03, 0.02, 0.2]} />
            <meshBasicMaterial color={neonColor} toneMapped={false} />
          </mesh>
        </group>
      </group>
      {/* Back Left */}
      <group ref={backLeftWheelGroup} position={[0.5, 0.08, -0.58]}>
        <group rotation={[0, 0, Math.PI / 2]}>
          <mesh castShadow>
            <cylinderGeometry args={[0.22, 0.22, 0.12, 16]} />
            <meshStandardMaterial color="#111827" roughness={0.9} />
          </mesh>
          <mesh position={[0, 0.07, 0]}>
            <boxGeometry args={[0.03, 0.02, 0.2]} />
            <meshBasicMaterial color={neonColor} toneMapped={false} />
          </mesh>
        </group>
      </group>
      {/* Back Right */}
      <group ref={backRightWheelGroup} position={[-0.5, 0.08, -0.58]}>
        <group rotation={[0, 0, Math.PI / 2]}>
          <mesh castShadow>
            <cylinderGeometry args={[0.22, 0.22, 0.12, 16]} />
            <meshStandardMaterial color="#111827" roughness={0.9} />
          </mesh>
          <mesh position={[0, 0.07, 0]}>
            <boxGeometry args={[0.03, 0.02, 0.2]} />
            <meshBasicMaterial color={neonColor} toneMapped={false} />
          </mesh>
        </group>
      </group>
    </group>
  )
}

interface OncomingBikeProps {
  color?: string
  neonColor?: string
  speed?: number
}

function OncomingBike({ color = "#F97316", neonColor = "#EC4899", speed = 6.8 }: OncomingBikeProps) {
  const frontWheelGroup = useRef<THREE.Group>(null)
  const backWheelGroup = useRef<THREE.Group>(null)

  useFrame((state, delta) => {
    const dt = Math.max(delta, 1 / 144)
    const spinSpeed = speed * 4.5
    if (frontWheelGroup.current) frontWheelGroup.current.rotation.x += spinSpeed * dt
    if (backWheelGroup.current) backWheelGroup.current.rotation.x += spinSpeed * dt
  })

  return (
    <group>
      {/* Front Wheel */}
      <group ref={frontWheelGroup} position={[0, 0.24, 0.6]}>
        <group rotation={[0, 0, Math.PI / 2]}>
          <mesh>
            <cylinderGeometry args={[0.24, 0.24, 0.08, 16]} />
            <meshStandardMaterial color="#111827" roughness={0.8} />
          </mesh>
          {/* Wheel Spokes for spin visibility */}
          <mesh position={[0, 0.05, 0]}>
            <boxGeometry args={[0.02, 0.02, 0.22]} />
            <meshBasicMaterial color={neonColor} toneMapped={false} />
          </mesh>
        </group>
      </group>
      
      {/* Back Wheel */}
      <group ref={backWheelGroup} position={[0, 0.24, -0.5]}>
        <group rotation={[0, 0, Math.PI / 2]}>
          <mesh>
            <cylinderGeometry args={[0.24, 0.24, 0.08, 16]} />
            <meshStandardMaterial color="#111827" roughness={0.8} />
          </mesh>
          <mesh position={[0, 0.05, 0]}>
            <boxGeometry args={[0.02, 0.02, 0.22]} />
            <meshBasicMaterial color={neonColor} toneMapped={false} />
          </mesh>
        </group>
      </group>

      {/* Frame Deck */}
      <mesh position={[0, 0.35, 0.05]} castShadow>
        <boxGeometry args={[0.18, 0.1, 0.85]} />
        <meshStandardMaterial color={color} roughness={0.5} />
      </mesh>

      {/* Front Fork & Handlebars */}
      <mesh position={[0, 0.45, 0.5]} rotation={[-Math.PI / 6, 0, 0]} castShadow>
        <cylinderGeometry args={[0.025, 0.025, 0.5]} />
        <meshStandardMaterial color="#94A3B8" />
      </mesh>
      <mesh position={[0, 0.7, 0.45]} rotation={[0, 0, Math.PI / 2]} castShadow>
        <cylinderGeometry args={[0.025, 0.025, 0.45]} />
        <meshStandardMaterial color="#1E293B" />
      </mesh>

      {/* Delivery Box (highly visible!) */}
      <mesh position={[0, 0.68, -0.4]} castShadow>
        <boxGeometry args={[0.42, 0.42, 0.42]} />
        <meshStandardMaterial color={color} roughness={0.4} />
      </mesh>
      {/* Glowing Neon Box Panel */}
      <mesh position={[0, 0.68, -0.18]}>
        <planeGeometry args={[0.3, 0.3]} />
        <meshBasicMaterial color={neonColor} toneMapped={false} />
      </mesh>

      {/* Rider Torso */}
      <mesh position={[0, 0.78, 0.05]} rotation={[0.2, 0, 0]} castShadow>
        <boxGeometry args={[0.28, 0.42, 0.22]} />
        <meshStandardMaterial color="#1F1B2E" roughness={0.6} />
      </mesh>
      {/* Glowing Safety Vest Stripes */}
      <mesh position={[0, 0.78, 0.17]}>
        <planeGeometry args={[0.22, 0.04]} />
        <meshBasicMaterial color="#10B981" toneMapped={false} />
      </mesh>

      {/* Helmet Head */}
      <mesh position={[0, 1.1, 0.12]} castShadow>
        <sphereGeometry args={[0.15, 16, 16]} />
        <meshStandardMaterial color="#1F1B2E" />
      </mesh>
      {/* Visor */}
      <mesh position={[0, 1.1, 0.22]} rotation={[0, 0, 0]}>
        <sphereGeometry args={[0.11, 12, 12, 0, Math.PI, 0, Math.PI/2]} />
        <meshStandardMaterial color={neonColor} metalness={0.9} toneMapped={false} />
      </mesh>

      {/* Glowing Headlight & Light Cone */}
      <mesh position={[0, 0.68, 0.62]}>
        <sphereGeometry args={[0.06, 12, 12]} />
        <meshBasicMaterial color="#FFFFFF" toneMapped={false} />
      </mesh>
      <mesh position={[0, 0.68, 1.4]} rotation={[Math.PI / 2, 0, 0]}>
        <coneGeometry args={[0.3, 1.5, 16, 1, true]} />
        <meshBasicMaterial
          color="#FEF3C7"
          transparent
          opacity={0.12}
          side={THREE.DoubleSide}
          depthWrite={false}
        />
      </mesh>
    </group>
  )
}

function ScrollingTraffic() {
  const ref = useRef<THREE.Group>(null)
  
  const vehicles = useMemo(
    () => [
      { id: 'v1', type: 'car', z: -15, speed: 8.5, color: '#F8FAFC', neonColor: '#22D3EE' },
      { id: 'v2', type: 'bike', z: -32, speed: 6.8, color: '#F97316', neonColor: '#EC4899' },
      { id: 'v3', type: 'car', z: -48, speed: 9.2, color: '#C084FC', neonColor: '#34D399' },
      { id: 'v4', type: 'bike', z: -64, speed: 7.2, color: '#10B981', neonColor: '#38BDF8' },
      { id: 'v5', type: 'car', z: -80, speed: 7.8, color: '#FB923C', neonColor: '#818CF8' },
    ],
    [],
  )

  useFrame((_, dt) => {
    if (!ref.current) return
    ref.current.children.forEach((child, i) => {
      const v = vehicles[i]
      child.position.z += v.speed * dt
      
      // When vehicle passes behind the camera, reset it far in the distance
      // We use 22 because the camera is at z = 8.5
      if (child.position.z > 22) {
        child.position.z = -75 - Math.random() * 20
      }
    })
  })

  return (
    <group ref={ref}>
      {vehicles.map((v) => (
        <group key={v.id} position={[2.0, 0, v.z]}>
          {v.type === 'car' ? (
            <OncomingCar color={v.color} neonColor={v.neonColor} speed={v.speed} />
          ) : (
            <OncomingBike color={v.color} neonColor={v.neonColor} speed={v.speed} />
          )}
        </group>
      ))}
    </group>
  )
}

function ScrollingDashes() {
  const ref = useRef<THREE.Group>(null)
  const startZs = useMemo(
    () => [-12, -9, -6, -3, 0, 3, 6, 9, 12],
    [],
  )
  const loopLength = 27

  useFrame((_, dt) => {
    if (!ref.current) return
    ref.current.children.forEach((child) => {
      child.position.z += BACKGROUND_SCROLL_SPEED * dt
      if (child.position.z > 13) {
        child.position.z -= loopLength
      }
    })
  })

  return (
    <group ref={ref}>
      {startZs.map((z, i) => (
        <mesh
          key={i}
          rotation={[-Math.PI / 2, 0, 0]}
          position={[0, 0.02, z]}
        >
          <planeGeometry args={[0.18, 1.4]} />
          <meshBasicMaterial color="#FFFFFF" transparent opacity={0.85} />
        </mesh>
      ))}
    </group>
  )
}

function Road() {
  return (
    <group>
      {/* Asphalt road */}
      <mesh
        rotation={[-Math.PI / 2, 0, 0]}
        position={[0, 0.005, 0]}
        receiveShadow
      >
        <planeGeometry args={[8, 60]} />
        <meshStandardMaterial color={ROAD} roughness={0.95} />
      </mesh>

      {/* Sidewalks */}
      <mesh
        rotation={[-Math.PI / 2, 0, 0]}
        position={[-6, 0.015, 0]}
        receiveShadow
      >
        <planeGeometry args={[4, 60]} />
        <meshStandardMaterial color={SIDEWALK} roughness={0.85} />
      </mesh>
      <mesh
        rotation={[-Math.PI / 2, 0, 0]}
        position={[6, 0.015, 0]}
        receiveShadow
      >
        <planeGeometry args={[4, 60]} />
        <meshStandardMaterial color={SIDEWALK} roughness={0.85} />
      </mesh>

      {/* Sidewalk edge stripes (white) */}
      <mesh rotation={[-Math.PI / 2, 0, 0]} position={[-4.05, 0.02, 0]}>
        <planeGeometry args={[0.12, 60]} />
        <meshBasicMaterial color="#FFFFFF" />
      </mesh>
      <mesh rotation={[-Math.PI / 2, 0, 0]} position={[4.05, 0.02, 0]}>
        <planeGeometry args={[0.12, 60]} />
        <meshBasicMaterial color="#FFFFFF" />
      </mesh>

      {/* Subtle grid on road */}
      <gridHelper
        args={[60, 60, GRID_LINE, GRID_LINE]}
        position={[0, 0.013, 0]}
      >
        <meshBasicMaterial transparent opacity={0.07} attach="material" />
      </gridHelper>

      <ScrollingDashes />
    </group>
  )
}

function Wheel({ position, wheelRef }: { position: [number, number, number]; wheelRef: React.RefObject<THREE.Group> }) {
  return (
    <group position={position} rotation={[0, 0, 0]}>
      <group ref={wheelRef}>
        {/* Tire */}
        <mesh castShadow>
          <torusGeometry args={[0.36, 0.09, 14, 32]} />
          <meshStandardMaterial color="#15161E" roughness={0.8} />
        </mesh>
        {/* Hub */}
        <mesh rotation={[Math.PI / 2, 0, 0]}>
          <cylinderGeometry args={[0.09, 0.09, 0.22, 16]} />
          <meshStandardMaterial color="#E5E7EB" metalness={0.6} roughness={0.3} />
        </mesh>
        {/* Spokes */}
        {Array.from({ length: 5 }).map((_, i) => (
          <mesh key={i} rotation={[0, 0, (i * Math.PI) / 2.5]}>
            <boxGeometry args={[0.02, 0.62, 0.02]} />
            <meshStandardMaterial color={LAVENDER} metalness={0.4} roughness={0.4} />
          </mesh>
        ))}
      </group>
    </group>
  )
}

const Rider = forwardRef<THREE.Group, { scrollProgress: number }>(({ scrollProgress }, ref) => {
  const legL = useRef<THREE.Mesh>(null)
  const legR = useRef<THREE.Mesh>(null)
  const armR = useRef<THREE.Mesh>(null)
  const frontWheelRef = useRef<THREE.Group>(null)
  const backWheelRef = useRef<THREE.Group>(null)
  const hudRef = useRef<THREE.Group>(null)

  const brandTexture = useMemo(() => {
    if (typeof window === 'undefined') return null
    const canvas = document.createElement('canvas')
    canvas.width = 256
    canvas.height = 256
    const ctx = canvas.getContext('2d')
    if (ctx) {
      // Dark slate background
      ctx.fillStyle = '#0F172A'
      ctx.fillRect(0, 0, 256, 256)
      // Neon green glowing border
      ctx.strokeStyle = '#10B981'
      ctx.lineWidth = 14
      ctx.strokeRect(7, 7, 242, 242)
      // Inner glowing purple border
      ctx.strokeStyle = '#8B5CF6'
      ctx.lineWidth = 6
      ctx.strokeRect(18, 18, 220, 220)
      
      // Text "NEARLE"
      ctx.shadowColor = '#10B981'
      ctx.shadowBlur = 20
      ctx.fillStyle = '#FFFFFF'
      ctx.font = 'bold 50px sans-serif'
      ctx.textAlign = 'center'
      ctx.textBaseline = 'middle'
      ctx.fillText('NEARLE', 128, 128)
    }
    const texture = new THREE.CanvasTexture(canvas)
    return texture
  }, [])

  const avatarTexture = useMemo(() => {
    if (typeof window === 'undefined') return null
    const canvas = document.createElement('canvas')
    canvas.width = 256
    canvas.height = 256
    const ctx = canvas.getContext('2d')
    if (ctx) {
      // Circular clip for avatar
      ctx.beginPath()
      ctx.arc(128, 128, 120, 0, Math.PI * 2)
      ctx.clip()

      // Gradient background
      const grad = ctx.createLinearGradient(0, 0, 256, 256)
      grad.addColorStop(0, '#7C3AED') // Violet
      grad.addColorStop(1, '#10B981') // Green
      ctx.fillStyle = grad
      ctx.fillRect(0, 0, 256, 256)

      // Outer neon border
      ctx.strokeStyle = '#FFFFFF'
      ctx.lineWidth = 10
      ctx.beginPath()
      ctx.arc(128, 128, 118, 0, Math.PI * 2)
      ctx.stroke()

      // Draw avatar face (procedural cute vector!)
      // Helmet circle
      ctx.fillStyle = '#1F1B2E'
      ctx.beginPath()
      ctx.arc(128, 100, 55, 0, Math.PI * 2)
      ctx.fill()

      // Face circle
      ctx.fillStyle = '#FBCFE8' // Peach face
      ctx.beginPath()
      ctx.arc(128, 115, 38, 0, Math.PI)
      ctx.fill()

      // Visor
      ctx.fillStyle = '#0F172A' // Dark visor
      ctx.fillRect(98, 85, 60, 25)
      // Visor shine reflection
      ctx.fillStyle = 'rgba(255, 255, 255, 0.4)'
      ctx.beginPath()
      ctx.moveTo(105, 85)
      ctx.lineTo(125, 85)
      ctx.lineTo(115, 110)
      ctx.lineTo(98, 110)
      ctx.closePath()
      ctx.fill()

      // Safety jacket collar
      ctx.fillStyle = '#8B5CF6'
      ctx.beginPath()
      ctx.moveTo(78, 220)
      ctx.lineTo(178, 220)
      ctx.lineTo(148, 160)
      ctx.lineTo(108, 160)
      ctx.closePath()
      ctx.fill()

      // Neon yellow safety vest strap
      ctx.fillStyle = '#10B981'
      ctx.fillRect(98, 175, 14, 45)
      ctx.fillRect(144, 175, 14, 45)

      // Friendly smile eyes below visor
      ctx.strokeStyle = '#1F1B2E'
      ctx.lineWidth = 4
      ctx.lineCap = 'round'
      ctx.beginPath()
      ctx.arc(113, 125, 6, 0, Math.PI, false) // Left eye smile
      ctx.stroke()
      ctx.beginPath()
      ctx.arc(143, 125, 6, 0, Math.PI, false) // Right eye smile
      ctx.stroke()
      
      // Happy mouth smile
      ctx.beginPath()
      ctx.arc(128, 138, 8, 0, Math.PI, false)
      ctx.stroke()
    }
    const texture = new THREE.CanvasTexture(canvas)
    return texture
  }, [])

  const ratingTexture = useMemo(() => {
    if (typeof window === 'undefined') return null
    const canvas = document.createElement('canvas')
    canvas.width = 128
    canvas.height = 64
    const ctx = canvas.getContext('2d')
    if (ctx) {
      // Rounded background capsule
      ctx.fillStyle = 'rgba(16, 185, 129, 0.95)' // Glowing neon green
      ctx.beginPath()
      ctx.roundRect(4, 4, 120, 56, 15)
      ctx.fill()
      
      // Star and text
      ctx.fillStyle = '#FFFFFF'
      ctx.font = 'bold 22px sans-serif'
      ctx.textAlign = 'center'
      ctx.textBaseline = 'middle'
      ctx.fillText('5.0 ★', 64, 32)
    }
    const texture = new THREE.CanvasTexture(canvas)
    return texture
  }, [])

  useFrame((state, delta) => {
    const t = state.clock.getElapsedTime()
    const dt = Math.max(delta, 1 / 144)

    const groupRef = ref as React.RefObject<THREE.Group>
    if (!groupRef || !groupRef.current) return

    // Gentle drift along the road as the user scrolls the page (driving strictly on the left-hand lane)
    const targetZ = 6 - scrollProgress * 14
    const targetX = -2.4 - Math.sin(scrollProgress * Math.PI * 2.2) * 0.45

    groupRef.current.position.z += (targetZ - groupRef.current.position.z) * 0.08
    groupRef.current.position.x += (targetX - groupRef.current.position.x) * 0.08

    const deltaX = targetX - groupRef.current.position.x
    const targetRotationZ = -deltaX * 0.35
    groupRef.current.rotation.z += (targetRotationZ - groupRef.current.rotation.z) * 0.1

    // Subtle bob + pedalling
    groupRef.current.position.y = 0.04 + Math.sin(t * 9) * 0.015
    if (legL.current) legL.current.rotation.x = Math.PI / 8 + Math.sin(t * 11) * 0.22
    if (legR.current) legR.current.rotation.x = -Math.PI / 8 - Math.sin(t * 11) * 0.22
    if (armR.current) armR.current.rotation.z = -Math.PI / 4 + Math.sin(t * 9) * 0.05

    if (hudRef.current) {
      hudRef.current.position.y = 2.2 + Math.sin(t * 4.5) * 0.08
    }

    const wheelSpeed = 10 + Math.abs(deltaX) * 40
    if (frontWheelRef.current) frontWheelRef.current.rotation.z += wheelSpeed * dt
    if (backWheelRef.current) backWheelRef.current.rotation.z += wheelSpeed * dt
  })

  return (
    <group ref={ref} position={[-2.4, 0, 6]} scale={1.0}>
      <group rotation={[0, Math.PI / 2, 0]}>
        <Wheel position={[-0.55, 0.35, 0]} wheelRef={backWheelRef} />
        <Wheel position={[0.7, 0.35, 0]} wheelRef={frontWheelRef} />

        {/* Frame deck */}
        <mesh position={[0.05, 0.55, 0]} castShadow>
          <boxGeometry args={[0.95, 0.18, 0.32]} />
          <meshStandardMaterial color={PRIMARY} roughness={0.5} />
        </mesh>

        {/* Front fork */}
        <mesh position={[0.7, 0.72, 0]} rotation={[0, 0, -Math.PI / 5]} castShadow>
          <cylinderGeometry args={[0.045, 0.045, 0.75, 10]} />
          <meshStandardMaterial color={LAVENDER} metalness={0.3} roughness={0.4} />
        </mesh>
        {/* Handlebars */}
        <mesh position={[0.92, 1.02, 0]} rotation={[Math.PI / 2, 0, 0]} castShadow>
          <cylinderGeometry args={[0.04, 0.04, 0.6, 10]} />
          <meshStandardMaterial color="#1F1B2E" />
        </mesh>

        {/* Seat */}
        <mesh position={[-0.1, 0.8, 0]} castShadow>
          <boxGeometry args={[0.42, 0.1, 0.28]} />
          <meshStandardMaterial color="#1F1B2E" />
        </mesh>

        {/* Delivery box */}
        <mesh position={[-0.55, 1.0, 0]} castShadow>
          <boxGeometry args={[0.6, 0.6, 0.55]} />
          <meshStandardMaterial color={PRIMARY} roughness={0.45} />
        </mesh>
        {/* Box accent strip */}
        <mesh position={[-0.55, 1.0, 0.281]}>
          <planeGeometry args={[0.42, 0.08]} />
          <meshStandardMaterial color={DEEP} />
        </mesh>
        <mesh position={[-0.55, 1.0, -0.281]} rotation={[0, Math.PI, 0]}>
          <planeGeometry args={[0.42, 0.08]} />
          <meshStandardMaterial color={DEEP} />
        </mesh>

        {brandTexture && (
          <mesh position={[-0.851, 1.0, 0]} rotation={[0, -Math.PI / 2, 0]}>
            <planeGeometry args={[0.45, 0.45]} />
            <meshBasicMaterial map={brandTexture} toneMapped={false} />
          </mesh>
        )}

        {/* Rider torso */}
        <group>
          <mesh position={[0.1, 1.15, 0]} castShadow>
            <boxGeometry args={[0.44, 0.6, 0.34]} />
            <meshStandardMaterial color={PRIMARY} roughness={0.5} />
          </mesh>
          {/* Reflective safety vest stripes */}
          <mesh position={[0.1, 1.15, 0.171]}>
            <planeGeometry args={[0.3, 0.05]} />
            <meshBasicMaterial color="#10B981" toneMapped={false} />
          </mesh>
          <mesh position={[0.1, 1.15, -0.171]} rotation={[0, Math.PI, 0]}>
            <planeGeometry args={[0.3, 0.05]} />
            <meshBasicMaterial color="#10B981" toneMapped={false} />
          </mesh>
        </group>

        {/* Right arm forward to bars */}
        <mesh ref={armR} position={[0.5, 1.05, 0]} rotation={[0, 0, -Math.PI / 5]} castShadow>
          <cylinderGeometry args={[0.07, 0.07, 0.5, 10]} />
          <meshStandardMaterial color={PRIMARY} />
        </mesh>

        {/* Legs */}
        <mesh ref={legL} position={[0.2, 0.7, 0.15]} castShadow>
          <cylinderGeometry args={[0.08, 0.08, 0.45, 10]} />
          <meshStandardMaterial color={DEEP} />
        </mesh>
        <mesh ref={legR} position={[0.2, 0.7, -0.15]} castShadow>
          <cylinderGeometry args={[0.08, 0.08, 0.45, 10]} />
          <meshStandardMaterial color={DEEP} />
        </mesh>

        {/* Helmet */}
        <mesh position={[0.18, 1.65, 0]} castShadow>
          <sphereGeometry args={[0.24, 20, 20]} />
          <meshStandardMaterial color="#1F1B2E" roughness={0.45} />
        </mesh>
        {/* Visor */}
        <mesh position={[0.36, 1.63, 0.02]} rotation={[0, -Math.PI / 6, 0]}>
          <sphereGeometry args={[0.17, 16, 16, 0, Math.PI]} />
          <meshStandardMaterial color="#0F172A" metalness={0.85} roughness={0.1} />
        </mesh>

        {/* Holographic Floating Rider Avatar HUD Bubble */}
        {avatarTexture && ratingTexture && (
          <group ref={hudRef} position={[0.18, 2.2, 0]} rotation={[0, -Math.PI / 2, 0]}>
            {/* Round Avatar Profile Card */}
            <mesh castShadow>
              <planeGeometry args={[0.55, 0.55]} />
              <meshBasicMaterial map={avatarTexture} transparent opacity={0.95} toneMapped={false} />
            </mesh>
            {/* Rating Tag Capsule */}
            <mesh position={[0, -0.38, 0.01]}>
              <planeGeometry args={[0.32, 0.16]} />
              <meshBasicMaterial map={ratingTexture} transparent opacity={0.95} toneMapped={false} />
            </mesh>
          </group>
        )}
      </group>
    </group>
  )
})

Rider.displayName = 'Rider'

function ScrollingBuildings({
  side,
  data,
}: {
  side: 'left' | 'right'
  data: Array<{
    z: number
    size: [number, number, number]
    y: number
    color?: string
    awning?: boolean
  }>
}) {
  const ref = useRef<THREE.Group>(null)
  const x = side === 'left' ? -8.5 : 8.5
  const loopLength = 40
  const speed = BACKGROUND_SCROLL_SPEED * 0.55

  useFrame((_, dt) => {
    if (!ref.current) return
    ref.current.children.forEach((child) => {
      child.position.z += speed * dt
      if (child.position.z > 18) child.position.z -= loopLength
    })
  })

  return (
    <group ref={ref}>
      {data.map((b, i) => {
        const isSkyscraper = b.size[1] > 7.0
        return (
          <group key={i} position={[x, b.y, b.z]}>
            {isSkyscraper ? (
              <Skyscraper position={[0, 0, 0]} size={b.size} color={b.color} />
            ) : (
              <ApartmentBuilding
                position={[0, 0, 0]}
                size={b.size}
                color={b.color}
                awningColor={b.awning ? PRIMARY : DEEP}
              />
            )}
          </group>
        )
      })}
    </group>
  )
}

function Scene({ scrollProgress }: { scrollProgress: number }) {
  const cam = useRef<THREE.Group>(null)
  const riderRef = useRef<THREE.Group>(null)
  const pointer = useThree((s) => s.pointer)

  useFrame((state) => {
    if (!cam.current) return
    cam.current.rotation.y += (pointer.x * 0.04 - cam.current.rotation.y) * 0.04

    // Static cinematic angle — rider parked on the right, road extending forward-left
    const targetCamX = 4.4 + pointer.x * 0.4
    const targetCamY = 2.6 + pointer.y * 0.15
    const targetCamZ = 8.5

    state.camera.position.x += (targetCamX - state.camera.position.x) * 0.05
    state.camera.position.y += (targetCamY - state.camera.position.y) * 0.05
    state.camera.position.z += (targetCamZ - state.camera.position.z) * 0.05

    state.camera.lookAt(-1.5, 1.4, -2)
  })

  const leftBuildings = useMemo(
    () => [
      { z: -10, y: 2.8, size: [3.5, 5.6, 4] as [number, number, number], color: BUILDING_LIGHT },
      { z: -3, y: 4.0, size: [3.5, 8.0, 4] as [number, number, number], color: BUILDING_MID },
      { z: 5, y: 3.2, size: [3.5, 6.4, 4] as [number, number, number], color: BUILDING_LIGHT },
      { z: 13, y: 4.4, size: [3.5, 8.8, 4] as [number, number, number], color: BUILDING_MID },
    ],
    [],
  )
  const rightBuildings = useMemo(
    () => [
      { z: -8, y: 3.4, size: [3.5, 6.8, 5] as [number, number, number], color: BUILDING_MID },
      { z: -1, y: 5.0, size: [3.5, 10.0, 4.5] as [number, number, number], color: BUILDING_LIGHT, awning: true },
      { z: 8, y: 3.6, size: [3.5, 7.2, 4] as [number, number, number], color: BUILDING_MID },
      { z: 16, y: 4.0, size: [3.5, 8.0, 4] as [number, number, number], color: BUILDING_LIGHT },
    ],
    [],
  )

  return (
    <group ref={cam}>
      <Road />

      <ScrollingLamps x={-4.6} rotationY={0} />
      <ScrollingLamps x={4.6} rotationY={Math.PI} />

      <ScrollingBuildings side="left" data={leftBuildings} />
      <ScrollingBuildings side="right" data={rightBuildings} />

      <ScrollingTraffic />

      <Rider ref={riderRef} scrollProgress={scrollProgress} />
    </group>
  )
}

export default function CityRider3D() {
  const [scrollProgress, setScrollProgress] = useState(0)
  const containerRef = useRef<HTMLDivElement>(null)

  useEffect(() => {
    const handleScroll = () => {
      if (!containerRef.current) return
      const rect = containerRef.current.getBoundingClientRect()
      const scrolled = window.scrollY
      const sectionTop = rect.top + scrolled
      const sectionHeight = rect.height
      const viewportHeight = window.innerHeight

      const start = sectionTop - viewportHeight
      const end = sectionTop + sectionHeight

      if (scrolled < start) {
        setScrollProgress(0)
      } else if (scrolled > end) {
        setScrollProgress(1)
      } else {
        const progress = (scrolled - start) / (end - start)
        setScrollProgress(progress)
      }
    }

    window.addEventListener('scroll', handleScroll, { passive: true })
    handleScroll()
    return () => window.removeEventListener('scroll', handleScroll)
  }, [])

  return (
    <div ref={containerRef} className="relative w-full h-full" style={{ background: SKY }}>
      <Canvas
        shadows
        camera={{ position: [4.4, 2.6, 8.5], fov: 50 }}
        dpr={[1, 1.7]}
        gl={{ antialias: true, alpha: false }}
        onCreated={({ camera, gl }) => {
          gl.setClearColor(SKY)
          camera.lookAt(-1.5, 1.4, -2)
        }}
      >
        <fog attach="fog" args={[SKY, 18, 38]} />
        <ambientLight intensity={0.9} />
        <directionalLight
          position={[6, 12, 5]}
          intensity={1.0}
          castShadow
          shadow-mapSize-width={1024}
          shadow-mapSize-height={1024}
        />
        <directionalLight position={[-6, 6, -4]} intensity={0.35} />
        <Scene scrollProgress={scrollProgress} />
      </Canvas>
    </div>
  )
}
