import { useEffect, useState, useMemo, useCallback, useRef } from "react";
import { createPortal } from "react-dom";
import { observer } from "mobx-react-lite";
import "../../styles/VideoPreview.css";
import { apiStore } from "../../api/ApiStore/store";
import { apiBaseURL } from "../../api/apiConfig";
import { useGeolocationStore } from "../../stores/hooks/useGeolocationStore";

const defaultVideoPath = new URL(
  "../../assets/video/taganai.mp4",
  import.meta.url,
).href;

const VideoPreviewWidget = observer(() => {
  const { context, isLoading, routeSights, route } = apiStore;
  const { selectedSightId } = useGeolocationStore();
  const [showVideo, setShowVideo] = useState(false);
  const [isExiting, setIsExiting] = useState(false);
  const [videoError, setVideoError] = useState(false);
  const inactivityTimer = useRef(null);
  const videoRef = useRef(null);

  const videoTimer = route?.video_timer
    ? route.video_timer * 1000
    : 60000 * 60 * 7;

  const apiBaseUrl = apiBaseURL;
  const mediaPath = "/media";

  // Используем selectedSightId если есть, иначе nearestSightId
  const nearestSightId = context?.nearestSightId;
  const activeSightId = selectedSightId || nearestSightId;

  const videoToShow = useMemo(() => {
    if (!activeSightId) return null;
    return routeSights?.find((sight) => sight.id === Number(activeSightId))
      ?.video_preview;
  }, [routeSights, activeSightId]);

  const videoSrc = useMemo(() => {
    // Если есть видео из API и не было ошибки - используем его
    if (videoToShow && !videoError) {
      return `${apiBaseUrl}${mediaPath}/${videoToShow}/download`;
    }
    // Иначе используем видео по умолчанию
    return defaultVideoPath;
  }, [videoToShow, videoError, apiBaseUrl, mediaPath]);

  const [currentVideoId, setCurrentVideoId] = useState(null);
  const [currentSightId, setCurrentSightId] = useState(null);
  const [isVideoFinished, setIsVideoFinished] = useState(false);

  const handleHideVideo = useCallback(() => {
    setIsExiting(true);
    setTimeout(() => {
      setShowVideo(false);
      setIsExiting(false);
      setIsVideoFinished(true);
    }, 500);
  }, []);

  const handleVideoEnded = useCallback(() => {
    setIsVideoFinished(true);
    setShowVideo(false);
  }, []);

  const resetInactivityTimer = useCallback(() => {
    if (inactivityTimer.current) {
      clearTimeout(inactivityTimer.current);
    }

    inactivityTimer.current = setTimeout(() => {
      if (!showVideo && activeSightId) {
        // Показываем видео после 10 секунд бездействия
        setShowVideo(true);
        setVideoError(false);
        setIsVideoFinished(false);
      }
    }, videoTimer);
  }, [videoTimer, showVideo, activeSightId]);

  const handleUserActivity = useCallback(() => {
    resetInactivityTimer();
    if (showVideo) {
      handleHideVideo();
    }
  }, [showVideo, resetInactivityTimer, handleHideVideo]);

  // Сброс состояния при изменении достопримечательности или видео
  useEffect(() => {
    if (!activeSightId) return;

    // Проверяем изменение достопримечательности (selectedSightId или nearestSightId)
    if (activeSightId !== currentSightId) {
      setCurrentSightId(activeSightId);
      setCurrentVideoId(videoToShow || null);
      setIsVideoFinished(false);
      setVideoError(false);
      setIsExiting(false);
      // Скрываем видео при смене достопримечательности - оно появится после 10 секунд бездействия
      if (showVideo) {
        setShowVideo(false);
      }
      // Перезапускаем таймер при смене достопримечательности
      resetInactivityTimer();
      return;
    }

    // Проверяем изменение видео для той же достопримечательности
    if (videoToShow !== currentVideoId) {
      setCurrentVideoId(videoToShow || null);
      setIsVideoFinished(false);
      setVideoError(false);
      setIsExiting(false);
      // Видео обновится автоматически через key при следующем показе
    }
  }, [
    activeSightId,
    videoToShow,
    currentSightId,
    currentVideoId,
    showVideo,
    resetInactivityTimer,
  ]);

  useEffect(() => {
    const events = ["mousemove", "keydown", "scroll", "touchstart"];

    events.forEach((event) =>
      window.addEventListener(event, handleUserActivity),
    );
    resetInactivityTimer();

    return () => {
      events.forEach((event) =>
        window.removeEventListener(event, handleUserActivity),
      );
      if (inactivityTimer.current) {
        clearTimeout(inactivityTimer.current);
      }
    };
  }, [handleUserActivity, resetInactivityTimer]);

  return createPortal(
    <div className="video-preview-wrapper">
      {showVideo && activeSightId && (
        <div
          className={`video-container ${
            isExiting ? "video-exit" : "video-enter"
          }`}
          onPointerUp={handleHideVideo}
        >
          <video
            key={`${activeSightId}-${videoSrc}`}
            ref={videoRef}
            className="video-fullscreen"
            src={videoSrc}
            autoPlay
            loop
            muted
            playsInline
            onLoadedData={() => {
              // Принудительно проигрываем видео при загрузке
              if (videoRef.current) {
                videoRef.current.play().catch(() => {
                  // Игнорируем ошибки автоплея
                });
              }
            }}
            onError={(e) => {
              // Если ошибка при загрузке основного видео, переключаемся на fallback
              if (videoToShow && !videoError) {
                setVideoError(true);
              } else if (!videoToShow || videoSrc === defaultVideoPath) {
                // Если даже fallback не загрузился, просто скрываем видео
                setShowVideo(false);
              }
            }}
            onEnded={handleVideoEnded}
          />
        </div>
      )}
    </div>,
    document.body,
  );
});

export default VideoPreviewWidget;
