"use client";

import {
  useEffect,
  useRef,
  useState,
  useCallback,
  MouseEvent as ReactMouseEvent,
} from "react";
import { useAppDispatch, useAppSelector } from "@/store/hooks";
import {
  togglePlay,
  setCurrentTime,
  setDuration,
  setPiP,
  setVolume,
} from "@/store/slices/playerSlice";
import { PiPButton } from "@/components/player/PiPButton";
import { getVideoEl, usePersistentPlayer } from "@/lib/PersistentPlayerContext";
import { useTranslation } from "@/i18n";

/* ── helpers ─────────────────────────────────────────────────────────────── */
function fmtTime(s: number) {
  if (!isFinite(s)) return "0:00";
  const h = Math.floor(s / 3600);
  const m = Math.floor((s % 3600) / 60);
  const sec = Math.floor(s % 60);
  if (h > 0)
    return `${h}:${String(m).padStart(2, "0")}:${String(sec).padStart(2, "0")}`;
  return `${m}:${String(sec).padStart(2, "0")}`;
}

const SPEEDS = [0.5, 0.75, 1, 1.25, 1.5, 1.75, 2];
const HIDE_DELAY = 3000;

/* ── SVG icons ───────────────────────────────────────────────────────────── */
const PlayIcon = () => (
  <svg viewBox="0 0 24 24" fill="currentColor" width="100%" height="100%">
    <path d="M8 5v14l11-7z" />
  </svg>
);
const PauseIcon = () => (
  <svg viewBox="0 0 24 24" fill="currentColor" width="100%" height="100%">
    <path d="M6 19h4V5H6v14zm8-14v14h4V5h-4z" />
  </svg>
);
const Skip10Back = () => (
  <svg viewBox="0 0 24 24" fill="currentColor" width="100%" height="100%">
    <path d="M12 5V1L7 6l5 5V7c3.31 0 6 2.69 6 6s-2.69 6-6 6-6-2.69-6-6H4c0 4.42 3.58 8 8 8s8-3.58 8-8-3.58-8-8-8z" />
    <text x="8.5" y="16" fontSize="5" fill="currentColor" fontFamily="sans-serif" fontWeight="bold">10</text>
  </svg>
);
const Skip10Fwd = () => (
  <svg viewBox="0 0 24 24" fill="currentColor" width="100%" height="100%">
    <path d="M12 5V1l5 5-5 5V7c-3.31 0-6 2.69-6 6s2.69 6 6 6 6-2.69 6-6h2c0 4.42-3.58 8-8 8s-8-3.58-8-8 3.58-8 8-8z" />
    <text x="8.5" y="16" fontSize="5" fill="currentColor" fontFamily="sans-serif" fontWeight="bold">10</text>
  </svg>
);
const VolumeFull = () => (
  <svg viewBox="0 0 24 24" fill="currentColor" width="100%" height="100%">
    <path d="M3 9v6h4l5 5V4L7 9H3zm13.5 3c0-1.77-1.02-3.29-2.5-4.03v8.05c1.48-.73 2.5-2.25 2.5-4.02zM14 3.23v2.06c2.89.86 5 3.54 5 6.71s-2.11 5.85-5 6.71v2.06c4.01-.91 7-4.49 7-8.77s-2.99-7.86-7-8.77z" />
  </svg>
);
const VolumeMute = () => (
  <svg viewBox="0 0 24 24" fill="currentColor" width="100%" height="100%">
    <path d="M16.5 12c0-1.77-1.02-3.29-2.5-4.03v2.21l2.45 2.45c.03-.2.05-.41.05-.63zm2.5 0c0 .94-.2 1.82-.54 2.64l1.51 1.51C20.63 14.91 21 13.5 21 12c0-4.28-2.99-7.86-7-8.77v2.06c2.89.86 5 3.54 5 6.71zM4.27 3L3 4.27 7.73 9H3v6h4l5 5v-6.73l4.25 4.25c-.67.52-1.42.93-2.25 1.18v2.06c1.38-.31 2.63-.95 3.69-1.81L19.73 21 21 19.73l-9-9L4.27 3zM12 4L9.91 6.09 12 8.18V4z" />
  </svg>
);
const VolumeLow = () => (
  <svg viewBox="0 0 24 24" fill="currentColor" width="100%" height="100%">
    <path d="M18.5 12c0-1.77-1.02-3.29-2.5-4.03v8.05c1.48-.73 2.5-2.25 2.5-4.02zM5 9v6h4l5 5V4L9 9H5z" />
  </svg>
);
const FullscreenIcon = () => (
  <svg viewBox="0 0 24 24" fill="currentColor" width="100%" height="100%">
    <path d="M7 14H5v5h5v-2H7v-3zm-2-4h2V7h3V5H5v5zm12 7h-3v2h5v-5h-2v3zM14 5v2h3v3h2V5h-5z" />
  </svg>
);
const ExitFullscreenIcon = () => (
  <svg viewBox="0 0 24 24" fill="currentColor" width="100%" height="100%">
    <path d="M5 16h3v3h2v-5H5v2zm3-8H5v2h5V5H8v3zm6 11h2v-3h3v-2h-5v5zm2-11V5h-2v5h5V8h-3z" />
  </svg>
);

/* ── component ────────────────────────────────────────────────────────────── */
interface Props {
  url: string;
}

export function CustomVideoPlayer({ url }: Props) {
  const dispatch = useAppDispatch();
  const { mountVideo } = usePersistentPlayer();
  const { t } = useTranslation();
  const {
    isPlaying: reduxPlaying,
    volume: reduxVolume,
    currentTime: resumeTime,
    isPiP,
  } = useAppSelector((s) => s.player);

  /* ── Refs ──────────────────────────────────────────────────────────────── */
  const slotRef      = useRef<HTMLDivElement>(null);
  const containerRef = useRef<HTMLDivElement>(null);
  const progressRef  = useRef<HTMLDivElement>(null);
  const videoRef     = useRef<HTMLVideoElement | null>(null);
  const hideTimer    = useRef<ReturnType<typeof setTimeout> | null>(null);
  const didSeekRef   = useRef(false);
  const animKeyRef   = useRef(0);

  // Stable ref so event handlers (defined once) always read the latest Redux value.
  const reduxPlayingRef = useRef(reduxPlaying);
  useEffect(() => { reduxPlayingRef.current = reduxPlaying; }, [reduxPlaying]);

  /* ── Local state ──────────────────────────────────────────────────────── */
  const [playing, setPlaying]           = useState(false);
  const [currentTime, setLocalTime]     = useState(0);
  const [duration, setLocalDuration]    = useState(0);
  const [buffered, setBuffered]         = useState(0);
  const [volume, setLocalVolume]        = useState(reduxVolume);
  const [muted, setMuted]               = useState(false);
  const [buffering, setBuffering]       = useState(false);
  const [controlsVisible, setControls] = useState(true);
  const [isFullscreen, setFullscreen]   = useState(false);
  const [speed, setSpeed]               = useState(1);
  const [showSpeedMenu, setSpeedMenu]   = useState(false);
  const [centerAnim, setCenterAnim]     = useState<"play" | "pause" | null>(null);
  const [animKey, setAnimKey]           = useState(0);
  const [showCenterIcon, setShowCenter] = useState(true);
  const [pipSupported, setPipSupported] = useState(false);
  const [dragging, setDragging]         = useState(false);
  const [seekPreview, setSeekPreview]   = useState<number | null>(null);
  const [seekPreviewX, setSeekPreviewX] = useState(0);

  /* ── Mount: acquire singleton, attach event listeners ─────────────────── */
  useEffect(() => {
    const container = slotRef.current;
    if (!container) return;

    const unmountSlot = mountVideo(container);
    const v = getVideoEl();
    if (!v) return unmountSlot;

    videoRef.current = v;
    v.style.objectFit = "contain";

    // Event handlers defined once — capture stable refs/setters.
    // reduxPlayingRef gives the latest Redux isPlaying without re-registering.
    const onLoadedMetadata = () => {
      setLocalDuration(v.duration);
      dispatch(setDuration(Math.floor(v.duration)));
      v.volume = v.muted ? 0 : v.volume; // keep existing volume
      if (document.pictureInPictureEnabled) setPipSupported(true);
      // Seek to resume position only for fresh sources (didSeekRef reset on src change)
      if (!didSeekRef.current && resumeTime > 1) {
        v.currentTime = resumeTime;
      }
      didSeekRef.current = true;
    };

    const onPlay = () => {
      setPlaying(true);
      setShowCenter(false);
      if (!reduxPlayingRef.current) dispatch(togglePlay());
      // Restart the controls hide timer
      setControls(true);
      if (hideTimer.current) clearTimeout(hideTimer.current);
      hideTimer.current = setTimeout(() => {
        setControls(false);
        setSpeedMenu(false);
      }, HIDE_DELAY);
    };

    const onPause = () => {
      setPlaying(false);
      setShowCenter(true);
      if (reduxPlayingRef.current) dispatch(togglePlay());
      setControls(true);
      if (hideTimer.current) clearTimeout(hideTimer.current);
    };

    const onTimeUpdate = () => {
      setLocalTime(v.currentTime);
      dispatch(setCurrentTime(v.currentTime));
      if (v.buffered.length > 0) {
        setBuffered(v.buffered.end(v.buffered.length - 1) / v.duration);
      }
    };

    const onWaiting = () => setBuffering(true);
    const onPlaying = () => setBuffering(false);
    const onEnded   = () => { setPlaying(false); setShowCenter(true); setControls(true); };

    v.addEventListener("loadedmetadata", onLoadedMetadata);
    v.addEventListener("play",           onPlay);
    v.addEventListener("pause",          onPause);
    v.addEventListener("timeupdate",     onTimeUpdate);
    v.addEventListener("waiting",        onWaiting);
    v.addEventListener("playing",        onPlaying);
    v.addEventListener("ended",          onEnded);

    // If returning from mini player: metadata already loaded — apply UI state now.
    if (v.readyState >= HTMLMediaElement.HAVE_METADATA) {
      setLocalDuration(v.duration);
      dispatch(setDuration(Math.floor(v.duration)));
      if (document.pictureInPictureEnabled) setPipSupported(true);
      setLocalTime(v.currentTime);
      setPlaying(!v.paused);
      setShowCenter(v.paused);
    }

    return () => {
      // Save current timestamp so other consumers can read it
      if (isFinite(v.currentTime) && v.currentTime > 0) {
        dispatch(setCurrentTime(v.currentTime));
      }
      if (document.pictureInPictureElement) document.exitPictureInPicture().catch(() => {});
      dispatch(setPiP(false));

      v.removeEventListener("loadedmetadata", onLoadedMetadata);
      v.removeEventListener("play",           onPlay);
      v.removeEventListener("pause",          onPause);
      v.removeEventListener("timeupdate",     onTimeUpdate);
      v.removeEventListener("waiting",        onWaiting);
      v.removeEventListener("playing",        onPlaying);
      v.removeEventListener("ended",          onEnded);

      unmountSlot(); // moves singleton back to park
    };
    // eslint-disable-next-line react-hooks/exhaustive-deps
  }, []); // intentionally mount-once

  /* ── Set src when URL changes (new video only) ─────────────────────────── */
  useEffect(() => {
    const v = getVideoEl();
    if (!v || !url) return;

    // Compare against the browser-resolved absolute URL that v.src holds.
    // When returning from mini player the singleton already has this source
    // playing at the correct timestamp — setting v.src again would restart from 0.
    let resolvedUrl = url;
    try { resolvedUrl = new URL(url, window.location.href).href; } catch { /* noop */ }
    if (v.src === resolvedUrl || v.src === url) return;

    // Genuinely new source — reset display and load
    didSeekRef.current = false;
    setLocalTime(0);
    setLocalDuration(0);
    setPlaying(false);
    setShowCenter(true);
    v.src = url;
  }, [url]);

  /* ── Sync Redux → video element ────────────────────────────────────────── */
  useEffect(() => {
    const v = videoRef.current;
    if (!v) return;
    if (reduxPlaying && v.paused) v.play().catch(() => {});
    if (!reduxPlaying && !v.paused) v.pause();
  }, [reduxPlaying]);

  useEffect(() => {
    setLocalVolume(reduxVolume);
    const v = videoRef.current;
    if (v) v.volume = reduxVolume / 100;
  }, [reduxVolume]);

  /* ── PiP event listeners ───────────────────────────────────────────────── */
  useEffect(() => {
    if (!pipSupported) return;
    const v = videoRef.current;
    if (!v) return;
    const onEnter = () => dispatch(setPiP(true));
    const onLeave = () => dispatch(setPiP(false));
    v.addEventListener("enterpictureinpicture", onEnter);
    v.addEventListener("leavepictureinpicture", onLeave);
    return () => {
      v.removeEventListener("enterpictureinpicture", onEnter);
      v.removeEventListener("leavepictureinpicture", onLeave);
    };
  }, [pipSupported, dispatch]);

  /* ── Auto-PiP when tab becomes hidden ─────────────────────────────────── */
  useEffect(() => {
    if (!pipSupported) return;
    const onVisibility = async () => {
      const v = videoRef.current;
      if (!v || !playing || document.pictureInPictureElement) return;
      if (document.hidden) {
        try { await v.requestPictureInPicture(); } catch { /* blocked */ }
      }
    };
    document.addEventListener("visibilitychange", onVisibility);
    return () => document.removeEventListener("visibilitychange", onVisibility);
  }, [pipSupported, playing]);

  /* ── Fullscreen change listener ────────────────────────────────────────── */
  useEffect(() => {
    const onFS = () => setFullscreen(!!document.fullscreenElement);
    document.addEventListener("fullscreenchange", onFS);
    return () => document.removeEventListener("fullscreenchange", onFS);
  }, []);

  /* ── Keyboard shortcuts ────────────────────────────────────────────────── */
  useEffect(() => {
    const onKey = (e: KeyboardEvent) => {
      const tag = (e.target as HTMLElement).tagName;
      if (tag === "INPUT" || tag === "TEXTAREA") return;
      const v = videoRef.current;
      if (!v) return;
      switch (e.key) {
        case " ":
        case "k":
          e.preventDefault();
          toggleVideoPlay();
          break;
        case "ArrowRight":
          e.preventDefault();
          v.currentTime = Math.min(v.currentTime + 10, v.duration);
          break;
        case "ArrowLeft":
          e.preventDefault();
          v.currentTime = Math.max(v.currentTime - 10, 0);
          break;
        case "ArrowUp":
          e.preventDefault();
          changeVolume(Math.min(volume + 10, 100));
          break;
        case "ArrowDown":
          e.preventDefault();
          changeVolume(Math.max(volume - 10, 0));
          break;
        case "m":
        case "M":
          e.preventDefault();
          toggleMute();
          break;
        case "f":
        case "F":
          e.preventDefault();
          toggleFullscreen();
          break;
      }
    };
    window.addEventListener("keydown", onKey);
    return () => window.removeEventListener("keydown", onKey);
    // eslint-disable-next-line react-hooks/exhaustive-deps
  }, [volume, playing]);

  /* ── Control helpers ───────────────────────────────────────────────────── */
  const showControls = useCallback(() => {
    setControls(true);
    if (hideTimer.current) clearTimeout(hideTimer.current);
    if (playing) {
      hideTimer.current = setTimeout(() => {
        setControls(false);
        setSpeedMenu(false);
      }, HIDE_DELAY);
    }
  }, [playing]);

  const triggerCenterAnim = useCallback((type: "play" | "pause") => {
    const key = ++animKeyRef.current;
    setAnimKey(key);
    setCenterAnim(type);
    setTimeout(() => setCenterAnim(null), 600);
  }, []);

  const toggleVideoPlay = useCallback(() => {
    const v = videoRef.current;
    if (!v) return;
    if (v.paused) {
      v.play().catch(() => {});
      setShowCenter(false);
      triggerCenterAnim("play");
    } else {
      v.pause();
      setShowCenter(true);
      triggerCenterAnim("pause");
    }
    dispatch(togglePlay());
    showControls();
  }, [dispatch, showControls, triggerCenterAnim]);

  const changeVolume = (val: number) => {
    setLocalVolume(val);
    setMuted(val === 0);
    dispatch(setVolume(val));
    const v = videoRef.current;
    if (v) { v.volume = val / 100; v.muted = val === 0; }
    showControls();
  };

  const toggleMute = () => {
    const v = videoRef.current;
    if (!v) return;
    const next = !muted;
    setMuted(next);
    v.muted = next;
    if (!next && volume === 0) changeVolume(50);
    showControls();
  };

  const toggleFullscreen = async () => {
    if (!containerRef.current) return;
    if (!document.fullscreenElement) await containerRef.current.requestFullscreen();
    else await document.exitFullscreen();
  };

  const handlePiPToggle = async () => {
    const v = videoRef.current;
    if (!v) return;
    try {
      if (!document.pictureInPictureElement) await v.requestPictureInPicture();
      else await document.exitPictureInPicture();
    } catch { /* blocked */ }
  };

  const handleProgressClick = (e: ReactMouseEvent<HTMLDivElement>) => {
    const rect = progressRef.current?.getBoundingClientRect();
    if (!rect || !videoRef.current) return;
    const ratio = Math.max(0, Math.min(1, (e.clientX - rect.left) / rect.width));
    videoRef.current.currentTime = ratio * duration;
    showControls();
  };

  const handleProgressMouseMove = (e: ReactMouseEvent<HTMLDivElement>) => {
    const rect = progressRef.current?.getBoundingClientRect();
    if (!rect) return;
    const ratio = Math.max(0, Math.min(1, (e.clientX - rect.left) / rect.width));
    setSeekPreview(ratio * duration);
    setSeekPreviewX(e.clientX - rect.left);
    if (dragging && videoRef.current) videoRef.current.currentTime = ratio * duration;
  };

  const handleVolumeIcon = () => {
    if (volume === 0 || muted) return <VolumeMute />;
    if (volume < 50) return <VolumeLow />;
    return <VolumeFull />;
  };

  const played = duration > 0 ? currentTime / duration : 0;

  /* ── Render ──────────────────────────────────────────────────────────────── */
  return (
    <div
      ref={containerRef}
      className="relative w-full rounded-xl overflow-hidden select-none"
      style={{ aspectRatio: "16/9", background: "#000" }}
      onMouseMove={showControls}
      onMouseLeave={() => {
        if (playing) { setControls(false); setSpeedMenu(false); }
        setSeekPreview(null);
      }}
      onDoubleClick={toggleFullscreen}
    >
      {/* ── Singleton <video> slot ────────────────────────────────────────── */}
      <div ref={slotRef} className="absolute inset-0" />

      {/* ── Click zone ────────────────────────────────────────────────────── */}
      <div
        className="absolute inset-0 z-10 cursor-pointer"
        style={{ background: "transparent" }}
        onClick={toggleVideoPlay}
      />

      {/* ── Gradient overlays ─────────────────────────────────────────────── */}
      <div
        className="absolute inset-0 z-20 pointer-events-none transition-opacity duration-300"
        style={{
          background:
            "linear-gradient(to top, rgba(0,0,0,0.75) 0%, transparent 30%, transparent 70%, rgba(0,0,0,0.35) 100%)",
          opacity: controlsVisible ? 1 : 0,
        }}
      />

      {/* ── Static pause icon ─────────────────────────────────────────────── */}
      <div
        className="absolute inset-0 z-30 flex items-center justify-center pointer-events-none transition-all duration-300"
        style={{ opacity: showCenterIcon && !playing ? 1 : 0 }}
      >
        <div
          className="flex items-center justify-center rounded-full"
          style={{
            width: 80,
            height: 80,
            background: "rgba(0,0,0,0.55)",
            backdropFilter: "blur(12px)",
            border: "2px solid rgba(255,255,255,0.25)",
            boxShadow: "0 8px 32px rgba(0,0,0,0.5), inset 0 1px 0 rgba(255,255,255,0.1)",
          }}
        >
          <div style={{ width: 32, height: 32, color: "#fff" }}>
            <PlayIcon />
          </div>
        </div>
      </div>

      {/* ── Click flash animation ─────────────────────────────────────────── */}
      {centerAnim && (
        <div
          key={animKey}
          className="absolute inset-0 z-30 flex items-center justify-center pointer-events-none"
          style={{ animation: "cvp-flash 0.6s ease-out forwards" }}
        >
          <div
            className="flex items-center justify-center rounded-full"
            style={{ width: 72, height: 72, background: "rgba(255,255,255,0.15)", backdropFilter: "blur(8px)" }}
          >
            <div style={{ width: 28, height: 28, color: "#fff" }}>
              {centerAnim === "play" ? <PlayIcon /> : <PauseIcon />}
            </div>
          </div>
        </div>
      )}

      {/* ── Buffering spinner ─────────────────────────────────────────────── */}
      {buffering && (
        <div className="absolute inset-0 z-30 flex items-center justify-center pointer-events-none">
          <div
            className="w-11 h-11 rounded-full border-2 animate-spin"
            style={{ borderColor: "rgba(255,255,255,0.2)", borderTopColor: "var(--accent, #e53e3e)" }}
          />
        </div>
      )}

      {/* ── Controls bar ──────────────────────────────────────────────────── */}
      <div
        className="absolute bottom-0 left-0 right-0 z-40 transition-all duration-300"
        style={{
          opacity: controlsVisible ? 1 : 0,
          transform: controlsVisible ? "translateY(0)" : "translateY(8px)",
          pointerEvents: controlsVisible ? "auto" : "none",
          padding: "0 12px 12px",
        }}
        onClick={(e) => e.stopPropagation()}
      >
        {/* Progress bar */}
        <div
          ref={progressRef}
          className="relative w-full cursor-pointer group/prog"
          style={{ height: 20, display: "flex", alignItems: "center" }}
          onClick={handleProgressClick}
          onMouseMove={handleProgressMouseMove}
          onMouseLeave={() => setSeekPreview(null)}
          onMouseDown={() => setDragging(true)}
          onMouseUp={() => setDragging(false)}
        >
          {seekPreview !== null && (
            <div
              className="absolute bottom-6 pointer-events-none"
              style={{
                left: Math.max(24, Math.min(seekPreviewX, (progressRef.current?.offsetWidth ?? 100) - 24)),
                transform: "translateX(-50%)",
                background: "rgba(0,0,0,0.8)",
                backdropFilter: "blur(8px)",
                border: "1px solid rgba(255,255,255,0.12)",
                borderRadius: 6,
                padding: "2px 8px",
                fontSize: 12,
                color: "#fff",
                fontFamily: "monospace",
                whiteSpace: "nowrap",
              }}
            >
              {fmtTime(seekPreview)}
            </div>
          )}

          <div
            className="w-full rounded-full overflow-hidden transition-all duration-150"
            style={{ height: 4, background: "rgba(255,255,255,0.15)" }}
          >
            <div
              className="absolute top-0 left-0 h-full rounded-full"
              style={{ width: `${buffered * 100}%`, background: "rgba(255,255,255,0.25)", transition: "width 0.3s" }}
            />
            <div
              className="absolute top-0 left-0 h-full rounded-full"
              style={{ width: `${played * 100}%`, background: "var(--accent, #e53e3e)", transition: dragging ? "none" : "width 0.1s" }}
            />
          </div>

          <div
            className="absolute rounded-full pointer-events-none transition-all"
            style={{
              left: `${played * 100}%`,
              top: "50%",
              transform: "translate(-50%, -50%)",
              width: 14,
              height: 14,
              background: "#fff",
              boxShadow: "0 0 6px rgba(0,0,0,0.6), 0 0 0 2px var(--accent, #e53e3e)",
              opacity: controlsVisible ? 1 : 0,
              transition: "opacity 0.2s",
            }}
          />
        </div>

        {/* Control buttons row */}
        <div className="flex items-center gap-2 mt-1" style={{ minHeight: 40 }}>
          <CtrlBtn onClick={toggleVideoPlay} title={playing ? t("player_pauseHint") : t("player_playHint")}>
            <div style={{ width: 22, height: 22 }}>{playing ? <PauseIcon /> : <PlayIcon />}</div>
          </CtrlBtn>

          <CtrlBtn
            onClick={() => { if (videoRef.current) videoRef.current.currentTime -= 10; showControls(); }}
            title={t("player_back10s")}
          >
            <div style={{ width: 20, height: 20 }}><Skip10Back /></div>
          </CtrlBtn>

          <CtrlBtn
            onClick={() => { if (videoRef.current) videoRef.current.currentTime += 10; showControls(); }}
            title={t("player_fwd10s")}
          >
            <div style={{ width: 20, height: 20 }}><Skip10Fwd /></div>
          </CtrlBtn>

          <div className="flex items-center gap-1 group/vol" style={{ position: "relative" }}>
            <CtrlBtn onClick={toggleMute} title={muted ? t("player_unmuteHint") : t("player_muteHint")}>
              <div style={{ width: 20, height: 20 }}>{handleVolumeIcon()}</div>
            </CtrlBtn>
            <div className="overflow-hidden transition-all duration-200" style={{ width: 72, opacity: 1 }}>
              <input
                type="range"
                min={0}
                max={100}
                value={muted ? 0 : volume}
                onChange={(e) => changeVolume(Number(e.target.value))}
                className="cvp-volume-slider"
                style={{ width: "100%", cursor: "pointer" }}
              />
            </div>
          </div>

          <span className="ml-1 tabular-nums" style={{ color: "rgba(255,255,255,0.9)", fontSize: 13, fontFamily: "monospace", whiteSpace: "nowrap" }}>
            {fmtTime(currentTime)} / {fmtTime(duration)}
          </span>

          <div className="flex-1" />

          {/* Playback speed */}
          <div className="relative">
            <CtrlBtn
              onClick={() => { setSpeedMenu(!showSpeedMenu); showControls(); }}
              title={t("player_playbackSpeed")}
              style={{ width: "auto", padding: "0 10px", fontSize: 12, fontFamily: "monospace", fontWeight: 600, color: speed !== 1 ? "var(--accent, #e53e3e)" : "#fff" }}
            >
              {speed}×
            </CtrlBtn>
            {showSpeedMenu && (
              <div
                className="absolute bottom-full right-0 mb-2 flex flex-col rounded-xl overflow-hidden"
                style={{ background: "rgba(15,15,15,0.92)", backdropFilter: "blur(20px)", border: "1px solid rgba(255,255,255,0.1)", boxShadow: "0 8px 32px rgba(0,0,0,0.6)", minWidth: 90 }}
              >
                {SPEEDS.map((s) => (
                  <button
                    key={s}
                    className="text-left transition-colors"
                    style={{
                      padding: "8px 16px",
                      fontSize: 13,
                      fontFamily: "monospace",
                      color: speed === s ? "var(--accent, #e53e3e)" : "rgba(255,255,255,0.8)",
                      background: speed === s ? "rgba(var(--accent-rgb,229,62,62),0.12)" : "transparent",
                      cursor: "pointer",
                    }}
                    onClick={() => { setSpeed(s); if (videoRef.current) videoRef.current.playbackRate = s; setSpeedMenu(false); showControls(); }}
                  >
                    {s === 1 ? t("player_normal") : `${s}×`}
                  </button>
                ))}
              </div>
            )}
          </div>

          {/* PiP button */}
          {pipSupported && (
            <PiPButton isActive={isPiP} onClick={handlePiPToggle} />
          )}

          {/* Fullscreen */}
          <CtrlBtn onClick={toggleFullscreen} title={isFullscreen ? t("player_exitFullscreenHint") : t("player_fullscreenHint")}>
            <div style={{ width: 20, height: 20 }}>{isFullscreen ? <ExitFullscreenIcon /> : <FullscreenIcon />}</div>
          </CtrlBtn>
        </div>
      </div>

      {/* CSS injected once */}
      <style>{`
        @keyframes cvp-flash {
          0%   { opacity: 1;   transform: scale(1);   }
          50%  { opacity: 0.6; transform: scale(1.3); }
          100% { opacity: 0;   transform: scale(1.6); }
        }
        .cvp-volume-slider {
          -webkit-appearance: none; appearance: none;
          height: 4px; border-radius: 99px;
          background: rgba(255,255,255,0.2); outline: none;
        }
        .cvp-volume-slider::-webkit-slider-thumb {
          -webkit-appearance: none; appearance: none;
          width: 12px; height: 12px; border-radius: 50%;
          background: #fff; cursor: pointer;
          box-shadow: 0 0 4px rgba(0,0,0,0.5);
          transition: transform 0.15s;
        }
        .cvp-volume-slider:hover::-webkit-slider-thumb { transform: scale(1.3); }
        .cvp-volume-slider::-moz-range-thumb {
          width: 12px; height: 12px; border-radius: 50%;
          background: #fff; border: none; cursor: pointer;
        }
        .group\/prog:hover > div:first-child { height: 6px !important; }
      `}</style>
    </div>
  );
}

/* ── Small icon button ────────────────────────────────────────────────────── */
function CtrlBtn({
  onClick, title, children, style,
}: {
  onClick?: () => void;
  title?: string;
  children: React.ReactNode;
  style?: React.CSSProperties;
}) {
  return (
    <button
      onClick={onClick}
      title={title}
      className="flex items-center justify-center rounded-lg transition-all duration-150 active:scale-90 hover:bg-white/10"
      style={{ width: 36, height: 36, color: "#fff", background: "transparent", border: "none", cursor: "pointer", flexShrink: 0, ...style }}
    >
      {children}
    </button>
  );
}
