import { useEffect, useState } from "react";
import {motion} from "framer-motion"
import CommentSection from "components/comment/CommentSection";
import ProfileWindow from "components/window/ProfileWindow";
import axios, { AxiosResponse } from "axios";
import Template from "components/window/Template";
import { fetch } from "logger";
import { GetStaticProps, NextPage } from "next";
import toast from "react-hot-toast";
import { dehydrate, QueryClient } from "@tanstack/query-core";
import { useQuery } from "@tanstack/react-query";
import { PlayerData, CommentsType } from "helper/types";
import { useTracker } from "hooks/useTracker";
import Seo from "components/SEO";
import { getFullWeapons, getFullLegends, allowedToTrack } from "helper";
function getOGURL(player?: PlayerData) {
  try {
    if (!player?.stats && !player?.ranked) return "";
    const fullLegends = getFullLegends(player.stats.legends);
    const fullWeapons = getFullWeapons(fullLegends);
    //
    let url = `${process.env.DOMAIN}/api/og/player?`;
    let searchParams = new URLSearchParams();

    searchParams.set(
      "isRanked",
      (!!(Object.keys(player?.ranked).length > 0 && player?.ranked)).toString()
    );
    // searchParams.set("name", player.stats.name)
    if (player?.stats.clan?.clan_name)
      searchParams.set("clan", player?.stats.clan?.clan_name);
    searchParams.set("xp", player.stats.xp.toString());
    searchParams.set("level", player.stats.level.toString());
    searchParams.set("xp_percentage", player.stats.xp_percentage.toString());
    searchParams.set(
      "games",
      (player?.ranked?.games ?? player?.stats?.games).toString()
    );
    searchParams.set(
      "wins",
      (player?.ranked?.wins ?? player?.stats?.wins).toString()
    );
    searchParams.set("kos", fullWeapons.kos.toString());
    searchParams.set("teamkos", fullWeapons.teamkos.toString());
    searchParams.set("suicides", fullWeapons.suicides.toString());
    searchParams.set("falls", fullWeapons.falls.toString());
    searchParams.set("matchtime", fullWeapons.matchtime.toString());
    searchParams.set("damagedealt", fullWeapons.dmg.toString());
    searchParams.set("damagetaken", fullWeapons.dmg_taken.toString());
    searchParams.set("rating", (player?.ranked?.rating || 0).toString());
    searchParams.set(
      "peak_rating",
      (player?.ranked?.peak_rating || 0).toString()
    );
    searchParams.set(
      "region_rank",
      (player?.ranked?.region_rank || 0).toString()
    );
    searchParams.set(
      "global_rank",
      (player?.ranked?.global_rank || 0).toString()
    );
    searchParams.set("tier", player?.ranked?.tier);
    searchParams.set("region", player?.ranked?.region);

    return (
      encodeURI(url + searchParams.toString()) +
      `&name=${encodeURIComponent(player.stats.name)}`
    );
  } catch (e) {
    return "";
  }
}
const PlayerPage: NextPage<props> = ({
  id,
  error,
  isSteam = false,
  isValid = false,
  router: {
    query: { name, animate = false },
  },
}: props) => {
  const { data: player } = useQuery<PlayerData>(
    [`player-${id}`],
    async () => getPlayerData(isSteam, id),
    {
      staleTime: 59000,
      cacheTime: 59000,
      // refetchOnWindowFocus: true,
    }
  );
  const [comments, setComments] = useState<CommentsType|undefined>(undefined)
  const { data: commentsData } = useQuery<CommentsType>(
    [`comment-${id}`],
    async () => {
      let comments: AxiosResponse = await axios.get<AxiosResponse>(
        `${process.env.DOMAIN}/api/player/${id}/comments`,
        {
          headers: {
            "Content-Type": "application/json",
            Accept: "application/json",
          },
        }
      );
      let data: {comments: CommentsType} = comments.data;
      setCommentsLoading(false)
      setComments(data.comments)
      return data.comments;
    },
    {
      staleTime: 10000,
      cacheTime: 10000,
      // refetchOnWindowFocus: true,
    }
  );
  const { getPlayerTrackerData, updatePlayerTrackerData } = useTracker();
  const [trackerData, setTrackerData] = useState({
    views: 0,
    badges: [],
  });
  const [commentsLoading, setCommentsLoading] = useState(true)
  useEffect(() => {
    async function run() {
      if (error) toast.error(error);
      fetch.info({
        prefix: `Player Page`,
        message: `Displaying player: %c${player?.stats?.name} (${id})%c\n\nSteam: ${isSteam}\nValid: ${isValid}`,
      });
      if (player?.stats && player.stats.name) {
        if(!allowedToTrack()) {
          setTrackerData(await getPlayerTrackerData(id, player.stats.name));
          return
        }
        let viewed_before = localStorage.getItem(`viewed_${id}`);
        let timestamp =
          viewed_before && JSON.parse(viewed_before)?.["timestamp"];
        // Check if the player has been viewed before
        // and if it was viewed return
        // and check if current timestamp is greater than the timestamp
        if (viewed_before && timestamp && timestamp > Date.now()) {
          setTrackerData(await getPlayerTrackerData(id, player.stats.name));
          return;
        }
        setTrackerData(await updatePlayerTrackerData(id, player.stats.name));
        localStorage.setItem(
          `viewed_${id}`,
          JSON.stringify({
            timestamp: Date.now() + 4 * 60 * 60 * 1000,
          })
        );
      }
    }
    run();
    return () => {};
  }, []);
  return (
<motion.div initial={animate ? {
        y: -20,
        opacity: 0
      } : {}} animate={animate ? {
        y: 0,
        opacity: 1
      } : {}} exit={{
        y: 20,
        opacity: 0,
      }} transition={{
        duration: 0.3,
        // delay: animate ? 0.8 : 0
      }}>     
      <Seo
        templateTitle={player?.stats?.name || "Player Not Found"}
        image={getOGURL(player)}
        description={
          player?.stats?.name
            ? `${player?.stats?.name}'s Statistics on Brawlhalla`
            : "Player not found"
        }
      />
      <Template  useWindow={false}>
        <ProfileWindow
          {...trackerData}
          name={player?.stats?.name}
          share={true}
          {...player}
          error={error}
        />
        <CommentSection brawlhalla_id={id} setComments={setComments} comments={comments} loading={commentsLoading} />
      </Template>
    </motion.div>
  );
};

// This is to cache the player data for all requests
// And it re-fetches the player data every 60s
async function getPlayerData(
  isSteam: boolean,
  id: string | number | string[] | undefined
) {
  let player: AxiosResponse = await axios.get<AxiosResponse>(
    `${process.env.DOMAIN}/api/player/${isSteam ? `steam/${id}` : id}`,
    {
      headers: {
        "Content-Type": "application/json",
        Accept: "application/json",
      },
    }
  );
  let data: PlayerData = player.data;
  if (!data?.ranked?.rating) data.ranked = {};
  return data;
}
export const getStaticProps: GetStaticProps = async (context) => {
  let id = context?.params?.id;
  if (!id)
    return {
      props: {
        isValid: false,
      },
      revalidate: 60,
    };
  let isSteam = false;
  let isValid = false;
  if (id.length === 17) {
    isSteam = true;
    isValid = true;
  }
  if (
    /[1-9]/g.test(id.toString()) &&
    !isNaN(Number(id.toString())) &&
    Number(id) >= 1
  ) {
    isValid = true;
  }
  if (id.length >= 18) {
    isSteam = false;
    isValid = false;
  }
  if (isValid) {
    try {
      const queryClient = new QueryClient();
      await queryClient.prefetchQuery(
        [`player-${id}`],
        async () => getPlayerData(isSteam, id),
        {
          staleTime: 59000,
          cacheTime: 59000,
        }
      );
      return {
        props: {
          dehydratedState: dehydrate(queryClient),
          isSteam,
          id,
          isValid,
        },
        revalidate: 60,
      };
    } catch (e) {
      console.log(e);
      return {
        props: {
          error: !!e,
        },
        revalidate: 60,
      };
    }
  }
  return {
    props: {
      id: id,
      isValid,
      error: "Invalid id",
    },
    // Re-fetches the data every {time} seconds
    revalidate: 60,
  };
};

export async function getStaticPaths() {
  return {
    paths: [],
    fallback: "blocking",
  };
}

interface props {
  player: PlayerData;
  id: string | number;
  error: any;
  animate?: boolean;
  router?: {
    query?: {
      animate?: boolean
    };
  };
  isSteam?: boolean;
  isValid?: boolean;
}
export default PlayerPage;
