import React, { useContext, useEffect, useState } from "react";
import { QuestContext } from "../../context/QuestContext";
import useQuestNotification from "../QuestNotification/useQuestNotification";
import general from "../../common/General/General";
import { ITopThree } from "../../components/Leaderboard/Leaderboard.type";
import { TextStyle, ViewStyle } from "react-native";
import { AllEvents } from "../../common/enum";

interface leaderboardParams {
  questUserId?: string;
  userToken?: string;
  userId?: string;
  onError?: (
    event: "GET_CAMPAIGN_ACTIONS" | "QUEST_LOGIN",
    message: string,
    data?: {}
  ) => void;
  styleConfig?: {
    Description?: TextStyle;
    Footer?: {
      FooterStyle?: ViewStyle;
      FooterText?: TextStyle;
      FooterIcon?: TextStyle;
    };
    Form?: ViewStyle;
    Heading?: ViewStyle;
    IconStyle?: ViewStyle;
    IndexBackground?: ViewStyle;
    IndexColor?: TextStyle;
    InnerBackground?: ViewStyle;
    MainHeading?: ViewStyle;
    PointsBackground?: ViewStyle;
    PointsColor?: ViewStyle;
    ProgressBarColor?: ViewStyle;
  };
}

const useLeaderboard = ({
  userToken,
  questUserId,
  userId,
  onError,
  styleConfig,
}: leaderboardParams) => {
  const { apiKey, entityId, authenticationToken } = useContext(QuestContext);
  const [loading, setLoading] = useState(true);
  const [leadersData, setLeadersData] = useState<ITopThree[]>([]);
  const [memberShip, setMemberShip] = useState(null);
  const [style, setStyle] = useState(styleConfig);

  const [credentials, setCredentials] = useState({
    userId: questUserId,
    token: userToken,
  });
  async function fetchData(userId:string, token:string) {
    try {
      const response = await general.makeRequest({
        url: `/entities/${entityId}/xp-leaderboard`,
        method: "GET",
        query: {
          streak: "default_streak",
        },
        headers: {
          "Content-Type": "application/json",
          userId: userId,
          token: token,
          apiKey,
        },
      });
      if (!response.success) {
        if (onError) {
          onError(AllEvents.GET_CAMPAIGN_ACTIONS, response.error, response);
        }
      }

      let users = response.data.map((user: ITopThree) => ({
        ...user,
        xpLimit: response.data[0].runningXP,
      }));

      if (response?.membershipsTiers?.length > 0) {
        setMemberShip(response.membershipsTiers);

        users = users.map((user: ITopThree) => {
          let maxTier = response.membershipsTiers.find(
            (tier:any) => tier.xpThreshold > user?.runningXP || 0
          );
          user.xpLimit = maxTier?.xpThreshold || user.xpLimit;
          return user;
        });
      }

      setLeadersData(users);
      if (response.data.sdkConfig.uiProps) {
        setStyle(response.data.sdkConfig.uiProps.styleConfig);
      }
    } catch (error:any) {
      if (onError) {
        onError(AllEvents.GET_CAMPAIGN_ACTIONS, error.message);
      }
    } finally {
      setLoading(false);
    }
  }

  async function externalLogin() {
    try {
      const response = await general.makeRequest({
        url: `/users/external/login`,
        method: "POST",
        headers: {
          "Content-Type": "application/json",
          apiKey,
          entityId,
          "entity-authentication-token": authenticationToken,
        },
        body: {
          externalUserId: userId,
          entityId,
        },
      });

      if (response.userId && response.token) {
        setCredentials({
          userId: response.userId,
          token: response.token,
        });
      }
      return response;
    } catch (error:any) {
      if (onError) {
        onError(AllEvents.QUEST_LOGIN, error.message);
      }
    }
  }

  useEffect(() => {
    if (questUserId && userToken) {
      (async () => {
        await fetchData(questUserId, userToken);
        setLoading(false);
      })();
    } else if (userId) {
      (async () => {
        let credentials = await externalLogin();
        await fetchData(credentials.userId, credentials.token);
        setLoading(false);
      })();
    }
  }, [questUserId, userToken, userId]);

  return {
    loading,
    leadersData,
    styleConfig: style,
  };
};

export default useLeaderboard;
