"use client";

import { useEffect, useRef, useState } from "react";
import {
  Play,
  Pause,
  Volume2,
  VolumeX,
  Maximize,
  Minimize,
} from "lucide-react";

type IOSVideoElement = HTMLVideoElement & {
  webkitEnterFullscreen?: () => void;
  webkitExitFullscreen?: () => void;
  webkitDisplayingFullscreen?: boolean;
};

type IOSFullscreenElement = HTMLElement & {
  webkitRequestFullscreen?: () => Promise<void> | void;
};

type IOSDocument = Document & {
  webkitFullscreenElement?: Element | null;
  webkitExitFullscreen?: () => Promise<void> | void;
};

export default function VideoSectionPage({
  videoUrl,
}: {
  videoUrl?: string;
}) {
  const currentVideoUrl =
    videoUrl || "https://yemedia.b-cdn.net/v3.mp4";

  const videoRef = useRef<HTMLVideoElement>(null);
  const videoContainerRef = useRef<HTMLDivElement>(null);

  const [isPlaying, setIsPlaying] = useState(true);
  const [isMuted, setIsMuted] = useState(true);
  const [progress, setProgress] = useState(0);
  const [isFullscreen, setIsFullscreen] = useState(false);
  const [isIOSNativeFullscreen, setIsIOSNativeFullscreen] =
    useState(false);

  // Update video progress and synchronize playback state.
  useEffect(() => {
    const video = videoRef.current;

    if (!video) return;

    const updateProgress = () => {
      if (video.duration && Number.isFinite(video.duration)) {
        setProgress(
          (video.currentTime / video.duration) * 100
        );
      }
    };

    const handlePlay = () => setIsPlaying(true);
    const handlePause = () => setIsPlaying(false);

    video.addEventListener("timeupdate", updateProgress);
    video.addEventListener("play", handlePlay);
    video.addEventListener("pause", handlePause);

    return () => {
      video.removeEventListener("timeupdate", updateProgress);
      video.removeEventListener("play", handlePlay);
      video.removeEventListener("pause", handlePause);
    };
  }, []);

  // Synchronize standard and iOS fullscreen changes.
  useEffect(() => {
    const handleFullscreenChange = () => {
      const iosDocument = document as IOSDocument;

      const fullscreen =
        !!document.fullscreenElement ||
        !!iosDocument.webkitFullscreenElement;

      setIsFullscreen(fullscreen);
    };

    const video = videoRef.current as IOSVideoElement | null;

    const handleIOSFullscreenStart = () => {
      setIsIOSNativeFullscreen(true);
      setIsFullscreen(true);
    };

    const handleIOSFullscreenEnd = () => {
      setIsIOSNativeFullscreen(false);
      setIsFullscreen(false);
    };

    document.addEventListener(
      "fullscreenchange",
      handleFullscreenChange
    );

    document.addEventListener(
      "webkitfullscreenchange",
      handleFullscreenChange
    );

    video?.addEventListener(
      "webkitbeginfullscreen",
      handleIOSFullscreenStart
    );

    video?.addEventListener(
      "webkitendfullscreen",
      handleIOSFullscreenEnd
    );

    return () => {
      document.removeEventListener(
        "fullscreenchange",
        handleFullscreenChange
      );

      document.removeEventListener(
        "webkitfullscreenchange",
        handleFullscreenChange
      );

      video?.removeEventListener(
        "webkitbeginfullscreen",
        handleIOSFullscreenStart
      );

      video?.removeEventListener(
        "webkitendfullscreen",
        handleIOSFullscreenEnd
      );
    };
  }, []);

  // Play / Pause
  const togglePlay = async () => {
    const video = videoRef.current;

    if (!video) return;

    try {
      if (video.paused) {
        await video.play();
      } else {
        video.pause();
      }
    } catch (error) {
      console.error("Unable to change video playback:", error);
    }
  };

  // Mute / Unmute
  const toggleMute = () => {
    const video = videoRef.current;

    if (!video) return;

    const nextMutedState = !video.muted;

    video.muted = nextMutedState;
    setIsMuted(nextMutedState);
  };

  // Fullscreen: standard browsers, iOS Safari, and CSS fallback.
  const toggleFullscreen = async () => {
    const container = videoContainerRef.current as
      | IOSFullscreenElement
      | null;

    const video = videoRef.current as IOSVideoElement | null;

    if (!container || !video) return;

    const iosDocument = document as IOSDocument;

    const nativeFullscreen =
      !!document.fullscreenElement ||
      !!iosDocument.webkitFullscreenElement;

    // Exit an existing fullscreen session.
    if (isFullscreen || nativeFullscreen || isIOSNativeFullscreen) {
      try {
        if (document.fullscreenElement) {
          await document.exitFullscreen();
        } else if (iosDocument.webkitFullscreenElement) {
          await iosDocument.webkitExitFullscreen?.();
        } else if (video.webkitDisplayingFullscreen) {
          video.webkitExitFullscreen?.();
        } else {
          // Exit CSS-based fullscreen fallback.
          setIsFullscreen(false);
        }
      } catch (error) {
        console.error("Unable to exit fullscreen:", error);
        setIsFullscreen(false);
      }

      return;
    }

    // 1. Standard fullscreen API.
    if (container.requestFullscreen) {
      try {
        await container.requestFullscreen();
        return;
      } catch {
        // Continue to iOS-specific methods.
      }
    }

    // 2. WebKit fullscreen API for compatible iPads.
    if (container.webkitRequestFullscreen) {
      try {
        await container.webkitRequestFullscreen();
        return;
      } catch {
        // Continue to the native video fullscreen API.
      }
    }

    // 3. Native video fullscreen for iOS Safari.
    // This is supported on many iPhone/iPad Safari versions.
    if (video.webkitEnterFullscreen) {
      try {
        video.webkitEnterFullscreen();
        return;
      } catch {
        // Use CSS fullscreen if native fullscreen fails.
      }
    }

    // 4. Fallback: simulate fullscreen using fixed positioning.
    setIsFullscreen(true);
  };

  // Seek video.
  const handleSeek = (
    e: React.MouseEvent<HTMLDivElement>
  ) => {
    const video = videoRef.current;

    if (
      !video ||
      !video.duration ||
      !Number.isFinite(video.duration)
    ) {
      return;
    }

    const rect = e.currentTarget.getBoundingClientRect();
    const percentage = Math.max(
      0,
      Math.min(1, (e.clientX - rect.left) / rect.width)
    );

    video.currentTime = percentage * video.duration;
  };

  return (
    <section
      ref={videoContainerRef}
      className={`relative w-full h-[550px] md:h-[550px] lg:h-[700px] overflow-hidden bg-black ${
        isFullscreen
          ? "video-is-fullscreen !fixed !inset-0 !z-[9999] !h-[100dvh] !w-screen !max-w-none"
          : ""
      }`}
      style={
        isFullscreen
          ? {
              height: "100vh",
              width: "100vw",
              maxWidth: "none",
              backgroundColor: "#000",
              paddingTop: "env(safe-area-inset-top)",
              paddingBottom: "env(safe-area-inset-bottom)",
            }
          : undefined
      }
    >
      {/* Background */}
      <div
        className="absolute inset-0 bg-[#D9D9D9]"
        style={
          isFullscreen
            ? { display: "none" }
            : {
                width: "1512px",
                height: "700px",
                left: "0px",
                top: "calc(50% - 700px / 2)",
              }
        }
      />

      {/* Video */}
      <div className="absolute inset-0 z-10 flex items-center justify-center bg-black">
        <video
          ref={videoRef}
          key={currentVideoUrl}
          className={`h-full w-full ${
            isFullscreen || isIOSNativeFullscreen
              ? "object-contain"
              : "object-cover"
          }`}
          autoPlay
          muted
          loop
          playsInline
          webkit-playsinline="true"
          preload="metadata"
        >
          <source src={currentVideoUrl} type="video/mp4" />
        </video>
      </div>

      {/* Progress bar */}
      {!isIOSNativeFullscreen && (
        <div
          className={`absolute left-[6%] right-4 z-20 flex w-[88%] items-center gap-4 px-4 ${
            isFullscreen
              ? "bottom-16 top-auto"
              : "top-20 md:top-8"
          }`}
        >
          <div
            onClick={handleSeek}
            className="h-[3px] flex-1 cursor-pointer overflow-hidden rounded-full bg-[#58585a66]"
          >
            <div
              className="h-full rounded-full bg-white transition-all duration-200"
              style={{
                width: `${progress}%`,
                opacity: 0.7,
              }}
            />
          </div>
        </div>
      )}

      {/* Controls */}
      {!isIOSNativeFullscreen && (
        <div
          className={`absolute right-3 z-30 flex items-center justify-center gap-6 ${
            isFullscreen
              ? "right-5 top-5"
              : "top-4 md:bottom-22 md:right-[7%] md:top-auto"
          }`}
          style={{
            paddingTop: isFullscreen
              ? "env(safe-area-inset-top)"
              : undefined,
          }}
        >
          <button
            type="button"
            onClick={togglePlay}
            aria-label={isPlaying ? "Pause video" : "Play video"}
            className="cursor-pointer text-white"
          >
            {isPlaying ? (
              <Pause size={30} fill="white" />
            ) : (
              <Play size={30} fill="white" />
            )}
          </button>

          <button
            type="button"
            onClick={toggleMute}
            aria-label={
              isMuted ? "Turn sound on" : "Turn sound off"
            }
            className="cursor-pointer text-white"
          >
            {isMuted ? (
              <VolumeX size={30} />
            ) : (
              <Volume2 size={30} />
            )}
          </button>

          <button
            type="button"
            onClick={toggleFullscreen}
            aria-label={
              isFullscreen ? "Exit fullscreen" : "Enter fullscreen"
            }
            className="cursor-pointer text-white"
          >
            {isFullscreen ? (
              <Minimize size={30} />
            ) : (
              <Maximize size={30} />
            )}
          </button>
        </div>
      )}
    </section>
  );
}
