"use client";

import { Button } from "@/components/ui/button";
import EpisodesDetails from "@/components/video-player/episodes-details";
import PlayerMedia, { PlayerMediaRef } from "@/components/video-player/player";
import { UnlockEpisodeModal } from "@/components/video-player/subscribe-unloack-modal";
import UnlockModal from "@/components/video-player/UnlockModal";
import { Episode } from "@/components/video-player/video-detail-type";
import {
  useAutoUnlockEpisode,
  useGetCheckWalletBalance,
  useUnlockEpisode,
} from "@/state/profile/profile.action";
import {
  useEpisodeLike,
  useGetEpisodeList,
  useGetVideoDetails,
  useRemoveSavedEpisode,
  useRemoveSeriesLike,
  useSavedEpisode,
} from "@/state/series/series.action";
import { useSettingsStore } from "@/state/store/settings.store";
import { ArrowLeft, ChevronDown, ChevronUp } from "lucide-react";
import { useSession } from "next-auth/react";
import { useRouter, useSearchParams } from "next/navigation";
import { useCallback, useEffect, useRef, useState } from "react";

export default function VideoPlayer({
  seriesId,
  videoId,
}: {
  seriesId?: string;
  videoId?: string;
}) {
  const searchParams = useSearchParams();
  const playerMediaRef = useRef<PlayerMediaRef>(null);
  const { data: session } = useSession();
  const setIsSocialOpen = useSettingsStore((state) => state.setIsSocialOpen);
  const episodeIdFromUrl = searchParams?.get("episode");
  const router = useRouter();
  const [selectedContent, setSelectedContent] = useState<Episode>();
  const [currentEpisodeIndex, setCurrentEpisodeIndex] = useState(0);
  const [postUnlockEpisodeId, setPostUnlockEpisodeId] = useState<string | null>(
    null,
  );
  const [isUnlockModalOpen, setIsUnlockModalOpen] = useState(false);
  const [unlockModalMode, setUnlockModalMode] = useState<
    "early_access" | "not_released" | null
  >(null);
  const [episodeList, setEpisodeList] = useState<Episode[]>([]);
  const { data: fetchedEpisodeList = [], refetch: refetchEpisodes } =
    useGetEpisodeList({ series_id: seriesId });
  const { data: videoDetails, refetch: refetchVideo } =
    useGetVideoDetails(videoId);
  const { data: balanceWallet } = useGetCheckWalletBalance(!!session?.user?.id);
  const { mutate: unlockEpisode } = useUnlockEpisode();
  const { mutate: autoUnlockEpisode } = useAutoUnlockEpisode();
  const { mutate: saveLikedEpisode, isPending: isLiking } = useEpisodeLike();
  const { mutate: removeLikedEpisode, isPending: isUnliking } =
    useRemoveSeriesLike();
  const { mutate: saveEpisode, isPending: isSaving } = useSavedEpisode();
  const { mutate: removeSavedEpisode, isPending: isUnsaving } =
    useRemoveSavedEpisode();

  useEffect(() => {
    if (fetchedEpisodeList.length > 0) {
      setEpisodeList(fetchedEpisodeList);
    }
  }, [fetchedEpisodeList]);

  useEffect(() => {
    const ref = playerMediaRef.current;

    return () => {
      if (ref) {
        ref.triggerSave();
      }
    };
  }, []);

  useEffect(() => {
    if (postUnlockEpisodeId && episodeList.length > 0) {
      const reselectEpisode = episodeList.find(
        (ep) => ep.episode_id === postUnlockEpisodeId,
      );
      if (reselectEpisode) {
        const newIndex = episodeList.findIndex(
          (ep) => ep.episode_id === postUnlockEpisodeId,
        );
        setSelectedContent(reselectEpisode);
        if (newIndex !== -1) setCurrentEpisodeIndex(newIndex);
        setPostUnlockEpisodeId(null);
        return;
      }
    }

    if (seriesId && episodeList.length > 0 && !selectedContent) {
      let initialIndex = 0;
      let initialEpisode =
        episodeList.find((ep) => ep.episode_number === 1) || episodeList[0];
      if (episodeIdFromUrl) {
        const foundIndex = episodeList.findIndex(
          (ep) => ep.episode_id === episodeIdFromUrl,
        );
        if (foundIndex !== -1) {
          initialIndex = foundIndex;
          initialEpisode = episodeList[foundIndex];
        }
      }
      setSelectedContent(initialEpisode);
      setCurrentEpisodeIndex(initialIndex);
    } else if (videoId && videoDetails && !selectedContent) {
      setSelectedContent(videoDetails);
    }
  }, [
    seriesId,
    videoId,
    episodeList,
    videoDetails,
    episodeIdFromUrl,
    postUnlockEpisodeId,
    selectedContent,
  ]);

  useEffect(() => {
    if (selectedContent) {
      if (selectedContent.episode_id && episodeList.length > 0) {
        const freshContent = episodeList.find(
          (ep) => ep.episode_id === selectedContent.episode_id,
        );
        if (freshContent && freshContent !== selectedContent) {
          setSelectedContent(freshContent);
        }
      }
    }
  }, [episodeList, selectedContent]);

  const handleUpdateEpisodeData = (
    episodeId: string,
    updatedData: Partial<Episode>,
  ) => {
    setEpisodeList((prevList) =>
      prevList?.map((ep) =>
        ep.episode_id === episodeId ? { ...ep, ...updatedData } : ep,
      ),
    );
  };

  const handlePremiumUnlock = useCallback(
    (content: Episode) => {
      const coinPrice = Number(content.coin_price || 0);
      const purchasedCoins = Number(balanceWallet?.purchased_coins || 0);
      const freeCoins = Number(balanceWallet?.free_coins || 0);
      const totalUsableCoins = content.can_use_free_coin
        ? purchasedCoins + freeCoins
        : purchasedCoins;

      const refetchAction = () => {
        if (seriesId) refetchEpisodes();
        else refetchVideo();
      };

      const handleSuccess = () => {
        setPostUnlockEpisodeId(content.episode_id || content.video_id || null);
        refetchAction();
      };

      const contentId = content.episode_id || content.video_id;
      if (!contentId) return;

      if (content.is_auto_unlockable && totalUsableCoins >= coinPrice) {
        unlockEpisode(
          {
            contentId,
            contentType: content.series ? "episode" : "video",
            isEarlyAccess: false,
          },
          { onSuccess: handleSuccess },
        );
        return;
      }

      if (
        totalUsableCoins >= coinPrice &&
        content.series?.series_id &&
        content.is_auto_unlockable == null
      ) {
        autoUnlockEpisode(
          { seriesId: content.series.series_id, priority: 1 },
          {
            onSuccess: () => {
              unlockEpisode(
                {
                  contentId,
                  contentType: content.series ? "episode" : "video",
                  isEarlyAccess: false,
                },
                { onSuccess: handleSuccess },
              );
            },
          },
        );
        return;
      }
      setIsUnlockModalOpen(true);
    },
    [
      balanceWallet,
      unlockEpisode,
      autoUnlockEpisode,
      seriesId,
      refetchEpisodes,
      refetchVideo,
    ],
  );

  useEffect(() => {
    setIsUnlockModalOpen(false);
    setUnlockModalMode(null);
    if (!selectedContent?.is_locked) return;

    if (!session) {
      setIsSocialOpen(true);
      return;
    }
    const initialStatus = selectedContent.series
      ? selectedContent.series.initial_status
      : selectedContent.initial_status;
    if (selectedContent.early_access_datetime) {
      setUnlockModalMode("early_access");
    } else if (initialStatus === "Published") {
      handlePremiumUnlock(selectedContent);
    } else if (initialStatus !== "Published") {
      setUnlockModalMode("not_released");
    }
  }, [selectedContent, handlePremiumUnlock, session, setIsSocialOpen]);

  const handleSelectEpisode = (episode: Episode) => {
    if (episode.is_locked && !session) {
      setIsSocialOpen(true);
      return;
    }
    const newIndex = episodeList.findIndex(
      (e) => e.episode_id === episode.episode_id,
    );
    if (newIndex !== -1) setCurrentEpisodeIndex(newIndex);
    setSelectedContent(episode);
  };

  const handleLikeToggle = (id: string, currentLikeStatus: boolean) => {
    if (!session) return setIsSocialOpen(true);

    const originalEpisode = episodeList.find((ep) => ep.episode_id === id);
    const originalVideoDetails =
      videoDetails?.video_id === id ? videoDetails : null;

    if (seriesId && originalEpisode) {
      const newLikesCount = currentLikeStatus
        ? (originalEpisode.likeCount || 1) - 1
        : (originalEpisode.likeCount || 0) + 1;
      handleUpdateEpisodeData(id, {
        is_liked: !currentLikeStatus,
        likeCount: newLikesCount,
      });
    } else if (!seriesId) {
      setSelectedContent((prev) => {
        if (!prev) return undefined;
        const newLikesCount = currentLikeStatus
          ? (prev.likeCount || 1) - 1
          : (prev.likeCount || 0) + 1;
        return {
          ...prev,
          is_liked: !currentLikeStatus,
          likeCount: newLikesCount,
        };
      });
    }

    const mutation = currentLikeStatus ? removeLikedEpisode : saveLikedEpisode;
    mutation(
      { id, type: seriesId ? "episode" : "video" },
      {
        onError: () => {
          if (seriesId && originalEpisode) {
            handleUpdateEpisodeData(id, {
              is_liked: originalEpisode.is_liked,
              likeCount: originalEpisode.likeCount,
            });
          } else if (originalVideoDetails) {
            setSelectedContent(originalVideoDetails);
          }
        },
      },
    );
  };

  const handleSaveToggle = (id: string, currentSaveStatus: boolean) => {
    if (!session) return setIsSocialOpen(true);

    const originalEpisode = episodeList.find((ep) => ep.episode_id === id);
    const originalVideoDetails =
      videoDetails?.video_id === id ? videoDetails : null;

    if (seriesId && originalEpisode) {
      const newSavesCount = currentSaveStatus
        ? (originalEpisode.saveCount || 1) - 1
        : (originalEpisode.saveCount || 0) + 1;
      handleUpdateEpisodeData(id, {
        is_saved: !currentSaveStatus,
        saveCount: newSavesCount,
      });
    } else if (!seriesId) {
      setSelectedContent((prev) => {
        if (!prev) return undefined;
        const newSavesCount = currentSaveStatus
          ? (prev.saveCount || 1) - 1
          : (prev.saveCount || 0) + 1;
        return {
          ...prev,
          is_saved: !currentSaveStatus,
          saveCount: newSavesCount,
        };
      });
    }

    const mutation = currentSaveStatus ? removeSavedEpisode : saveEpisode;
    mutation(
      { id, type: seriesId ? "episode" : "video" },
      {
        onError: () => {
          if (seriesId && originalEpisode) {
            handleUpdateEpisodeData(id, {
              is_saved: originalEpisode.is_saved,
              saveCount: originalEpisode.saveCount,
            });
          } else if (originalVideoDetails) {
            setSelectedContent(originalVideoDetails);
          }
        },
      },
    );
  };

  const handlePreviousEpisode = () => {
    playerMediaRef.current?.triggerSave();
    if (currentEpisodeIndex > 0) {
      const newIndex = currentEpisodeIndex - 1;
      handleSelectEpisode(episodeList[newIndex]);
    }
  };

  const handleNextEpisode = () => {
    playerMediaRef.current?.triggerSave();
    if (currentEpisodeIndex < episodeList.length - 1) {
      const newIndex = currentEpisodeIndex + 1;
      handleSelectEpisode(episodeList[newIndex]);
    }
  };

  const onUnLockEpisodes = (isEarlyAccess: boolean) => {
    if (!selectedContent) return;
    const contentId = selectedContent.episode_id || selectedContent.video_id;
    if (!contentId) return;
    unlockEpisode(
      {
        contentId,
        contentType: selectedContent.series ? "episode" : "video",
        isEarlyAccess,
      },
      {
        onSuccess: async () => {
          const refetchFn = seriesId ? refetchEpisodes : refetchVideo;
          const { data: freshData } = await refetchFn();
          const newContent = Array.isArray(freshData)
            ? freshData.find(
                (ep) =>
                  ep.episode_id === contentId || ep.video_id === contentId,
              )
            : freshData;
          if (newContent) {
            setSelectedContent(newContent);
            if (seriesId) {
              handleUpdateEpisodeData(contentId, {
                ...newContent,
                is_locked: false,
              });
            }
          }
          setUnlockModalMode(null);
          if (isUnlockModalOpen) setIsUnlockModalOpen(false);
        },
      },
    );
  };

  const handleDurationUpdate = (contentId: string, duration: number) => {
    if (seriesId) {
      handleUpdateEpisodeData(contentId, { watch_duration: duration });
    } else if (videoId === contentId) {
      setSelectedContent((prev) => {
        if (!prev) return undefined;
        return { ...prev, watch_duration: duration };
      });
    }
  };

  const handleEpisodeEnd = () => {
    if (!seriesId || episodeList.length === 0) {
      return;
    }
    playerMediaRef.current?.triggerSave();
    const isLastEpisode = currentEpisodeIndex >= episodeList.length - 1;

    if (isLastEpisode) {
      const firstEpisode = episodeList[0];
      if (firstEpisode) {
        handleSelectEpisode(firstEpisode);
      }
    } else {
      const nextIndex = currentEpisodeIndex + 1;
      const nextEpisode = episodeList[nextIndex];
      if (nextEpisode) {
        handleSelectEpisode(nextEpisode);
      }
    }
  };

  const isPreviousDisabled = currentEpisodeIndex === 0;
  const isNextDisabled = currentEpisodeIndex >= episodeList.length - 1;
  const handelBack = () => {
    router.back();
  };
  return (
    <>
      <div className="container mx-auto text-white">
        <div className="md:flex">
          <div className="flex-1 flex flex-col">
            <div className="flex justify-center relative">
              <div className="absolute top-3 right-3 md:right-auto md:left-2 z-10">
                <Button
                  className="cursor-pointer bg-gradient-to-r from-[#ED3A57] via-[#ED3A57] to-[#FD521E] "
                  onClick={handelBack}
                >
                  <ArrowLeft />
                </Button>
              </div>
              <PlayerMedia
                ref={playerMediaRef}
                videoUrl={
                  !selectedContent?.is_locked
                    ? selectedContent?.video || selectedContent?.video_file
                    : undefined
                }
                thumbnailUrl={
                  selectedContent?.thumbnail_high_9x16 ??
                  selectedContent?.thumbnail
                }
                mediaKey={
                  selectedContent?.episode_id || selectedContent?.video_id
                }
                lastWatchedTime={selectedContent?.watch_duration || 0}
                contentId={
                  selectedContent?.episode_id || selectedContent?.video_id
                }
                key={selectedContent?.episode_id || selectedContent?.video_id}
                seriesId={selectedContent?.series?.series_id}
                onDurationUpdate={handleDurationUpdate}
                onEnded={handleEpisodeEnd}
                placements={selectedContent?.placements}
              />
              {seriesId && (
                <div className="flex items-end justify-end flex-col ml-5">
                  <button
                    onClick={handlePreviousEpisode}
                    disabled={isPreviousDisabled}
                    className="cursor-pointer disabled:opacity-50 disabled:cursor-not-allowed"
                  >
                    <div className=" bg-[#ed3a57] w-10 h-10 flex align-middle justify-center items-center rounded-full">
                      <ChevronUp />
                    </div>
                  </button>
                  <button
                    onClick={handleNextEpisode}
                    disabled={isNextDisabled}
                    className="cursor-pointer disabled:opacity-50 disabled:cursor-not-allowed mt-2"
                  >
                    <div className=" bg-[#ed3a57] w-10 h-10 flex align-middle justify-center items-center rounded-full">
                      <ChevronDown />
                    </div>
                  </button>
                </div>
              )}
            </div>
          </div>
          <div className="w-96 bg-[#252525]">
            <EpisodesDetails
              selectedContent={selectedContent}
              episodeList={episodeList}
              onSelectEpisode={handleSelectEpisode}
              onLikeToggle={handleLikeToggle}
              onSaveToggle={handleSaveToggle}
              isLiking={isLiking || isUnliking}
              isSaving={isSaving || isUnsaving}
              seriesId={seriesId}
            />
          </div>
        </div>
      </div>

      <UnlockModal
        isOpen={isUnlockModalOpen}
        onClose={() => setIsUnlockModalOpen(false)}
        content={selectedContent}
        onWatchAd={() => console.log("Watching Ad...")}
        onBecomeVip={() => router.push("/profile")}
        onUnLockEpisodes={() => onUnLockEpisodes(false)}
      />
      <UnlockEpisodeModal
        isOpen={unlockModalMode !== null}
        onClose={() => setUnlockModalMode(null)}
        content={selectedContent}
        mode={unlockModalMode}
        onClick={() => onUnLockEpisodes(true)}
      />
    </>
  );
}
