import { useCallback, useEffect, useRef, useState } from 'react'
import { useNavigate } from 'react-router-dom'
import { ROUTE_PATHS } from '../app/route-paths'
import { usePoseLoop } from '../pose/usePoseLoop'
import type { FrameCallback } from '../pose/usePoseLoop'
import type { PoseSettings } from '../types'
import { loadSettings } from '../types'
import styles from './RecordPage.module.css'

interface RecordedFrame {
  t: number
  landmarks: { x: number; y: number; visibility?: number }[]
  worldLandmarks: { x: number; y: number; z: number; visibility?: number }[]
}

type RecordState = 'idle' | 'countdown' | 'recording' | 'done'

export function RecordPage() {
  const navigate = useNavigate()
  const videoRef = useRef<HTMLVideoElement>(null)
  const canvasRef = useRef<HTMLCanvasElement>(null)
  const arCanvasRef = useRef<HTMLCanvasElement>(null)

  const [settings] = useState<PoseSettings>(loadSettings)
  const [recordState, setRecordState] = useState<RecordState>('idle')
  const [countdownValue, setCountdownValue] = useState(5)
  const [copied, setCopied] = useState(false)

  const framesRef = useRef<RecordedFrame[]>([])
  const [frameCount, setFrameCount] = useState(0)
  const recordStartRef = useRef(0)
  const recordStateRef = useRef(recordState)
  recordStateRef.current = recordState

  const onFrame: FrameCallback = useCallback((landmarks, worldLandmarks, timestamp) => {
    if (recordStateRef.current !== 'recording') return
    const t = timestamp - recordStartRef.current
    framesRef.current.push({
      t,
      landmarks: landmarks.map(l => ({ x: l.x, y: l.y, visibility: l.visibility })),
      worldLandmarks: worldLandmarks.map(l => ({ x: l.x, y: l.y, z: l.z, visibility: l.visibility })),
    })
    setFrameCount(framesRef.current.length)
  }, [])

  const { loading, error } = usePoseLoop(
    videoRef,
    canvasRef,
    arCanvasRef,
    settings,
    null,
    {},
    'full',
    onFrame,
  )

  // Countdown timer
  useEffect(() => {
    if (recordState !== 'countdown') return
    if (countdownValue <= 0) {
      recordStartRef.current = performance.now()
      framesRef.current = []
      setFrameCount(0)
      setRecordState('recording')
      return
    }
    const timer = setTimeout(() => setCountdownValue(v => v - 1), 1000)
    return () => clearTimeout(timer)
  }, [recordState, countdownValue])

  function startCountdown() {
    setCountdownValue(5)
    setCopied(false)
    setRecordState('countdown')
  }

  function stopRecording() {
    setRecordState('done')
  }

  function copyJson() {
    const json = JSON.stringify(framesRef.current)
    navigator.clipboard.writeText(json).then(() => {
      setCopied(true)
      setTimeout(() => setCopied(false), 2000)
    })
  }

  function downloadJson() {
    const json = JSON.stringify(framesRef.current)
    const blob = new Blob([json], { type: 'application/json' })
    const url = URL.createObjectURL(blob)
    const a = document.createElement('a')
    a.href = url
    a.download = `recording-${Date.now()}.json`
    a.click()
    URL.revokeObjectURL(url)
  }

  function recordAgain() {
    framesRef.current = []
    setFrameCount(0)
    setCopied(false)
    setRecordState('idle')
  }

  return (
    <div className={styles.root}>
      <video ref={videoRef} className="webcam-video" playsInline muted />
      <canvas ref={canvasRef} className="pose-overlay" />
      <canvas ref={arCanvasRef} className="ar-overlay" />

      {loading && (
        <div className={styles.loadingOverlay}>
          <div className={styles.spinner} />
          <p className={styles.loadingText}>Starting camera...</p>
        </div>
      )}

      {error && (
        <div className={styles.loadingOverlay}>
          <p className={styles.loadingText}>{error}</p>
        </div>
      )}

      <button className={styles.backBtn} onClick={() => navigate(ROUTE_PATHS.home)}>
        Back
      </button>

      {/* Countdown overlay */}
      {recordState === 'countdown' && countdownValue > 0 && (
        <div className={styles.countdown}>
          <span key={countdownValue} className={styles.countdownNumber}>
            {countdownValue}
          </span>
        </div>
      )}

      {/* Recording indicator */}
      {recordState === 'recording' && (
        <div className={styles.recordingIndicator}>
          <div className={styles.recordingDot} />
          <span className={styles.recordingText}>REC</span>
          <span className={styles.frameCount}>{frameCount} frames</span>
        </div>
      )}

      {/* Controls */}
      {recordState === 'idle' && !loading && !error && (
        <div className={styles.controls}>
          <button className={styles.recordBtn} onClick={startCountdown}>
            <div className={styles.recordBtnInner} />
          </button>
        </div>
      )}

      {recordState === 'recording' && (
        <div className={styles.controls}>
          <button className={styles.stopBtn} onClick={stopRecording}>
            <div className={styles.recordBtnInner} />
          </button>
        </div>
      )}

      {/* Results overlay */}
      {recordState === 'done' && (
        <div className={styles.resultOverlay}>
          <h2 className={styles.resultTitle}>Recording Complete</h2>
          <p className={styles.resultInfo}>
            {framesRef.current.length} frames captured
            {framesRef.current.length > 0 && (
              <> ({(framesRef.current[framesRef.current.length - 1].t / 1000).toFixed(1)}s)</>
            )}
          </p>
          <div className={styles.resultActions}>
            <button className={styles.actionBtn} onClick={downloadJson}>
              Download JSON
            </button>
            <button className={styles.actionBtn} onClick={copyJson}>
              {copied ? 'Copied!' : 'Copy JSON'}
            </button>
            <button className={styles.actionBtnSecondary} onClick={recordAgain}>
              Record Again
            </button>
          </div>
          <span className={styles.copiedMsg}>
            {copied ? 'JSON copied to clipboard' : ''}
          </span>
        </div>
      )}
    </div>
  )
}
