import {
  useSavedWatchedHistory,
  useViewCountEpisodes,
  useViewCountVideos,
} from "@/state/series/series.action";
import { useSession } from "next-auth/react";
import Image from "next/image";
import React, {
  forwardRef,
  useEffect,
  useImperativeHandle,
  useRef,
  useState,
} from "react";
import ReactPlayer from "react-player";
import AddModal from "./add-modal";
import { Placement } from "./video-detail-type";

export interface PlayerMediaRef {
  triggerSave: () => void;
}

export interface PlayerMediaProps {
  videoUrl?: string | undefined;
  mediaKey?: string;
  lastWatchedTime: number | null | undefined;
  contentId?: string;
  seriesId?: string;
  onDurationUpdate: (contentId: string, duration: number) => void;
  onEnded?: () => void;
  thumbnailUrl?: string;
  placements?: Placement[];
}

const PlayerSkeleton = () => (
  <div className="w-full h-full bg-gray-800 animate-pulse" />
);

const PlayerMediaComponent = forwardRef<PlayerMediaRef, PlayerMediaProps>(
  (
    {
      videoUrl,
      mediaKey,
      lastWatchedTime,
      contentId,
      seriesId,
      onDurationUpdate,
      onEnded,
      thumbnailUrl,
      placements,
    },
    ref,
  ) => {
    const playerRef = useRef<ReactPlayer>(null);
    const currentTimeRef = useRef(0);
    const { mutate: saveHistory } = useSavedWatchedHistory();
    const { mutate: viewCountGetEpisodes } = useViewCountEpisodes(contentId);
    const { mutate: viewCountGetVideos } = useViewCountVideos(contentId);

    // const [internalKey, setInternalKey] = useState(mediaKey);
    const { data: session } = useSession();

    const [openModal, setOpenModal] = useState(false);
    const [activePlacements, setActivePlacements] = useState<Placement[]>([]);

    const getActivePlacements = (playedSeconds: number) => {
      if (!placements?.length) {
        return [];
      }

      return placements.filter((placement) => {
        const startWindow = Math.max(
          0,
          placement.placement_timestamp - placement.duration_seconds,
        );
        const endWindow =
          placement.placement_timestamp + placement.duration_seconds;

        return playedSeconds >= startWindow && playedSeconds <= endWindow;
      });
    };

    // useEffect(() => {
    //   setInternalKey(`${mediaKey || "player"}-${videoUrl}-${Date.now()}`);
    // }, [mediaKey, videoUrl]);
    const saveCurrentWatchHistory = () => {
      const currentTimeInSeconds = currentTimeRef.current;
      if (!contentId || currentTimeInSeconds <= 0) {
        return;
      }

      let dataParams = {};
      if (seriesId) {
        dataParams = {
          seriesId,
          episodeId: contentId,
          timeStamp: currentTimeInSeconds,
        };
      } else {
        dataParams = {
          videoId: contentId,
          timeStamp: currentTimeInSeconds,
        };
      }
      if (session?.user?.id) {
        saveHistory(dataParams, {
          onSuccess: () => {
            onDurationUpdate(contentId, currentTimeInSeconds);
          },
        });
      }
    };

    useImperativeHandle(ref, () => ({
      triggerSave: () => {
        saveCurrentWatchHistory();
      },
    }));

    useEffect(() => {
      if (!videoUrl) return;

      const interval = setInterval(() => {
        saveCurrentWatchHistory();
      }, 5000);

      return () => {
        clearInterval(interval);
        if (playerRef.current) {
          const internalPlayer = playerRef.current.getInternalPlayer();
          if (internalPlayer && typeof internalPlayer.destroy === "function") {
            internalPlayer.destroy();
          }
        }
      };
    }, [videoUrl, saveCurrentWatchHistory]);

    const handleProgress = (progress: { playedSeconds: number }) => {
      if (progress && typeof progress.playedSeconds === "number") {
        currentTimeRef.current = Math.round(progress.playedSeconds);
      }
    };

    const handleReady = () => {
      if (playerRef.current) {
        currentTimeRef.current = 0;
        const startTime =
          typeof lastWatchedTime === "number" && lastWatchedTime > 0
            ? lastWatchedTime
            : 0;
        playerRef.current.seekTo(startTime, "seconds");
      }
    };
    const handleOnPlay = () => {
      setOpenModal(false);
      setActivePlacements([]);

      if (seriesId && session?.user?.id) {
        viewCountGetEpisodes({});
      } else if (contentId && session?.user?.id) {
        viewCountGetVideos({});
      }
    };
    const handelStop = () => {
      const matchedPlacements = getActivePlacements(currentTimeRef.current);

      setActivePlacements(matchedPlacements);
      setOpenModal(matchedPlacements.length > 0);
    };
    const LockedPlayerDisplay = () => (
      <>
        {thumbnailUrl ? (
          <Image
            src={thumbnailUrl}
            alt="Content thumbnail"
            layout="fill"
            objectFit="cover"
            className="opacity-30"
          />
        ) : (
          <PlayerSkeleton />
        )}
      </>
    );

    return (
      <div className="relative w-[300px] sm:w-[400px] md:w-[400px] lg:w-[500px] aspect-[9/16] h-[calc(100vh-100px)] overflow-hidden shadow-lg bg-black">
        {videoUrl ? (
          <ReactPlayer
            key={mediaKey}
            url={videoUrl}
            ref={playerRef}
            className="react-player"
            playing={!!videoUrl}
            controls={true}
            loop={true}
            muted={false}
            width="100%"
            onEnded={onEnded}
            pip={false}
            onPlay={handleOnPlay}
            onPause={handelStop}
            height="100%"
            style={{ width: "100%", height: "100%", objectFit: "cover" }}
            onProgress={handleProgress}
            onReady={handleReady}
            config={{
              file: {
                forceHLS: true,
                attributes: {
                  disablePictureInPicture: true,
                },
              },
            }}
          />
        ) : (
          // <PlayerSkeleton />
          <LockedPlayerDisplay />
        )}
        <AddModal
          open={openModal && activePlacements.length > 0}
          onOpenChange={setOpenModal}
          placements={activePlacements}
        />
      </div>
    );
  },
);

PlayerMediaComponent.displayName = "PlayerMediaComponent";

const PlayerMedia = React.memo(PlayerMediaComponent);

export default PlayerMedia;
