import React, { useEffect, useRef, useState } from 'react'
import { createRoot } from 'react-dom/client'
import './styles.css'

/* ── hooks ──────────────────────────────────────────────── */

function useClock(timeZone) {
  const [t, setT] = useState('')
  useEffect(() => {
    const tick = () => setT(new Date().toLocaleTimeString('en-GB', { timeZone, hour12: false }))
    tick()
    const id = setInterval(tick, 1000)
    return () => clearInterval(id)
  }, [timeZone])
  return t
}

/* ── typewriter ─────────────────────────────────────────── */

function Typewriter({ text, delay = 0, speed = 45, onDone }) {
  const [out, setOut] = useState('')
  const [done, setDone] = useState(false)
  useEffect(() => {
    let i = 0
    const start = setTimeout(() => {
      const id = setInterval(() => {
        i += 1
        setOut(text.slice(0, i))
        if (i >= text.length) {
          clearInterval(id)
          setDone(true)
          onDone?.()
        }
      }, speed)
      return () => clearInterval(id)
    }, delay)
    return () => clearTimeout(start)
  }, [text, delay, speed, onDone])
  return <>{out}{!done && <span className="cursor">_</span>}</>
}

/* ── aurora canvas: stars + aurora + snow + mountains + pines ── */

function AuroraCanvas() {
  const canvasRef = useRef(null)

  useEffect(() => {
    const canvas = canvasRef.current
    const ctx = canvas.getContext('2d')
    let anim
    let w, h, dpr

    const stars = Array.from({ length: 160 }, () => ({
      x: Math.random(),
      y: Math.random() * 0.52,
      size: Math.random() * 1.4 + 0.3,
      phase: Math.random() * Math.PI * 2,
      twinkle: 0.3 + Math.random() * 0.7,
    }))

    const flakes = Array.from({ length: 60 }, (_, i) => ({
      x: Math.random(),
      y: Math.random(),
      size: Math.random() * 1.6 + 0.6,
      speed: 0.06 + Math.random() * 0.22,
      drift: (Math.random() - 0.5) * 0.35,
      swayPhase: Math.random() * Math.PI * 2,
    }))

    const trees = [0.08, 0.18, 0.28, 0.38, 0.52, 0.62, 0.78, 0.88, 0.96]

    const resize = () => {
      dpr = Math.min(window.devicePixelRatio || 1, 2)
      w = window.innerWidth
      h = window.innerHeight
      canvas.width = w * dpr
      canvas.height = h * dpr
      canvas.style.width = `${w}px`
      canvas.style.height = `${h}px`
      ctx.setTransform(dpr, 0, 0, dpr, 0, 0)
    }

    const mountainY = (x) =>
      h * 0.68 +
      Math.sin(x * 0.007 + 1.3) * 50 +
      Math.sin(x * 0.0028 + 2.4) * 90

    const draw = (time) => {
      // bg
      ctx.fillStyle = '#030803'
      ctx.fillRect(0, 0, w, h)

      // stars
      stars.forEach((s) => {
        const a = 0.15 + 0.85 * Math.abs(Math.sin(time * 0.0007 * s.twinkle + s.phase))
        ctx.beginPath()
        ctx.arc(s.x * w, s.y * h, s.size, 0, Math.PI * 2)
        ctx.fillStyle = `rgba(210,235,210,${a})`
        ctx.fill()
      })

      // aurora ribbons
      for (let b = 0; b < 4; b++) {
        const base = h * (0.14 + b * 0.09)
        ctx.beginPath()
        for (let x = -10; x <= w + 10; x += 5) {
          const y =
            base +
            Math.sin(x * 0.0016 + time * 0.00022 + b * 2.3) * 55 +
            Math.sin(x * 0.004 + time * 0.00008 * (b + 1)) * 22
          if (x === -10) ctx.moveTo(x, y)
          else ctx.lineTo(x, y)
        }
        ctx.lineTo(w, h * 0.85)
        ctx.lineTo(0, h * 0.85)
        ctx.closePath()
        const g = ctx.createLinearGradient(0, base - 40, 0, h * 0.75)
        const stops = [
          ['rgba(51,255,51,0.055)', 'rgba(0,0,0,0)'],
          ['rgba(0,255,170,0.04)', 'rgba(0,0,0,0)'],
          ['rgba(180,255,100,0.03)', 'rgba(0,0,0,0)'],
          ['rgba(51,255,200,0.025)', 'rgba(0,0,0,0)'],
        ]
        g.addColorStop(0, stops[b][0])
        g.addColorStop(1, stops[b][1])
        ctx.fillStyle = g
        ctx.fill()
      }

      // snow
      flakes.forEach((f, idx) => {
        f.y += f.speed * 0.016
        f.x += f.drift * 0.016 + Math.sin(time * 0.001 + f.swayPhase) * 0.0003
        if (f.y > 1.01) { f.y = -0.02; f.x = Math.random() }
        if (f.x > 1.01) f.x = 0
        if (f.x < -0.01) f.x = 1
        ctx.beginPath()
        ctx.arc(f.x * w, f.y * h, f.size, 0, Math.PI * 2)
        ctx.fillStyle = `rgba(230,245,230,${0.35 + 0.65 * Math.sin(time * 0.002 + idx)})`
        ctx.fill()
      })

      // mountain silhouette
      ctx.beginPath()
      ctx.moveTo(0, h)
      for (let x = 0; x <= w; x += 24) {
        const my = mountainY(x) + (Math.random() > 0.94 ? -12 : 0)
        ctx.lineTo(x, my)
      }
      ctx.lineTo(w, h)
      ctx.closePath()
      ctx.fillStyle = '#010401'
      ctx.fill()

      // pine trees
      trees.forEach((tx) => {
        const bx = tx * w
        const by = mountainY(bx)
        // trunk
        ctx.fillStyle = '#000300'
        ctx.fillRect(bx - 1.5, by, 3, 14)
        // tiers
        for (let tier = 0; tier < 3; tier++) {
          const tw = 11 - tier * 3
          const th = 16 - tier * 3
          const ty = by - 2 - tier * 12
          ctx.beginPath()
          ctx.moveTo(bx - tw, ty)
          ctx.lineTo(bx + tw, ty)
          ctx.lineTo(bx, ty - th)
          ctx.closePath()
          ctx.fillStyle = '#000400'
          ctx.fill()
        }
      })

      anim = requestAnimationFrame(draw)
    }

    resize()
    window.addEventListener('resize', resize)
    anim = requestAnimationFrame(draw)
    return () => {
      cancelAnimationFrame(anim)
      window.removeEventListener('resize', resize)
    }
  }, [])

  return <canvas className="sky" ref={canvasRef} aria-hidden="true" />
}

/* ── App ─────────────────────────────────────────────────── */

function App() {
  const clock = useClock('Europe/Copenhagen')
  const [phase, setPhase] = useState(0)
  const [bootDone, setBootDone] = useState(false)

  useEffect(() => {
    const timers = [
      setTimeout(() => setPhase(1), 900),
      setTimeout(() => setPhase(2), 2600),
      setTimeout(() => setPhase(3), 4200),
      setTimeout(() => setPhase(4), 5400),
      setTimeout(() => setBootDone(true), 6000),
    ]
    return () => timers.forEach(clearTimeout)
  }, [])

  return (
    <div className="site">
      <AuroraCanvas />
      <div className="crt" aria-hidden="true" />
      <div className="grain" aria-hidden="true" />

      <div className={`boot${bootDone ? ' done' : ''}`}>
        {phase >= 1 && <span className="boot-line">INIT NORDIC RELAY...</span>}
        {phase >= 2 && <span className="boot-line">CALIBRATING AURORA SENSORS...</span>}
        {phase >= 3 && <span className="boot-line">ACQUIRING SIGNAL...</span>}
        {phase >= 4 && <span className="boot-line">READY.</span>}
        {phase >= 1 && !bootDone && <span className="boot-cursor">_</span>}
      </div>

      <main>
        <h1 className={bootDone ? 'on' : ''}>ANOTHER DAN</h1>
        <p className={`tagline ${bootDone ? 'on' : ''}`}>
          <Typewriter text="sounds for the strange in-between" delay={bootDone ? 400 : 0} speed={55} />
        </p>
        <p className={`coords ${bootDone ? 'on' : ''}`}>55°40′34″N  12°34′06″E  ·  CPH</p>
        <div className={`actions ${bootDone ? 'on' : ''}`}>
          <a className="action" href="https://open.spotify.com/artist/3hXWFbrtft1d5pbR5t6ewA?si=2pYX4Z4iTcS0iHR8Gu7CUg" target="_blank" rel="noreferrer">
            [ SPOTIFY ]
          </a>
          <a className="action" href="mailto:dan@anotherdan.com?subject=Transmission">
            [ SAY HELLO ]
          </a>
        </div>
      </main>

      <footer>
        <span className="clock">{clock}</span>
        <span className="temp">—2°C</span>
        <span className="status">{bootDone ? '● ONLINE' : '○ BOOTING'}</span>
      </footer>
    </div>
  )
}

createRoot(document.getElementById('root')).render(<App />)
