"use client";

import dynamic from "next/dynamic";
import { useEffect, useRef, useState } from "react";
import { usePathname, useRouter } from "next/navigation";
import { Maximize2, X, Play, Pause } from "lucide-react";
import { useAppDispatch, useAppSelector } from "@/store/hooks";
import {
  togglePlay,
  stopAll,
  setCurrentTime,
} from "@/store/slices/playerSlice";
import { useSidebar } from "@/lib/SidebarContext";
import { getVideoEl, usePersistentPlayer } from "@/lib/PersistentPlayerContext";
import { useTranslation } from "@/i18n";

// react-player is used only for the YouTube path in the mini player.
// HTML5 videos use the singleton <video> element via PersistentPlayerContext.
// eslint-disable-next-line @typescript-eslint/no-explicit-any
const ReactPlayer = dynamic(() => import("react-player"), { ssr: false }) as any;

function buildYouTubeConfig() {
  return { youtube: { playerVars: { rel: 0, modestbranding: 1, iv_load_policy: 3 } } };
}

export function MiniVideoPlayer() {
  const pathname  = usePathname();
  const router    = useRouter();
  const dispatch  = useAppDispatch();
  const { collapse } = useSidebar();
  const { mountVideo } = usePersistentPlayer();
  const { t } = useTranslation();

  const {
    currentMediaId,
    type,
    isPlaying,
    isPiP,
    title,
    channelName,
    volume,
    currentTime,
    videoUrl,
    videoContentUploadType,
  } = useAppSelector((s) => s.player);

  const [visible, setVisible] = useState(false);
  const [hovered, setHovered] = useState(false);

  // ── HTML5 singleton slot ───────────────────────────────────────────────────
  const slotRef = useRef<HTMLDivElement>(null);

  // ── YouTube seek refs (react-player path only) ────────────────────────────
  // eslint-disable-next-line @typescript-eslint/no-explicit-any
  const playerRef       = useRef<any>(null);
  const seekAttemptedRef = useRef(false);
  const resumeAtRef     = useRef(0);
  const currentTimeRef  = useRef(currentTime);
  useEffect(() => { currentTimeRef.current = currentTime; }, [currentTime]);

  /* ── Visibility ────────────────────────────────────────────────────────── */
  const isOnVideoPage = pathname.startsWith("/video/");
  const isYouTube     = videoContentUploadType === "youtube";

  const shouldShow =
    !isOnVideoPage &&
    !isPiP &&
    type === "video" &&
    !!currentMediaId &&
    !!videoUrl;

  // Animate in with a short delay so the element is rendered before the CSS fires.
  useEffect(() => {
    if (shouldShow) {
      if (!isYouTube) {
        // HTML5: reset YouTube refs (not needed, but keep them clean)
        seekAttemptedRef.current = false;
      } else {
        // YouTube: capture the exact timestamp for seeking
        seekAttemptedRef.current = false;
        resumeAtRef.current = currentTimeRef.current;
      }
      const timerId = setTimeout(() => setVisible(true), 40);
      return () => clearTimeout(timerId);
    } else {
      setVisible(false);
    }
  }, [shouldShow, isYouTube]);

  /* ── HTML5: mount singleton into slot ─────────────────────────────────── */
  useEffect(() => {
    if (!shouldShow || isYouTube) return;

    const container = slotRef.current;
    if (!container) return;

    const v = getVideoEl();
    if (v) {
      v.style.objectFit = "cover"; // mini player looks better with cover
    }

    const unmount = mountVideo(container);

    // Keep Redux currentTime updated while video plays in mini player
    const onTimeUpdate = () => {
      const el = getVideoEl();
      if (el) dispatch(setCurrentTime(el.currentTime));
    };
    v?.addEventListener("timeupdate", onTimeUpdate);

    return () => {
      v?.removeEventListener("timeupdate", onTimeUpdate);
      const el = getVideoEl();
      if (el) el.style.objectFit = "contain"; // restore for full player
      unmount();
    };
  }, [shouldShow, isYouTube, mountVideo, dispatch]);

  /* ── HTML5: sync Redux isPlaying → video element ──────────────────────── */
  useEffect(() => {
    if (!shouldShow || isYouTube) return;
    const v = getVideoEl();
    if (!v) return;
    if (isPlaying && v.paused) v.play().catch(() => {});
    if (!isPlaying && !v.paused) v.pause();
  }, [isPlaying, shouldShow, isYouTube]);

  /* ── Handlers ──────────────────────────────────────────────────────────── */

  const handlePlayPause = (e: React.MouseEvent) => {
    e.stopPropagation();
    if (!isYouTube) {
      // HTML5: control element directly, dispatch to sync Redux
      const v = getVideoEl();
      if (v) {
        if (v.paused) v.play().catch(() => {});
        else v.pause();
      }
    }
    dispatch(togglePlay());
  };

  const handleExpand = (e: React.MouseEvent) => {
    e.stopPropagation();
    collapse();
    router.push(`/video/${currentMediaId}`);
  };

  const handleClose = (e: React.MouseEvent) => {
    e.stopPropagation();
    // Save latest position before stopping
    if (!isYouTube) {
      const v = getVideoEl();
      if (v && isFinite(v.currentTime) && v.currentTime > 0) {
        dispatch(setCurrentTime(v.currentTime));
      }
    }
    dispatch(stopAll());
  };

  // ── YouTube seek helpers ───────────────────────────────────────────────────
  const attemptSeek = () => {
    if (seekAttemptedRef.current) return;
    seekAttemptedRef.current = true;
    const target = resumeAtRef.current;
    if (target < 1 || !playerRef.current) return;
    const internal = playerRef.current.getInternalPlayer?.();
    if (internal instanceof HTMLVideoElement) internal.currentTime = target;
    else playerRef.current.seekTo(target, "seconds");
  };

  const handleYouTubeProgress = (state: { playedSeconds: number }) => {
    if (!seekAttemptedRef.current) { attemptSeek(); return; }
    const target = resumeAtRef.current;
    if (target > 1 && state.playedSeconds < target * 0.9) return;
    dispatch(setCurrentTime(state.playedSeconds));
  };

  /* ── Don't render until there's something to show ──────────────────────── */
  if (!shouldShow) return null;

  return (
    <div
      className="fixed z-50 bottom-[80px] right-3 md:bottom-6 md:right-6"
      style={{
        transition: "transform 0.38s cubic-bezier(0.34,1.56,0.64,1), opacity 0.28s ease",
        transform: visible ? "translateY(0) scale(1)" : "translateY(120%) scale(0.92)",
        opacity: visible ? 1 : 0,
        pointerEvents: visible ? "auto" : "none",
      }}
    >
      <div
        className="relative overflow-hidden cursor-pointer select-none"
        style={{
          width: "min(320px, calc(100vw - 24px))",
          height: "auto",
          aspectRatio: "16/9",
          borderRadius: "12px",
          background: "#0a0a0a",
          boxShadow:
            "0 24px 64px rgba(0,0,0,0.72), 0 4px 16px rgba(0,0,0,0.5), 0 0 0 1px rgba(255,255,255,0.06)",
        }}
        onMouseEnter={() => setHovered(true)}
        onMouseLeave={() => setHovered(false)}
        onClick={handleExpand}
      >
        {/* ── Video area ──────────────────────────────────────────────────── */}
        <div className="absolute inset-0">
          {isYouTube ? (
            /* YouTube: new ReactPlayer instance with seek on ready */
            <ReactPlayer
              ref={playerRef}
              src={videoUrl}
              playing={isPlaying}
              volume={volume / 100}
              width="100%"
              height="100%"
              onReady={attemptSeek}
              onStart={attemptSeek}
              onProgress={handleYouTubeProgress}
              config={buildYouTubeConfig()}
              style={{ position: "absolute", inset: 0 }}
            />
          ) : (
            /* HTML5: singleton <video> moved into this slot — no restart, no seek */
            <div ref={slotRef} className="absolute inset-0" />
          )}
        </div>

        {/* ── Top controls (always visible) ───────────────────────────────── */}
        <div
          className="absolute top-0 left-0 right-0 flex justify-end gap-1 p-2 z-10"
          style={{ background: "linear-gradient(to bottom, rgba(0,0,0,0.7) 0%, transparent 100%)" }}
        >
          <button
            onClick={handleExpand}
            className="w-7 h-7 rounded-full flex items-center justify-center transition-all hover:scale-110 active:scale-95"
            style={{ background: "rgba(255,255,255,0.15)", backdropFilter: "blur(6px)" }}
            aria-label={t("player_openFullPlayer")}
          >
            <Maximize2 size={13} color="#fff" strokeWidth={2} />
          </button>
          <button
            onClick={handleClose}
            className="w-7 h-7 rounded-full flex items-center justify-center transition-all hover:scale-110 active:scale-95"
            style={{ background: "rgba(255,255,255,0.15)", backdropFilter: "blur(6px)" }}
            aria-label={t("player_closeMiniPlayer")}
          >
            <X size={13} color="#fff" strokeWidth={2} />
          </button>
        </div>

        {/* ── Center play/pause on hover ──────────────────────────────────── */}
        <div
          className="absolute inset-0 flex items-center justify-center pointer-events-none z-10"
          style={{ transition: "opacity 0.2s ease", opacity: hovered ? 1 : 0 }}
        >
          <button
            onClick={handlePlayPause}
            className="w-11 h-11 rounded-full flex items-center justify-center pointer-events-auto transition-all hover:scale-110 active:scale-95"
            style={{ background: "rgba(0,0,0,0.6)", backdropFilter: "blur(8px)", border: "1px solid rgba(255,255,255,0.2)" }}
            aria-label={isPlaying ? t("player_pause") : t("player_play")}
          >
            {isPlaying ? (
              <Pause size={18} fill="white" strokeWidth={0} />
            ) : (
              <Play size={18} fill="white" strokeWidth={0} className="ml-0.5" />
            )}
          </button>
        </div>

        {/* ── Bottom info bar ─────────────────────────────────────────────── */}
        <div
          className="absolute bottom-0 left-0 right-0 px-3 py-2 z-10"
          style={{ background: "linear-gradient(to top, rgba(0,0,0,0.85) 0%, transparent 100%)" }}
        >
          <p className="text-[#ffffff] text-xs font-semibold leading-tight truncate">{title}</p>
          <p className="text-[10px] mt-0.5 truncate" style={{ color: "rgba(255,255,255,0.55)" }}>
            {channelName}
          </p>
        </div>
      </div>
    </div>
  );
}
