import { useEffect, useRef, useState } from 'react'
import { Html } from '@react-three/drei'
import { useFrame, useThree } from '@react-three/fiber'
import { useXR } from '@react-three/xr'
import { MathUtils } from 'three'
import { Label } from './Label'
import { SceneButton } from './SceneButton'

// Original fictional assembly. Replace components/Workbench.jsx in React XR.
const parts = [
  { title: 'Optics', text: 'The lens shapes the light.', color: '#50d6c3' },
  { title: 'Power core', text: 'A copper coil surrounds the core.', color: '#e4a369' },
  { title: 'Radiator', text: 'Spaced fins expose more surface.', color: '#c5d0db' },
]

function Metal({ color = '#6e7a87', ...props }) {
  return <meshStandardMaterial color={color} metalness={0.65} roughness={0.28} {...props} />
}

function Part({ index, selected, expanded, rotating, reduced, onSelect }) {
  const root = useRef(null)
  const turn = useRef(null)
  const part = parts[index]
  useFrame((_, dt) => {
    const target = (index - 1) * (expanded ? 0.53 : 0.23)
    root.current.position.x = reduced ? target : MathUtils.damp(root.current.position.x, target, 7, dt)
    if (rotating && !reduced) turn.current.rotation.y += Math.min(dt, 0.1) * 0.4
    else turn.current.rotation.y = reduced ? 0.35 : MathUtils.damp(turn.current.rotation.y, 0.35, 7, dt)
  })
  return (
    <group ref={root} position={[(index - 1) * 0.23, 1.2, -1.42]}>
      <group ref={turn} rotation={[0, 0.35, 0]} name={`Inspect ${part.title}`} onPointerDown={e => { e.stopPropagation(); onSelect(index) }}>
        <mesh rotation={[0, 0, Math.PI / 2]} castShadow>
          <cylinderGeometry args={[0.17, 0.17, 0.2, 48]} />
          <Metal color={index === 1 ? '#69452c' : '#536373'} />
        </mesh>
        {index === 0 && <>
          <mesh position={[-0.108, 0, 0]} rotation={[0, Math.PI / 2, 0]}>
            <circleGeometry args={[0.14, 48]} />
            <meshStandardMaterial color={part.color} metalness={0.4} roughness={0.16} emissive={part.color} emissiveIntensity={0.2} side={2} />
          </mesh>
          {[0.07, 0.11, 0.15].map(r => <mesh key={r} position={[-0.112, 0, 0]} rotation={[0, Math.PI / 2, 0]}>
            <torusGeometry args={[r, 0.005, 8, 48]} /><Metal color="#b7e8df" />
          </mesh>)}
        </>}
        {index === 1 && Array.from({ length: 9 }, (_, n) => <mesh key={n} position={[-0.088 + n * 0.022, 0, 0]} rotation={[0, Math.PI / 2, 0]} castShadow>
          <torusGeometry args={[0.18, 0.009, 8, 40]} /><Metal color={part.color} />
        </mesh>)}
        {index === 2 && Array.from({ length: 7 }, (_, n) => <mesh key={n} position={[-0.09 + n * 0.03, 0, 0]} rotation={[0, 0, Math.PI / 2]} castShadow>
          <cylinderGeometry args={[0.215, 0.215, 0.012, 48]} /><Metal color={part.color} />
        </mesh>)}
      </group>
      <mesh position={[0, -0.345, 0]} rotation={[-Math.PI / 2, 0, 0]} pointerEvents="none">
        <ringGeometry args={[0.12, selected ? 0.14 : 0.125, 48]} />
        <meshBasicMaterial color={selected ? '#4ff0c7' : '#727e8b'} />
      </mesh>
      <Label text={part.title} height={0.028} position={[0, -0.29, 0.12]} color={selected ? '#a3ffe6' : '#f5f7fa'} />
    </group>
  )
}

export function Workbench() {
  const [expanded, setExpanded] = useState(false)
  const [rotating, setRotating] = useState(false)
  const [selected, setSelected] = useState(0)
  const [reduced, setReduced] = useState(false)
  const [exitError, setExitError] = useState('')
  const session = useXR(state => state.session)
  const camera = useThree(state => state.camera)
  const aspect = useThree(state => state.size.width / state.size.height)
  useEffect(() => {
    if (session || !camera.isPerspectiveCamera) return
    // Keep the entire table visible in narrow desktop/browser previews.
    const distance = 2.05 / (2 * Math.tan(MathUtils.degToRad(camera.fov / 2)) * aspect)
    camera.position.set(0, 1.6, Math.max(0.35, distance - 1.42))
    camera.lookAt(0, 1.05, -1.42)
  }, [aspect, camera, session])
  useEffect(() => {
    const query = window.matchMedia('(prefers-reduced-motion: reduce)')
    const sync = () => setReduced(query.matches)
    sync()
    query.addEventListener('change', sync)
    return () => query.removeEventListener('change', sync)
  }, [])
  const reset = () => { setExpanded(false); setRotating(false); setSelected(0) }
  const leave = () => { setExitError(''); session?.end().catch(() => setExitError('Use the headset menu to leave.')) }
  return <>
    <group name="Inspection table">
      <mesh position={[0, 0.8, -1.42]} castShadow receiveShadow>
        <boxGeometry args={[1.85, 0.1, 1.05]} /><Metal color="#29343f" roughness={0.7} />
      </mesh>
      {[-0.7, 0.7].map(x => <mesh key={x} position={[x, 0.38, -1.42]} castShadow>
        <boxGeometry args={[0.08, 0.76, 0.7]} /><Metal color="#48515a" />
      </mesh>)}
      <mesh position={[0, 1.64, -1.85]} castShadow>
        <boxGeometry args={[1.8, 0.27, 0.035]} /><meshStandardMaterial color="#17232d" roughness={0.8} />
      </mesh>
      <Label text="Beacon / assembly study" height={0.045} position={[0, 1.7, -1.827]} />
      <Label text={`${parts[selected].title}: ${parts[selected].text}`} height={0.031} position={[0, 1.6, -1.826]} color="#bfe7de" />
      {parts.map((part, index) => <Part key={part.title} index={index} selected={selected === index} expanded={expanded} rotating={rotating} reduced={reduced} onSelect={setSelected} />)}
      <SceneButton name="Separate assembly" label={expanded ? 'Assemble' : 'Separate'} position={[-0.45, 0.86, -1.05]} color="#30b89b" onPress={() => setExpanded(v => !v)} />
      {!reduced && <SceneButton name="Rotate assembly" label={rotating ? 'Face front' : 'Rotate'} position={[0, 0.86, -1.05]} color="#8493a3" onPress={() => setRotating(v => !v)} />}
      <SceneButton name="Reset assembly" label="Reset" position={[0.45, 0.86, -1.05]} color="#8493a3" onPress={reset} />
      {session && <SceneButton name="Leave XR" label="Leave XR" position={[0.78, 0.86, -1.55]} color="#c77757" onPress={leave} />}
      {exitError && <Label text={exitError} height={0.035} position={[0, 1.9, -1.85]} />}
    </group>
    {!session && <Html fullscreen calculatePosition={(_, __, size) => [size.width / 2, size.height / 2]} style={{ pointerEvents: 'none' }}>
      <style>{`
        .beacon-controls { position:absolute; bottom:18px; left:50%; transform:translateX(-50%); width:min(560px,calc(100% - 32px)); box-sizing:border-box; padding:14px 16px; color:#f5f7fa; background:#17232df5; border:1px solid #697b8b; border-radius:8px; font:14px/1.4 system-ui,sans-serif; pointer-events:auto; }
        .beacon-controls p { margin:0 0 10px; }
        .beacon-controls .beacon-row { display:flex; flex-wrap:wrap; gap:8px; margin-top:8px; }
        .beacon-controls button { min-height:40px; border:1px solid #8394a4; border-radius:4px; background:#263746; color:#fff; padding:7px 12px; font:inherit; cursor:pointer; }
        .beacon-controls button[aria-pressed="true"] { background:#105b4d; border-color:#70e7c7; }
        .beacon-controls button:focus-visible { outline:3px solid #70e7c7; outline-offset:3px; }
        .beacon-controls button:disabled { opacity:0.6; cursor:default; }
        .beacon-controls summary { cursor:pointer; font-weight:600; }
        @media(max-width:600px) { .beacon-controls { bottom:8px; padding:10px; font-size:13px; } }
      `}</style>
      <details className="beacon-controls" open>
        <summary>Inspect the beacon</summary>
        <p aria-live="polite">{parts[selected].title}: {parts[selected].text}</p>
        <div className="beacon-row" aria-label="Choose a part">
          {parts.map((p, i) => <button key={p.title} aria-pressed={i === selected} onClick={() => setSelected(i)}>{p.title}</button>)}
        </div>
        <div className="beacon-row" aria-label="Assembly controls">
          <button aria-pressed={expanded} onClick={() => setExpanded(v => !v)}>{expanded ? 'Assemble' : 'Separate parts'}</button>
          <button aria-pressed={rotating && !reduced} disabled={reduced} onClick={() => setRotating(v => !v)}>{reduced ? 'Reduced motion' : rotating ? 'Face front' : 'Rotate parts'}</button>
          <button onClick={reset}>Reset</button>
        </div>
      </details>
    </Html>}
  </>
}
