'use client';

import { useCallback, useEffect, useRef, useState } from 'react';
import { createPortal } from 'react-dom';
import { Loader2, Pause, Play, Volume2, VolumeX, X } from 'lucide-react';
import { Button } from '@/components/ui/button';
import { cn } from '@/lib/utils';

function formatDuration(seconds: number) {
  if (!Number.isFinite(seconds) || seconds < 0) return '0:00';
  const whole = Math.floor(seconds);
  const mins = Math.floor(whole / 60);
  const secs = whole % 60;
  return `${mins}:${secs.toString().padStart(2, '0')}`;
}

export function ChatVideoLightbox({
  open,
  src,
  fileName,
  durationMs,
  onClose
}: {
  open: boolean;
  src: string;
  fileName?: string;
  durationMs?: number;
  onClose: () => void;
}) {
  const videoRef = useRef<HTMLVideoElement | null>(null);
  const hideControlsTimerRef = useRef<ReturnType<typeof setTimeout> | null>(null);
  const [mounted, setMounted] = useState(false);
  const [playing, setPlaying] = useState(false);
  const [loading, setLoading] = useState(true);
  const [muted, setMuted] = useState(false);
  const [progress, setProgress] = useState(0);
  const [duration, setDuration] = useState(durationMs ? durationMs / 1000 : 0);
  const [controlsVisible, setControlsVisible] = useState(true);
  const [scrubbing, setScrubbing] = useState(false);

  useEffect(() => {
    setMounted(true);
  }, []);

  const revealControls = useCallback(() => {
    setControlsVisible(true);
    if (hideControlsTimerRef.current) clearTimeout(hideControlsTimerRef.current);
    hideControlsTimerRef.current = setTimeout(() => {
      if (playing) setControlsVisible(false);
    }, 2800);
  }, [playing]);

  const togglePlayback = useCallback(() => {
    const video = videoRef.current;
    if (!video) return;
    if (video.paused) {
      void video.play();
    } else {
      video.pause();
    }
    revealControls();
  }, [revealControls]);

  useEffect(() => {
    if (!open) return;
    function handleKeyDown(event: KeyboardEvent) {
      if (event.key === 'Escape') onClose();
      if (event.key === ' ') {
        event.preventDefault();
        togglePlayback();
      }
    }
    window.addEventListener('keydown', handleKeyDown);
    return () => window.removeEventListener('keydown', handleKeyDown);
  }, [open, onClose, togglePlayback]);

  useEffect(() => {
    if (!open || typeof document === 'undefined') return;
    const previousOverflow = document.body.style.overflow;
    document.body.style.overflow = 'hidden';
    return () => {
      document.body.style.overflow = previousOverflow;
    };
  }, [open]);

  useEffect(() => {
    const video = videoRef.current;
    if (!video || !open) return;

    const onLoaded = () => {
      if (Number.isFinite(video.duration) && video.duration > 0) {
        setDuration(video.duration);
      }
      setLoading(false);
    };
    const onTimeUpdate = () => {
      if (!scrubbing && video.duration) {
        setProgress(video.currentTime / video.duration);
      }
    };
    const onPlay = () => {
      setPlaying(true);
      revealControls();
    };
    const onPause = () => {
      setPlaying(false);
      setControlsVisible(true);
    };
    const onEnded = () => {
      setPlaying(false);
      setControlsVisible(true);
    };

    video.addEventListener('loadedmetadata', onLoaded);
    video.addEventListener('timeupdate', onTimeUpdate);
    video.addEventListener('play', onPlay);
    video.addEventListener('pause', onPause);
    video.addEventListener('ended', onEnded);

    return () => {
      video.removeEventListener('loadedmetadata', onLoaded);
      video.removeEventListener('timeupdate', onTimeUpdate);
      video.removeEventListener('play', onPlay);
      video.removeEventListener('pause', onPause);
      video.removeEventListener('ended', onEnded);
    };
  }, [open, revealControls, scrubbing, src]);

  useEffect(() => {
    if (!open) return;
    const video = videoRef.current;
    if (!video) return;
    setLoading(true);
    setProgress(0);
    setPlaying(false);
    video.src = src;
    video.load();
    void video.play().catch(() => undefined);
  }, [open, src]);

  useEffect(() => {
    return () => {
      if (hideControlsTimerRef.current) clearTimeout(hideControlsTimerRef.current);
    };
  }, []);

  function seekTo(ratio: number) {
    const video = videoRef.current;
    if (!video || !video.duration) return;
    const next = Math.min(Math.max(ratio, 0), 1);
    video.currentTime = next * video.duration;
    setProgress(next);
  }

  if (!open || !mounted) return null;

  return createPortal(
    <div
      className="fixed inset-0 z-[5500] flex flex-col bg-[#05070d]/96"
      onMouseMove={revealControls}
      onClick={revealControls}
    >
      <div
        className={cn(
          'flex items-center justify-between px-4 py-3 text-white transition-opacity duration-300',
          controlsVisible ? 'opacity-100' : 'opacity-0'
        )}
      >
        <div className="min-w-0">
          <p className="truncate text-sm font-medium">{fileName?.trim() || 'Видео'}</p>
          <p className="text-xs text-white/55">Полноэкранный просмотр</p>
        </div>
        <Button
          type="button"
          size="icon"
          variant="ghost"
          className="text-white hover:bg-white/10"
          aria-label="Закрыть"
          onClick={onClose}
        >
          <X className="h-5 w-5" />
        </Button>
      </div>

      <div className="relative flex min-h-0 flex-1 items-center justify-center px-4 pb-4">
        <video
          ref={videoRef}
          src={src}
          className="max-h-full max-w-full rounded-2xl bg-black shadow-[0_24px_80px_rgba(0,0,0,0.45)]"
          playsInline
          onClick={togglePlayback}
        />

        {loading ? (
          <div className="pointer-events-none absolute inset-0 flex items-center justify-center">
            <Loader2 className="h-12 w-12 animate-spin text-white/80" />
          </div>
        ) : null}

        {!playing && !loading ? (
          <button
            type="button"
            onClick={togglePlayback}
            className="absolute flex h-20 w-20 items-center justify-center rounded-full bg-white/15 text-white backdrop-blur-sm transition hover:bg-white/25"
            aria-label="Воспроизвести"
          >
            <Play className="ml-1 h-10 w-10" />
          </button>
        ) : null}
      </div>

      <div
        className={cn(
          'px-4 pb-[max(1rem,env(safe-area-inset-bottom))] transition-opacity duration-300',
          controlsVisible ? 'opacity-100' : 'opacity-0'
        )}
      >
        <div className="mx-auto w-full max-w-3xl rounded-2xl bg-black/45 px-4 py-3 backdrop-blur-md">
          <input
            type="range"
            min={0}
            max={1000}
            value={Math.round(progress * 1000)}
            className="h-1.5 w-full cursor-pointer appearance-none rounded-full bg-white/20 accent-[#3390ec]"
            onChange={(event) => {
              setScrubbing(true);
              seekTo(Number(event.target.value) / 1000);
            }}
            onMouseUp={() => setScrubbing(false)}
            onTouchEnd={() => setScrubbing(false)}
            aria-label="Позиция воспроизведения"
          />

          <div className="mt-3 flex items-center gap-3">
            <button
              type="button"
              onClick={togglePlayback}
              className="flex h-10 w-10 items-center justify-center rounded-full bg-white/10 text-white transition hover:bg-white/20"
              aria-label={playing ? 'Пауза' : 'Воспроизвести'}
            >
              {playing ? <Pause className="h-5 w-5" /> : <Play className="ml-0.5 h-5 w-5" />}
            </button>

            <span className="min-w-[88px] text-xs tabular-nums text-white/80">
              {formatDuration(progress * duration)} / {formatDuration(duration)}
            </span>

            <div className="flex-1" />

            <button
              type="button"
              onClick={() => {
                const video = videoRef.current;
                if (!video) return;
                video.muted = !video.muted;
                setMuted(video.muted);
              }}
              className="flex h-10 w-10 items-center justify-center rounded-full bg-white/10 text-white transition hover:bg-white/20"
              aria-label={muted ? 'Включить звук' : 'Выключить звук'}
            >
              {muted ? <VolumeX className="h-5 w-5" /> : <Volume2 className="h-5 w-5" />}
            </button>
          </div>
        </div>
      </div>
    </div>,
    document.body
  );
}
