import Link from "next/link";
import React, { useState, useRef, useEffect, Fragment } from "react";
import { useDraggable } from "react-use-draggable-scroll";
import Image from "next/image";
import { MdChevronRight } from "react-icons/md";
import {
  ChevronRightIcon,
  ArrowRightCircleIcon,
} from "@heroicons/react/24/outline";

import { ChevronLeftIcon } from "@heroicons/react/20/solid";
import { ExclamationCircleIcon, PlayIcon } from "@heroicons/react/24/solid";
import { useRouter } from "next/router";
import HistoryOptions from "./content/historyOptions";
import { toast } from "sonner";
import { truncateImgUrl } from "@/utils/imageUtils";

type ContentProps = {
  ids: string;
  section: string;
  data?: any;
  userData?: UserDataTypes[];
  og?: any;
  userName?: string;
  setRemoved?: any;
  type?: string;
};

type UserDataTypes = {
  id: string;
  aniId?: string;
  title?: string;
  aniTitle?: string;
  image?: string;
  episode?: number;
  timeWatched?: number;
  duration?: number;
  provider?: string;
  nextId?: string;
  nextNumber?: number;
  dub?: boolean;
  createdDate: string;
  userProfileId: string;
  watchId: string;
};

interface SlicedDataTypes {
  id: string | number;
  slug?: string;
  nextAiringEpisode?: any;
  currentEpisode?: number;
  idMal: number;
  status: string;
  title: Title;
  bannerImage: string;
  coverImage: CoverImage | string;
  image?: string;
  episodeNumber?: number;
  description: string;
}

interface Title {
  romaji: string;
  english: string;
  native: string;
}

interface CoverImage {
  extraLarge: string;
  large: string;
  medium: string;
  color?: string;
}

export default function Content({
  ids,
  section,
  data,
  userData,
  og,
  userName,
  setRemoved,
  type = "anime",
}: ContentProps) {
  const ref = useRef<HTMLElement>(null!);
  const { events } = useDraggable(ref);

  const router = useRouter();

  const [clicked, setClicked] = useState(false);

  useEffect(() => {
    const click = localStorage.getItem("clicked");

    if (click) {
      setClicked(JSON.parse(click));
    }
    // eslint-disable-next-line react-hooks/exhaustive-deps
  }, []);

  const [scrollLeft, setScrollLeft] = useState(false);
  const [scrollRight, setScrollRight] = useState(true);

  const slideLeft = () => {
    if (ref.current) {
      ref.current.classList.add("scroll-smooth");
      var slider = document.getElementById(ids);
      if (slider?.scrollLeft) {
        slider.scrollLeft = slider.scrollLeft - 500;
      }
      ref.current.classList.remove("scroll-smooth");
    }
  };
  const slideRight = () => {
    if (ref.current) {
      ref.current.classList.add("scroll-smooth");
      var slider = document.getElementById(ids);
      if (slider?.scrollLeft) {
        slider.scrollLeft = slider.scrollLeft + 500;
      }
      ref.current.classList.remove("scroll-smooth");
    }
  };

  const handleScroll = (e: any) => {
    const scrollLeft = e.target.scrollLeft > 31;
    const scrollRight =
      e.target.scrollLeft < e.target.scrollWidth - e.target.clientWidth;
    setScrollLeft(scrollLeft);
    setScrollRight(scrollRight);
  };

  function handleAlert(e: string) {
    if (localStorage.getItem("clicked")) {
      const existingDataString = localStorage.getItem("clicked");
      const existingData = existingDataString
        ? JSON.parse(existingDataString)
        : {};

      existingData[e] = true;

      const updatedDataString = JSON.stringify(existingData);

      localStorage.setItem("clicked", updatedDataString);
    } else {
      const newData = {
        [e]: true,
      };

      const newDataString = JSON.stringify(newData);

      localStorage.setItem("clicked", newDataString);
    }
  }

  const array = data;
  let filteredData = array?.filter((item: any) => item !== null);
  const slicedData: SlicedDataTypes[] =
    filteredData?.length > 15 ? filteredData?.slice(0, 15) : filteredData;

  const goToPage = () => {
    if (section === "Recently Watched") {
      router.push(`/en/anime/recently-watched`);
    }
    if (section === "New Episodes") {
      router.push(`/en/anime/recent`);
    }
    if (section === "Trending Now") {
      router.push(`/en/anime/trending`);
    }
    if (section === "Popular Anime") {
      router.push(`/en/anime/popular`);
    }
    if (section === "Your Plan") {
      router.push(`/en/profile/${userName}/#planning`);
    }
    if (section === "On-Going Anime" || section === "Your Watch List") {
      router.push(`/en/profile/${userName}/#current`);
    }
  };

  const removeItem = async (id: string, aniId: string) => {
    if (userName) {
      // remove from database
      const res = await fetch(`/api/user/update/episode`, {
        method: "DELETE",
        headers: {
          "Content-Type": "application/json",
        },
        body: JSON.stringify({
          name: userName,
          id,
          aniId,
        }),
      });
      const data = await res.json();

      if (id) {
        // remove from local storage
        const artplayerSettings =
          JSON.parse(localStorage.getItem("artplayer_settings") || "{}") || {};
        if (artplayerSettings[id]) {
          delete artplayerSettings[id];
          localStorage.setItem(
            "artplayer_settings",
            JSON.stringify(artplayerSettings)
          );
        }
      }
      if (aniId) {
        const currentData =
          JSON.parse(localStorage.getItem("artplayer_settings") || "{}") || {};

        const updatedData: { [key: string]: any } = {};

        for (const key in currentData) {
          const item = currentData[key];
          if (item.aniId !== aniId) {
            updatedData[key] = item;
          }
        }

        localStorage.setItem("artplayer_settings", JSON.stringify(updatedData));
      }

      // update client
      setRemoved(id || aniId);

      if (data?.message === "Episode deleted") {
        toast.success("Episode removed from history");
      }
    } else {
      if (id) {
        // remove from local storage
        const artplayerSettings =
          JSON.parse(localStorage.getItem("artplayer_settings") || "{}") || {};
        if (artplayerSettings[id]) {
          delete artplayerSettings[id];
          localStorage.setItem(
            "artplayer_settings",
            JSON.stringify(artplayerSettings)
          );
        }
        setRemoved(id);
      }
      if (aniId) {
        const currentData =
          JSON.parse(localStorage.getItem("artplayer_settings") || "{}") || {};

        // Create a new object to store the updated data
        const updatedData: { [key: string]: any } = {};

        // Iterate through the current data and copy items with different aniId to the updated object
        for (const key in currentData) {
          const item = currentData[key];
          if (item.aniId !== aniId) {
            updatedData[key] = item;
          }
        }

        // Update localStorage with the filtered data
        localStorage.setItem("artplayer_settings", JSON.stringify(updatedData));
        setRemoved(aniId);
      }
    }
  };

  return (
    <div>
      <div
        className={`flex items-center justify-between lg:justify-normal lg:gap-3 px-5 z-40 ${
          section === "Recommendations" ? "" : "cursor-pointer"
        }`}
        onClick={goToPage}
      >
        <h1 className="font-karla text-[20px] font-bold">{section}</h1>
        <ChevronRightIcon className="w-5 h-5" />
      </div>
      <div className="relative flex items-center lg:gap-2">
        <div
          onClick={slideLeft}
          className={`flex items-center mb-5 cursor-pointer hover:text-action absolute left-0 bg-gradient-to-r from-[#141519] z-40 h-full hover:opacity-100 ${
            scrollLeft ? "lg:visible" : "invisible"
          }`}
        >
          <ChevronLeftIcon className="w-7 h-7 stroke-2" />
        </div>
        <div
          id={ids}
          className="flex h-full w-full select-none overflow-x-scroll overflow-y-hidden scrollbar-hide lg:gap-8 gap-4 lg:p-10 py-8 px-5 z-30"
          onScroll={handleScroll}
          {...events}
          ref={ref as React.RefObject<HTMLDivElement>}
        >
          {ids !== "recentlyWatched"
            ? slicedData?.map((anime) => {
                const progress = og?.find((i: any) => i.mediaId === anime.id);

                let image;
                if (typeof anime.coverImage === "string") {
                  image = truncateImgUrl(anime.coverImage);
                } else if (anime.coverImage) {
                  image = anime.coverImage.extraLarge || anime.coverImage.large;
                }

                if (!image && anime.image) {
                  image = anime.image;
                }

                return (
                  <div
                    key={anime.id}
                    className="flex flex-col gap-3 shrink-0 cursor-pointer"
                  >
                    <Link
                      href={
                        ids === "listManga"
                          ? `/en/manga/${anime.id}`
                          : ids === "recentAdded"
                          ? anime?.slug
                            ? `/en/anime/watch/${
                                anime.id
                              }/gogoanime?id=${encodeURIComponent(
                                anime?.slug
                              )}&num=${anime.currentEpisode}`
                            : `/en/${type}/${anime.id}`
                          : `/en/${type}/${anime.id}`
                      }
                      className="hover:scale-105 hover:shadow-lg duration-300 ease-out group relative"
                      title={anime.title.romaji}
                    >
                      {ids === "onGoing" && (
                        <div className="h-[190px] lg:h-[265px] w-[135px] lg:w-[185px] bg-gradient-to-b from-transparent to-black/90 absolute z-40 rounded-md whitespace-normal font-karla group">
                          <div className="flex flex-col items-center h-full justify-end text-center pb-5">
                            <h1 className="line-clamp-1 w-[70%] text-[10px]">
                              {anime.title.romaji || anime.title.english}
                            </h1>
                            {checkProgress(progress) &&
                              !clicked?.hasOwnProperty(anime.id) && (
                                <ExclamationCircleIcon className="w-7 h-7 absolute z-40 text-white -top-3 -right-3" />
                              )}
                            {checkProgress(progress) && (
                              <div
                                onClick={() => handleAlert(String(anime.id))}
                                className="group-hover:visible invisible absolute top-0 bg-black bg-opacity-20 w-full h-full z-20 text-center"
                              >
                                <h1 className="text-[12px] lg:text-sm pt-28 lg:pt-44 font-bold opacity-100">
                                  {checkProgress(progress)}
                                </h1>
                              </div>
                            )}
                            {anime.nextAiringEpisode && (
                              <div className="flex gap-1 text-[13px] lg:text-base">
                                <h1>
                                  Episode {anime.nextAiringEpisode.episode} in
                                </h1>
                                <h1 className="font-bold">
                                  {convertSecondsToTime(
                                    anime?.nextAiringEpisode?.timeUntilAiring
                                  )}
                                </h1>
                              </div>
                            )}
                          </div>
                        </div>
                      )}
                      <div className="h-[190px] w-[135px] lg:h-[265px] lg:w-[185px] rounded-md z-30">
                        {ids === "recentAdded" && (
                          <div className="absolute bg-gradient-to-b from-black/30 to-transparent from-5% to-30% top-0 z-30 w-full h-full rounded" />
                        )}
                        {image && (
                          <Image
                            draggable={false}
                            src={image}
                            alt={
                              anime.title.romaji ||
                              anime.title.english ||
                              "coverImage"
                            }
                            width={500}
                            height={300}
                            className="z-20 h-[190px] w-[135px] lg:h-[265px] lg:w-[185px] object-cover rounded-md brightness-90"
                          />
                        )}
                      </div>
                      {ids === "recentAdded" && (
                        <Fragment>
                          <Image
                            src="/svg/episode-badge.svg"
                            alt="episode-badge"
                            width={200}
                            height={100}
                            className="w-24 lg:w-32 absolute top-1 -right-[12px] lg:-right-[17px] z-40"
                          />
                          <p className="absolute z-40 text-center w-[86px] lg:w-[110px] top-1 -right-2 lg:top-[5.5px] lg:-right-2 font-karla text-sm lg:text-base">
                            Episode{" "}
                            <span className="text-white">
                              {anime?.currentEpisode || anime?.episodeNumber}
                            </span>
                          </p>
                        </Fragment>
                      )}
                    </Link>
                    {ids !== "onGoing" && (
                      <Link
                        href={
                          ids === "listManga"
                            ? `/en/manga/${anime.id}`
                            : `/en/${type.toLowerCase()}/${anime.id}`
                        }
                        className="w-[135px] lg:w-[185px] line-clamp-2"
                        title={anime.title.romaji}
                      >
                        <h1 className="font-karla font-semibold xl:text-base text-[15px]">
                          {anime.status === "RELEASING" ||
                          ids === "recentAdded" ? (
                            <span className="dots bg-green-500" />
                          ) : anime.status === "NOT_YET_RELEASED" ? (
                            <span className="dots bg-red-500" />
                          ) : null}
                          {anime.title.romaji}
                        </h1>
                      </Link>
                    )}
                  </div>
                );
              })
            : userData
                ?.filter((i) => i.title && i.title !== null)
                ?.slice(0, 10)
                .map((i) => {
                  const time = i.timeWatched;
                  const duration = i.duration;
                  let prog = time && duration ? (time / duration) * 100 : 0;
                  if (prog > 90) prog = 100;

                  return (
                    <div
                      key={i.watchId}
                      className="flex flex-col gap-2 shrink-0 cursor-pointer relative group/item"
                    >
                      <div className="absolute flex flex-col gap-1 z-40 top-1 right-1 transition-all duration-200 ease-out opacity-0 group-hover/item:opacity-100 scale-90 group-hover/item:scale-100 group-hover/item:visible invisible ">
                        <HistoryOptions
                          remove={removeItem}
                          watchId={i.watchId}
                          aniId={i.aniId}
                        />
                        {i?.nextId && (
                          <button
                            type="button"
                            className="flex flex-col items-center group/next relative"
                            onClick={() => {
                              router.push(
                                `/en/anime/watch/${i.aniId}/${
                                  i.provider
                                }?id=${encodeURIComponent(
                                  i?.nextId || ""
                                )}&num=${i?.nextNumber}${
                                  i?.dub ? `&dub=${i?.dub}` : ""
                                }`
                              );
                            }}
                          >
                            <ChevronRightIcon className="w-6 h-6 shrink-0 bg-primary p-1 rounded-full hover:text-action scale-100 hover:scale-105 transition-all duration-200 ease-out" />
                            <span className="absolute font-karla bg-secondary shadow-black shadow-2xl py-1 px-2 whitespace-nowrap text-white text-sm rounded-md right-7 -bottom-[2px] z-40 duration-300 transition-all ease-out group-hover/next:visible group-hover/next:scale-100 group-hover/next:translate-x-0 group-hover/next:opacity-100 opacity-0 translate-x-10 scale-50 invisible">
                              Play Next Episode
                            </span>
                          </button>
                        )}
                      </div>
                      <Link
                        className="relative w-[320px] aspect-video rounded-md overflow-hidden group"
                        href={`/en/anime/watch/${i.aniId}/${
                          i.provider
                        }?id=${encodeURIComponent(i.watchId)}&num=${i.episode}${
                          i?.dub ? `&dub=${i?.dub}` : ""
                        }`}
                      >
                        <div className="w-full h-full bg-gradient-to-t from-black/70 from-20% to-transparent group-hover:to-black/40 transition-all duration-300 ease-out absolute z-30" />
                        <div className="absolute bottom-3 left-0 mx-2 text-white flex gap-2 items-center w-[80%] z-30">
                          <PlayIcon className="w-5 h-5 shrink-0" />
                          <h1
                            className="font-semibold font-karla line-clamp-1"
                            title={i?.title || i?.aniTitle}
                          >
                            {i?.title === i.aniTitle
                              ? `Episode ${i.episode}`
                              : i?.title || i?.aniTitle}
                          </h1>
                        </div>
                        <span
                          className={`absolute bottom-0 left-0 h-[2px] bg-red-600 z-30`}
                          style={{
                            width: `${prog}%`,
                          }}
                        />

                        {i?.image && (
                          <Image
                            src={i?.image}
                            width={320}
                            height={180}
                            alt="Episode Thumbnail"
                            className="w-full object-cover group-hover:scale-[1.02] duration-300 ease-out z-10"
                          />
                        )}
                      </Link>

                      <Link
                        className="flex flex-col font-karla w-full"
                        href={`/en/anime/watch/${i.aniId}/${
                          i.provider
                        }?id=${encodeURIComponent(i.watchId)}&num=${i.episode}`}
                      >
                        {/* <h1 className="font-semibold">{i.title}</h1> */}
                        <p className="flex items-center gap-1 text-sm text-gray-400 w-[320px]">
                          <span
                            className="text-white"
                            style={{
                              display: "inline-block",
                              maxWidth: "220px",
                              overflow: "hidden",
                              textOverflow: "ellipsis",
                              whiteSpace: "nowrap",
                            }}
                            title={i.aniTitle}
                          >
                            {i.aniTitle}
                          </span>{" "}
                          | Episode {i.episode}
                        </p>
                      </Link>
                    </div>
                  );
                })}
          {userData &&
            userData?.filter((i) => i.aniId !== null)?.length >= 10 &&
            section !== "Recommendations" && (
              <div
                key={section}
                className="flex flex-col cursor-pointer"
                onClick={goToPage}
              >
                <div className="w-[320px] aspect-video overflow-hidden object-cover rounded-md border-secondary border-2 flex flex-col gap-2 items-center text-center justify-center text-[#6a6a6a] hover:text-[#9f9f9f] hover:border-[#757575] transition-colors duration-200">
                  <h1 className="whitespace-pre-wrap text-sm">
                    More on {section}
                  </h1>
                  <ArrowRightCircleIcon className="w-5 h-5" />
                </div>
              </div>
            )}
          {filteredData?.length >= 10 && section !== "Recommendations" && (
            <div
              key={section}
              className="flex cursor-pointer"
              onClick={goToPage}
            >
              <div className="h-[190px] w-[135px] lg:h-[265px] lg:w-[185px] object-cover rounded-md border-secondary border-2 flex flex-col gap-2 items-center text-center justify-center text-[#6a6a6a] hover:text-[#9f9f9f] hover:border-[#757575] transition-colors duration-200">
                <h1 className="whitespace-pre-wrap text-sm">
                  More on {section}
                </h1>
                <ArrowRightCircleIcon className="w-5 h-5" />
              </div>
            </div>
          )}
        </div>
        <MdChevronRight
          onClick={slideRight}
          size={30}
          className={`hidden md:block mb-5 cursor-pointer hover:text-action absolute right-0 bg-gradient-to-l from-[#141519] z-40 h-full hover:opacity-100 hover:bg-gradient-to-l ${
            scrollRight ? "visible" : "hidden"
          }`}
        />
      </div>
    </div>
  );
}

function convertSecondsToTime(sec: number) {
  let days = Math.floor(sec / (3600 * 24));
  let hours = Math.floor((sec % (3600 * 24)) / 3600);
  let minutes = Math.floor((sec % 3600) / 60);

  let time = "";

  if (days > 0) {
    time += `${days}d `;
    time += `${hours}h`;
  } else {
    time += `${hours}h `;
    time += `${minutes}m`;
  }

  return time.trim();
}

function checkProgress(entry: { progress: any; media: any }) {
  const { progress, media } = entry;
  const { episodes, nextAiringEpisode } = media;

  if (nextAiringEpisode !== null) {
    const { episode } = nextAiringEpisode;

    if (episode - progress > 1) {
      const missedEpisodes = episode - progress - 1;
      return `${missedEpisodes} episode${missedEpisodes > 1 ? "s" : ""} behind`;
    }
  }

  return;
}
