import { useRef, useState, useCallback, useEffect, forwardRef, useImperativeHandle } from 'react'
import { FaPlay, FaPause, FaStop, FaStepBackward, FaStepForward, FaVolumeMute, FaVolumeUp } from 'react-icons/fa'
import { endpoints } from '../../api'
import type { Media } from '../../types'

interface Props {
  media: Media
  onTimeUpdate: (time: number) => void
  children?: React.ReactNode
}

const STEP_BTN_CLASS = 'w-9 h-8 flex items-center justify-center bg-az-bg rounded hover:bg-az-border text-az-text text-xs font-mono'
const ICON_BTN_CLASS = 'w-10 h-10 flex items-center justify-center bg-az-bg rounded hover:bg-az-border text-white'

export interface VideoPlayerHandle {
  seek: (seconds: number) => void
  getVideoElement: () => HTMLVideoElement | null
}

const VideoPlayer = forwardRef<VideoPlayerHandle, Props>(function VideoPlayer({ media, onTimeUpdate, children }, ref) {
  const videoRef = useRef<HTMLVideoElement>(null)

  useImperativeHandle(ref, () => ({
    seek(seconds: number) {
      if (videoRef.current) {
        videoRef.current.currentTime = seconds
        setCurrentTime(seconds)
      }
    },
    getVideoElement() {
      return videoRef.current
    },
  }))
  const [error, setError] = useState<string | null>(null)
  const [playing, setPlaying] = useState(false)
  const [currentTime, setCurrentTime] = useState(0)
  const [duration, setDuration] = useState(0)
  const [muted, setMuted] = useState(false)

  const videoUrl = media.path.startsWith('blob:')
    ? media.path
    : endpoints.annotations.mediaFile(media.id)

  const stepFrames = useCallback((count: number) => {
    const video = videoRef.current
    if (!video) return
    const fps = 30
    video.currentTime = Math.max(0, Math.min(video.duration, video.currentTime + count / fps))
  }, [])

  const togglePlay = useCallback(() => {
    const v = videoRef.current
    if (!v) return
    if (v.paused) { v.play(); setPlaying(true) }
    else { v.pause(); setPlaying(false) }
  }, [])

  const stop = useCallback(() => {
    const v = videoRef.current
    if (!v) return
    v.pause()
    v.currentTime = 0
    setPlaying(false)
  }, [])

  useEffect(() => {
    const handler = (e: KeyboardEvent) => {
      if (e.target instanceof HTMLInputElement || e.target instanceof HTMLTextAreaElement) return
      switch (e.key) {
        case ' ': e.preventDefault(); togglePlay(); break
        case 'ArrowLeft': e.preventDefault(); stepFrames(e.ctrlKey ? -150 : -1); break
        case 'ArrowRight': e.preventDefault(); stepFrames(e.ctrlKey ? 150 : 1); break
        case 'm': case 'M': setMuted(m => !m); break
      }
    }
    window.addEventListener('keydown', handler)
    return () => window.removeEventListener('keydown', handler)
  }, [togglePlay, stepFrames])

  const formatTime = (s: number) => {
    const m = Math.floor(s / 60)
    const sec = Math.floor(s % 60)
    return `${m.toString().padStart(2, '0')}:${sec.toString().padStart(2, '0')}`
  }

  return (
    <div className="bg-black flex flex-col flex-1 min-h-0">
      {error && <div className="bg-az-red/80 text-white text-xs px-2 py-1">{error}</div>}
      <div className="relative flex-1 min-h-0 flex items-center justify-center">
        <video
          ref={videoRef}
          src={videoUrl}
          muted={muted}
          controls={false}
          playsInline
          className="max-w-full max-h-full object-contain"
          onTimeUpdate={e => {
            const t = (e.target as HTMLVideoElement).currentTime
            setCurrentTime(t)
            onTimeUpdate(t)
          }}
          onLoadedMetadata={e => {
            setDuration((e.target as HTMLVideoElement).duration)
            setError(null)
          }}
          onError={() => setError(`Failed to load video (${media.name})`)}
        />
        {children && <div className="absolute inset-0">{children}</div>}
      </div>
      {/* Progress row: time | slider | remaining */}
      <div className="flex items-center gap-3 bg-az-header px-4 py-1.5">
        <span className="text-white text-xs font-mono tabular-nums min-w-[40px] text-right">{formatTime(currentTime)}</span>
        <input
          type="range"
          min={0}
          max={duration || 1}
          step={0.01}
          value={currentTime}
          onChange={e => {
            const v = Number(e.target.value)
            setCurrentTime(v)
            if (videoRef.current) videoRef.current.currentTime = v
          }}
          className="flex-1 accent-az-orange h-1 cursor-pointer"
          style={{
            background: `linear-gradient(to right, #fd7e14 0%, #fd7e14 ${(currentTime / (duration || 1)) * 100}%, #495057 ${(currentTime / (duration || 1)) * 100}%, #495057 100%)`,
          }}
        />
        <span className="text-white text-xs font-mono tabular-nums min-w-[40px]">-{formatTime(Math.max(0, duration - currentTime))}</span>
      </div>

      {/* Buttons row */}
      <div className="flex items-center justify-center gap-2 bg-az-header pb-2 flex-wrap">
        <button onClick={() => stepFrames(-1)} title="Previous frame" className={ICON_BTN_CLASS}>
          <FaStepBackward size={14} />
        </button>
        <button onClick={togglePlay} title={playing ? 'Pause' : 'Play'} className="w-10 h-10 flex items-center justify-center bg-az-orange rounded hover:brightness-110 text-white">
          {playing ? <FaPause size={14} /> : <FaPlay size={14} />}
        </button>
        <button onClick={() => stepFrames(1)} title="Next frame" className={ICON_BTN_CLASS}>
          <FaStepForward size={14} />
        </button>
        <button onClick={stop} title="Stop" className={ICON_BTN_CLASS}>
          <FaStop size={14} />
        </button>

        <span className="w-px h-8 bg-az-border mx-1" />

        {[1, 5, 10, 30, 60].map(n => (
          <button key={`prev-${n}`} onClick={() => stepFrames(-n)} title={`-${n} frames`} className={STEP_BTN_CLASS}>
            -{n}
          </button>
        ))}
        <span className="w-px h-8 bg-az-border mx-1" />
        {[1, 5, 10, 30, 60].map(n => (
          <button key={`next-${n}`} onClick={() => stepFrames(n)} title={`+${n} frames`} className={STEP_BTN_CLASS}>
            +{n}
          </button>
        ))}

        <span className="w-px h-8 bg-az-border mx-1" />

        <button onClick={() => setMuted(m => !m)} title={muted ? 'Unmute' : 'Mute'} className={ICON_BTN_CLASS}>
          {muted ? <FaVolumeMute size={14} /> : <FaVolumeUp size={14} />}
        </button>
      </div>
    </div>
  )
})

export default VideoPlayer
