import React from 'react';
import { useParams } from 'react-router-dom';
import { Loader2, Maximize2, Minimize2, Pause, Play, WifiOff } from 'lucide-react';
import { AnimatePresence, motion } from 'framer-motion';
import { useLiveShowState } from '../hooks/useLiveShowState';
import { useLiveShowPlayback } from '../hooks/useLiveShowPlayback';
import LiveShowStage from '../components/LiveShowStage';
import LiveShowBackdrop from '../components/LiveShowBackdrop';
import { useTranslation } from '../i18n/useTranslation';
import { prefersReducedMotion } from '../lib/motion';
import { resolveLiveShowEffect } from '../lib/liveShowEffects';

export default function LiveShowPlayerPage() {
  const { token } = useParams<{ token: string }>();
  const { t } = useTranslation();
  const { status, connection, error, event, photos, settings } = useLiveShowState(token ?? null);
  const [paused, setPaused] = React.useState(false);
  const { frame, layout, frameKey, nextFrame } = useLiveShowPlayback(photos, settings, { paused });
  const hasPhoto = frame.length > 0;
  const stageTitle = event?.name ?? t('liveShowPlayer.title', 'Live Show');
  const reducedMotion = prefersReducedMotion();
  const effect = resolveLiveShowEffect(settings.effect_preset, settings.effect_intensity, reducedMotion);
  const showStage = status === 'ready' && hasPhoto;
  const showEmpty = status === 'ready' && !hasPhoto;
  const [controlsVisible, setControlsVisible] = React.useState(true);
  const [isFullscreen, setIsFullscreen] = React.useState(false);
  const [isOnline, setIsOnline] = React.useState(typeof navigator !== 'undefined' ? navigator.onLine : true);
  const hideTimerRef = React.useRef<number | null>(null);
  const preloadRef = React.useRef<Set<string>>(new Set());
  const stageRef = React.useRef<HTMLDivElement | null>(null);

  React.useEffect(() => {
    document.body.classList.add('guest-immersive');
    return () => {
      document.body.classList.remove('guest-immersive');
    };
  }, []);

  React.useEffect(() => {
    const updateOnline = () => setIsOnline(navigator.onLine);
    window.addEventListener('online', updateOnline);
    window.addEventListener('offline', updateOnline);
    return () => {
      window.removeEventListener('online', updateOnline);
      window.removeEventListener('offline', updateOnline);
    };
  }, []);

  React.useEffect(() => {
    const handleFullscreen = () => setIsFullscreen(Boolean(document.fullscreenElement));
    document.addEventListener('fullscreenchange', handleFullscreen);
    handleFullscreen();
    return () => document.removeEventListener('fullscreenchange', handleFullscreen);
  }, []);

  const revealControls = React.useCallback(() => {
    setControlsVisible(true);
    if (hideTimerRef.current) {
      window.clearTimeout(hideTimerRef.current);
    }
    hideTimerRef.current = window.setTimeout(() => {
      setControlsVisible(false);
    }, 3000);
  }, []);

  React.useEffect(() => {
    if (!showStage) {
      setControlsVisible(true);
      return;
    }
    revealControls();
  }, [revealControls, showStage, frameKey]);

  const togglePause = React.useCallback(() => {
    setPaused((prev) => !prev);
  }, []);

  const toggleFullscreen = React.useCallback(async () => {
    const target = stageRef.current ?? document.documentElement;
    try {
      if (!document.fullscreenElement) {
        await target.requestFullscreen?.();
      } else {
        await document.exitFullscreen?.();
      }
    } catch (err) {
      console.warn('Fullscreen toggle failed', err);
    }
  }, []);

  React.useEffect(() => {
    const handleKey = (event: KeyboardEvent) => {
      if (event.target && (event.target as HTMLElement).closest('input, textarea, select, button')) {
        return;
      }
      if (event.code === 'Space') {
        event.preventDefault();
        togglePause();
        revealControls();
      }
      if (event.key.toLowerCase() === 'f') {
        event.preventDefault();
        toggleFullscreen();
        revealControls();
      }
      if (event.key === 'Escape' && document.fullscreenElement) {
        event.preventDefault();
        document.exitFullscreen?.();
      }
    };

    window.addEventListener('keydown', handleKey);
    return () => window.removeEventListener('keydown', handleKey);
  }, [revealControls, toggleFullscreen, togglePause]);

  React.useEffect(() => {
    const candidates = [...frame, ...nextFrame].slice(0, 6);
    candidates.forEach((photo) => {
      const src = photo.full_url || photo.thumb_url;
      if (!src || preloadRef.current.has(src)) {
        return;
      }
      const img = new Image();
      img.src = src;
      preloadRef.current.add(src);
    });
  }, [frame, nextFrame]);

  return (
    <div
      ref={stageRef}
      className="relative flex min-h-screen flex-col items-center justify-center overflow-hidden bg-black text-white"
      aria-busy={status === 'loading'}
      onMouseMove={revealControls}
      onTouchStart={revealControls}
    >
      <LiveShowBackdrop mode={settings.background_mode} photo={frame[0]} intensity={settings.effect_intensity} />
      <div className="pointer-events-none absolute inset-x-0 top-0 z-30 flex items-center justify-between px-6 py-4 text-sm">
        <span className="font-semibold text-white" style={{ fontFamily: 'var(--guest-heading-font)' }}>
          {stageTitle}
        </span>
        <span className="rounded-full bg-white/10 px-3 py-1 text-xs font-semibold uppercase tracking-[0.24em] text-white/70">
          {connection === 'sse'
            ? t('liveShowPlayer.connection.live', 'Live')
            : t('liveShowPlayer.connection.sync', 'Sync')}
        </span>
      </div>

      {status === 'loading' && (
        <div className="flex flex-col items-center gap-4 text-white/70">
          <Loader2 className="h-10 w-10 animate-spin" aria-hidden />
          <p className="text-sm">{t('liveShowPlayer.loading', 'Live Show wird geladen...')}</p>
        </div>
      )}

      {status === 'error' && (
        <div className="max-w-md space-y-2 px-6 text-center">
          <p className="text-lg font-semibold text-white">
            {t('liveShowPlayer.error.title', 'Live Show nicht erreichbar')}
          </p>
          <p className="text-sm text-white/70">
            {error ?? t('liveShowPlayer.error.description', 'Bitte überprüfe den Live-Link.')}
          </p>
        </div>
      )}

      <AnimatePresence initial={false} mode="sync">
        {showStage && (
          <motion.div key={frameKey} className="relative z-10 flex min-h-0 w-full flex-1 items-stretch" {...effect.frame}>
            <LiveShowStage layout={layout} photos={frame} title={stageTitle} />
          </motion.div>
        )}
      </AnimatePresence>

      {showStage && effect.flash && (
        <motion.div
          key={`flash-${frameKey}`}
          className="pointer-events-none absolute inset-0 z-20 bg-white"
          {...effect.flash}
        />
      )}

      <AnimatePresence initial={false}>
        {controlsVisible && (
          <motion.div
            className="absolute bottom-6 left-1/2 z-30 flex -translate-x-1/2 items-center gap-3 rounded-full border border-white/10 bg-black/60 px-4 py-2 text-xs text-white/80 shadow-lg backdrop-blur"
            initial={{ opacity: 0, y: 12 }}
            animate={{ opacity: 1, y: 0 }}
            exit={{ opacity: 0, y: 8 }}
            transition={{ duration: 0.2 }}
          >
            <button
              type="button"
              className="flex items-center gap-2 rounded-full bg-white/10 px-3 py-1 text-xs font-semibold uppercase tracking-[0.2em] text-white"
              onClick={togglePause}
            >
              {paused ? <Play className="h-4 w-4" aria-hidden /> : <Pause className="h-4 w-4" aria-hidden />}
              <span>{paused ? t('liveShowPlayer.controls.play', 'Play') : t('liveShowPlayer.controls.pause', 'Pause')}</span>
            </button>
            <button
              type="button"
              className="flex items-center gap-2 rounded-full bg-white/10 px-3 py-1 text-xs font-semibold uppercase tracking-[0.2em] text-white"
              onClick={toggleFullscreen}
            >
              {isFullscreen ? <Minimize2 className="h-4 w-4" aria-hidden /> : <Maximize2 className="h-4 w-4" aria-hidden />}
              <span>
                {isFullscreen
                  ? t('liveShowPlayer.controls.exitFullscreen', 'Exit fullscreen')
                  : t('liveShowPlayer.controls.fullscreen', 'Fullscreen')}
              </span>
            </button>
            {!isOnline && (
              <span className="flex items-center gap-2 text-white/70">
                <WifiOff className="h-4 w-4" aria-hidden />
                {t('liveShowPlayer.controls.offline', 'Offline')}
              </span>
            )}
          </motion.div>
        )}
      </AnimatePresence>

      {paused && showStage && (
        <div className="pointer-events-none absolute inset-0 z-20 flex items-center justify-center">
          <div className="rounded-full border border-white/20 bg-black/50 px-6 py-3 text-sm font-semibold uppercase tracking-[0.3em] text-white/80">
            {t('liveShowPlayer.controls.paused', 'Paused')}
          </div>
        </div>
      )}

      {showEmpty && (
        <div className="max-w-md space-y-2 px-6 text-center text-white/70">
          <p className="text-lg font-semibold text-white">
            {t('liveShowPlayer.empty.title', 'Noch keine Live-Fotos')}
          </p>
          <p className="text-sm">{t('liveShowPlayer.empty.description', 'Warte auf die ersten Uploads...')}</p>
        </div>
      )}
    </div>
  );
}
