import React, { useRef, useImperativeHandle, forwardRef, useState } from 'react';
import StationOverlay from '../overlay/StationOverlay';
import RoutePanel from '../overlay/RoutePanel';
import 'video.js/dist/video-js.css';
import { useVideoPlayer } from '../../hooks/useVideoPlayer';
import { useFrameStep } from '../../hooks/useFrameStep';
import { useKeyboard } from '../../hooks/useKeyboard';
import { usePlayerStore } from '../../store/playerStore';
import { captureFrame, downloadDataUrl } from '../../utils/frameCapture';
import { secondsToTimecode, secondsToFrame } from '../../utils/timecode';
import { useCaptureStore } from '../../store/captureStore';
import HlsConversionStatus from './HlsConversionStatus';
import { StationBar } from '../../stationbar/StationBar';

export interface VideoPlayerHandle {
  loadLocalFile: (file: File) => void;
  loadServerStream: (videoId: string, filename: string) => void | Promise<void>;
  seekTo: (time: number) => void;
  getVideoElement: () => HTMLVideoElement | null;
}

interface VideoPlayerProps {
  onAddMemo: (time: number) => void;
  onToggleHelp?: () => void;
}

const VideoPlayer = forwardRef<VideoPlayerHandle, VideoPlayerProps>(
  function VideoPlayer({ onAddMemo, onToggleHelp }, ref) {
    const containerRef = useRef<HTMLDivElement>(null);
    const wrapperRef = useRef<HTMLDivElement>(null);

    const { playerRef, loadLocalFile, loadServerStream, switchToHls, getVideoElement } =
      useVideoPlayer(containerRef);

    const { stepForward, stepBackward, fps } = useFrameStep(playerRef);
    const { currentTime, duration, playing, source, playbackRate } = usePlayerStore();

    // Expose methods to parent via ref
    useImperativeHandle(ref, () => ({
      loadLocalFile,
      loadServerStream,
      seekTo: (time: number) => {
        playerRef.current?.currentTime(time);
      },
      getVideoElement,
    }));

    const addCapture = useCaptureStore((s) => s.addCapture);

    const handleCaptureFrame = () => {
      const video = getVideoElement();
      if (!video) return;
      const dataUrl = captureFrame(video);
      if (!dataUrl) return;
      const filename = `frame_${secondsToTimecode(currentTime).replace(/[:.]/g, '-')}.jpg`;
      downloadDataUrl(dataUrl, filename);
      addCapture({
        id: `${Date.now()}-${Math.random().toString(36).slice(2, 8)}`,
        dataUrl,
        time: currentTime,
        filename,
        createdAt: Date.now(),
      });
    };

    const handleAddMemo = () => onAddMemo(currentTime);
    const [showStations, setShowStations] = useState(true);

    const handleTogglePlay = (): void => {
      const p = playerRef.current;
      if (!p) return;
      if (playing) p.pause();
      else void p.play();
    };
    const handleStop = (): void => {
      const p = playerRef.current;
      if (!p) return;
      p.pause();
      p.currentTime(0);
    };
    const handleSeek = (t: number): void => {
      playerRef.current?.currentTime(t);
    };

    useKeyboard({
      playerRef,
      onStepForward: stepForward,
      onStepBackward: stepBackward,
      onCaptureFrame: handleCaptureFrame,
      onAddMemo: handleAddMemo,
      onToggleHelp,
      containerRef: wrapperRef,
    });

    // Drag and drop local video file
    const handleDrop = (e: React.DragEvent) => {
      e.preventDefault();
      const file = e.dataTransfer.files[0];
      if (file?.type.startsWith('video/')) loadLocalFile(file);
    };

    // VIDEO_FPS: 영상 실제 fps (29.97 = 30000/1001). Python SRT FrameCnt 기준과 일치.
    // stableFps(VFC 감지)는 31fps 오감지가 있어 프레임 번호 표시에는 사용하지 않음.
    const VIDEO_FPS = 30000 / 1001;
    const frame = secondsToFrame(currentTime, VIDEO_FPS);
    const videoId = source?.kind === 'server' ? source.videoId : null;

    return (
      <div
        ref={wrapperRef}
        className="relative bg-black w-full"
        onDrop={handleDrop}
        onDragOver={(e) => e.preventDefault()}
      >
        {/* 영상 영역 — 타임코드를 '영상 하단'에 앵커하기 위한 relative 래퍼 */}
        <div className="relative w-full">
          {/* Video.js container — data-vjs-player prevents extra wrapper per CLAUDE.md */}
          {/* 영상 클릭 = 재생/일시정지 토글 (컨트롤바 숨김 상태) */}
          <div
            data-vjs-player
            ref={containerRef}
            className="w-full"
            style={{ cursor: source ? 'pointer' : 'default' }}
            onClick={() => {
              if (source) handleTogglePlay();
            }}
          />
          {/* 프레임/타임코드 — 영상 좌상단 코너 HUD (정보 그룹) */}
          {source && (
            <div className="absolute top-2 left-2 bg-black/70 text-white text-xs px-2 py-1 rounded font-mono pointer-events-none z-30">
              {secondsToTimecode(currentTime)} | F{frame} | {fps}fps
            </div>
          )}
          {/* 재생 배속 — 영상 우하단 (항상 보임). 현재 배속은 파랗게 강조 */}
          {source && (
            <div className="absolute bottom-2 right-2 flex items-center gap-1 bg-black/70 px-2 py-1 rounded z-30">
              <span className="text-gray-400 text-xs">배속</span>
              {[1, 1.5, 2, 3, 4].map((r) => (
                <button
                  key={r}
                  type="button"
                  onClick={() => playerRef.current?.playbackRate(r)}
                  className={`text-xs px-1.5 py-0.5 rounded font-semibold ${
                    Math.abs(playbackRate - r) < 0.01
                      ? 'bg-blue-600 text-white'
                      : 'bg-gray-700 text-gray-200 hover:bg-gray-600'
                  }`}
                >
                  {r}x
                </button>
              ))}
            </div>
          )}
          {/* 루트 패널 미니맵 — 영상 영역 기준(아래 StationBar 침범 방지) */}
          <RoutePanel
            currentTime={currentTime}
            visible={showStations}
            onSeek={(time) => playerRef.current?.currentTime(time)}
          />
        </div>

        {/* Empty state placeholder */}
        {!source && (
          <div className="absolute inset-0 flex flex-col items-center justify-center text-gray-500 pointer-events-none select-none" style={{ minHeight: '240px' }}>
            <div className="text-5xl mb-3">&#9654;</div>
            <p className="text-lg">동영상을 드래그하거나 아래에서 선택하세요</p>
            <p className="text-sm mt-1">로컬 파일 또는 서버 영상 재생 지원</p>
          </div>
        )}

        {/* 측점 오버레이 */}
        <StationOverlay
          currentFrame={frame}
          currentTime={currentTime}
          fps={fps}
          visible={showStations}
        />

        {/* 측점 기반 재생 바 — videoplayer-main 스테이션 바 이식 (시간 스크러버 대체) */}
        <StationBar
          currentTime={currentTime}
          duration={duration}
          playing={playing}
          onTogglePlay={handleTogglePlay}
          onStop={handleStop}
          onCapture={handleCaptureFrame}
          onSeek={handleSeek}
          showStations={showStations}
          onToggleStations={() => setShowStations((v) => !v)}
        />

        {/* abcVideo 전용 유틸 행 (파일/프레임이동/HLS) */}
        <div className="flex items-center gap-2 p-2 bg-gray-900 flex-wrap">
          <label className="cursor-pointer bg-blue-600 hover:bg-blue-700 text-white text-sm px-3 py-1.5 rounded">
            파일 선택
            <input
              type="file"
              accept="video/*"
              className="hidden"
              onChange={(e) => {
                const file = e.target.files?.[0];
                if (file) loadLocalFile(file);
              }}
            />
          </label>

          {/* 프레임 직접 이동 */}
          <form
            onSubmit={e => {
              e.preventDefault();
              const input = (e.currentTarget.elements.namedItem('frameInput') as HTMLInputElement);
              const frameNum = parseInt(input.value, 10);
              if (!isNaN(frameNum)) {
                playerRef.current?.currentTime(frameNum / VIDEO_FPS);
              }
              input.blur();
            }}
            className="flex items-center gap-1"
          >
            <span className="text-gray-500 text-xs">F</span>
            <input
              name="frameInput"
              type="number"
              min={0}
              step={1}
              placeholder="프레임"
              className="w-20 bg-black/60 border border-gray-600 rounded px-1.5 py-1 text-xs text-yellow-300 font-mono
                         [appearance:textfield] [&::-webkit-outer-spin-button]:appearance-none [&::-webkit-inner-spin-button]:appearance-none"
            />
            <button
              type="submit"
              className="text-xs px-2 py-1 rounded border border-gray-600 bg-gray-800 text-gray-300 hover:text-white"
            >
              이동
            </button>
          </form>

          {videoId && (
            <HlsConversionStatus
              videoId={videoId}
              onConversionDone={() => switchToHls(videoId)}
            />
          )}

          <span className="text-gray-500 text-xs ml-auto hidden sm:inline">
            Space 재생 | ←/→ 5초 | J/L 10초 | ,/. 프레임 | Shift+S 캡처
          </span>
        </div>
      </div>
    );
  }
);

export default VideoPlayer;
