import { useEffect, useRef, useState } from 'react'
import * as THREE from 'three'
import { buildPhone, CLOSED_ANGLE, PhonePreview } from './phone'

// A reusable "tools" inventory: a three.js rack you cycle through, one 3D tool at a
// time, then USE to open it. Tool-driven (see TOOLS below), so it isn't tied to any
// level type — new tools (map, visual novel, …) just register a model + a component.
// Rendered as a dev overlay at /?inventory=1 for now; drop <Inventory/> into the
// real navbar later.

function buildPhoneModel() {
  const { group, hinge } = buildPhone()
  hinge.rotation.x = CLOSED_ANGLE // sit closed on the rack
  group.scale.setScalar(1.15)
  group.position.y = -0.05
  return group
}

function buildNotebook() {
  const g = new THREE.Group()
  const coverMat = new THREE.MeshStandardMaterial({ color: 0x7c3a2b, roughness: 0.85, metalness: 0.05, flatShading: true })
  const pageMat = new THREE.MeshStandardMaterial({ color: 0xe7dcbf, roughness: 0.95, flatShading: true })
  const wireMat = new THREE.MeshStandardMaterial({ color: 0xcaa74a, roughness: 0.5, metalness: 0.5, flatShading: true })
  const back = new THREE.Mesh(new THREE.BoxGeometry(0.86, 1.16, 0.05), coverMat); back.position.z = -0.08; g.add(back)
  const pages = new THREE.Mesh(new THREE.BoxGeometry(0.8, 1.08, 0.12), pageMat); g.add(pages)
  const front = new THREE.Mesh(new THREE.BoxGeometry(0.86, 1.16, 0.05), coverMat); front.position.z = 0.09; g.add(front)
  const strap = new THREE.Mesh(new THREE.BoxGeometry(0.06, 1.2, 0.02), new THREE.MeshStandardMaterial({ color: 0x2a2320, roughness: 0.8, flatShading: true }))
  strap.position.set(0.3, 0, 0.12); g.add(strap)
  for (let i = 0; i < 8; i++) { // spiral binding down the spine
    const ring = new THREE.Mesh(new THREE.TorusGeometry(0.035, 0.012, 6, 10), wireMat)
    ring.position.set(-0.43, 0.49 - i * 0.14, 0); ring.rotation.y = Math.PI / 2; g.add(ring)
  }
  g.traverse(obj => { if (obj instanceof THREE.Mesh) obj.castShadow = true })
  return g
}

const TOOLS: { key: string; name: string; build: () => THREE.Group }[] = [
  { key: 'notebook', name: 'Notebook', build: buildNotebook },
  { key: 'phone', name: 'Phone', build: buildPhoneModel },
]

function ToolRack({ index }: { index: number }) {
  const stageRef = useRef<HTMLDivElement>(null)
  const holderRef = useRef<THREE.Group | null>(null)

  useEffect(() => {
    const stage = stageRef.current
    if (!stage) return
    const renderer = new THREE.WebGLRenderer({ antialias: true, alpha: true })
    renderer.setPixelRatio(Math.min(window.devicePixelRatio, 2))
    stage.appendChild(renderer.domElement)
    renderer.domElement.style.cssText = 'position:absolute;inset:0;width:100%;height:100%'

    const scene = new THREE.Scene()
    const camera = new THREE.PerspectiveCamera(34, 1, 0.1, 100)
    camera.position.set(0.5, 0.45, 3.3)
    camera.lookAt(0, 0, 0)
    scene.add(new THREE.AmbientLight(0x40483a, 0.9))
    const key = new THREE.DirectionalLight(0xfff4e0, 1.1); key.position.set(2, 3, 3); scene.add(key)
    const rim = new THREE.DirectionalLight(0x9fd020, 0.4); rim.position.set(-2, 1, -2); scene.add(rim)
    const holder = new THREE.Group(); scene.add(holder); holderRef.current = holder

    const resize = () => { const w = stage.clientWidth, h = stage.clientHeight; if (w && h) { camera.aspect = w / h; camera.updateProjectionMatrix(); renderer.setSize(w, h, false) } }
    resize(); const ro = new ResizeObserver(resize); ro.observe(stage)

    let raf = 0
    const tick = () => { holder.rotation.y += 0.008; renderer.render(scene, camera); raf = requestAnimationFrame(tick) }
    tick()
    return () => {
      cancelAnimationFrame(raf); ro.disconnect(); renderer.dispose(); renderer.domElement.remove()
      scene.traverse(o => { if (o instanceof THREE.Mesh) { o.geometry.dispose(); (o.material as THREE.Material).dispose() } })
      holderRef.current = null
    }
  }, [])

  // Swap the model when the selected tool changes.
  useEffect(() => {
    const holder = holderRef.current
    if (!holder) return
    while (holder.children.length) { const child = holder.children[0]; holder.remove(child); child.traverse(o => { if (o instanceof THREE.Mesh) { o.geometry.dispose(); (o.material as THREE.Material).dispose() } }) }
    holder.rotation.set(0, 0, 0)
    holder.add(TOOLS[index].build())
  }, [index])

  return <div ref={stageRef} className="inv-stage" />
}

export function Inventory({ onClose }: { onClose?: () => void }) {
  const [index, setIndex] = useState(0)
  const [active, setActive] = useState<string | null>(null)

  if (active) return <div className="inv-tool">
    <button className="inv-back" onClick={() => setActive(null)}>‹ TOOLS</button>
    {active === 'phone' ? <PhonePreview /> : <NotebookTool />}
  </div>

  return <div className="inv-backdrop">
    <ToolRack index={index} />
    <button className="inv-arrow left" onClick={() => setIndex(i => (i - 1 + TOOLS.length) % TOOLS.length)} aria-label="Previous tool">◀</button>
    <button className="inv-arrow right" onClick={() => setIndex(i => (i + 1) % TOOLS.length)} aria-label="Next tool">▶</button>
    <div className="inv-plate">
      <div className="inv-name">{TOOLS[index].name}</div>
      <div className="inv-dots">{TOOLS.map((tool, i) => <span key={tool.key} className={i === index ? 'on' : ''} />)}</div>
      <button className="inv-use" onClick={() => setActive(TOOLS[index].key)}>USE ▸</button>
    </div>
    {onClose && <button className="inv-close" onClick={onClose}>×</button>}
    <p className="inv-hint">INVENTORY · dev preview</p>
  </div>
}

// Placeholder notebook tool — a lined page you can scribble on (not yet persisted).
function NotebookTool() {
  const [text, setText] = useState('')
  return <div className="notebook">
    <div className="notebook-page">
      <div className="notebook-head">FIELD NOTEBOOK</div>
      <textarea value={text} onChange={e => setText(e.target.value)} placeholder="Jot a lead…" spellCheck={false} />
    </div>
  </div>
}
