<script lang="ts" context="module">
  import {
    GetAniListItem,
    GetAniListLoggedInUser,
    GetAniListUserWatchingList,
    GetMyAnimeListAnime,
    GetMyAnimeListLoggedInUser,
    GetSimklLoggedInUser,
    LogoutAniList,
    LogoutMyAnimeList,
    LogoutSimkl,
    SimklGetUserWatchlist,
    SimklSearch,
  } from "../../wailsjs/go/main/App";
  import type {
    AniListCurrentUserWatchList,
    AniListGetSingleAnime,
  } from "../anilist/types/AniListCurrentUserWatchListType.js";
  import { writable } from "svelte/store";
  import type {
    SimklAnime,
    SimklUser,
    SimklWatchList,
  } from "../simkl/types/simklTypes";
  import {
    type AniListUser,
    MediaListSort,
  } from "../anilist/types/AniListTypes";
  import type {
    MALAnime,
    MALWatchlist,
    MyAnimeListUser,
  } from "../mal/types/MALTypes";
  import type { TableItems } from "../helperTypes/TableTypes";
  import { AniListGetSingleAnimeDefaultData } from "../helperDefaults/AniListGetSingleAnime";

  export let aniListAnime = writable(AniListGetSingleAnimeDefaultData);
  export let title = writable("");
  export let aniListLoggedIn = writable(false);
  export let simklLoggedIn = writable(false);
  export let malLoggedIn = writable(false);
  export let simklWatchList = writable({} as SimklWatchList);
  export let aniListPrimary = writable(true);
  export let simklPrimary = writable(false);
  export let malPrimary = writable(false);
  export let simklUser = writable({} as SimklUser);
  export let aniListUser = writable({} as AniListUser);
  export let malUser = writable({} as MyAnimeListUser);
  export let aniListWatchlist = writable({} as AniListCurrentUserWatchList);
  export let malWatchList = writable({} as MALWatchlist);
  export let malAnime = writable({} as MALAnime);
  export let simklAnime = writable({} as SimklAnime);
  export let loading = writable(false);
  export let tableItems = writable([] as TableItems);
  export let watchlistNeedsRefresh = writable(false);
  export let aniListSort = writable(MediaListSort.UpdatedTimeDesc);

  export let watchListPage = writable(1);
  export let animePerPage = writable(20);

  let isAniListPrimary: boolean;
  let page: number;
  let perPage: number;
  let sort: string;
  let aniWatchlist: AniListCurrentUserWatchList;
  let currentAniListAnime: AniListGetSingleAnime;

  let isMalLoggedIn: boolean;
  let isSimklLoggedIn: boolean;

  aniListPrimary.subscribe((value) => (isAniListPrimary = value));
  watchListPage.subscribe((value) => (page = value));
  animePerPage.subscribe((value) => (perPage = value));
  aniListWatchlist.subscribe((value) => (aniWatchlist = value));
  malLoggedIn.subscribe((value) => (isMalLoggedIn = value));
  simklLoggedIn.subscribe((value) => (isSimklLoggedIn = value));
  aniListAnime.subscribe((value) => (currentAniListAnime = value));
  aniListSort.subscribe((value) => (sort = value));

  export interface ApiError {
    service: string;
    message: string;
    statusCode?: string;
    canRetry: boolean;
  }
  export const apiError = writable<ApiError | null>(null);
  export const isApiDown = writable(false);
  export function setApiError(
    service: string,
    message: string,
    statusCode?: string,
    canRetry: boolean = true,
  ) {
    apiError.set({
      service,
      message,
      statusCode,
      canRetry,
    });
    isApiDown.set(true);
  }
  export function clearApiError() {
    apiError.set(null);
    isApiDown.set(false);
  }

  export async function GetAnimeSingleItem(
    aniId: number,
    login: boolean,
  ): Promise<""> {
    await GetAniListItem(aniId, login).then((aniListResult) => {
      let finalResult: AniListGetSingleAnime;
      finalResult = aniListResult;
      if (login === false) {
        finalResult.data.MediaList.status = "";
        finalResult.data.MediaList.score = 0;
        finalResult.data.MediaList.progress = 0;
        finalResult.data.MediaList.notes = "";
        finalResult.data.MediaList.repeat = 0;
        finalResult.data.MediaList.startedAt.day = 0;
        finalResult.data.MediaList.startedAt.month = 0;
        finalResult.data.MediaList.startedAt.year = 0;
        finalResult.data.MediaList.completedAt.day = 0;
        finalResult.data.MediaList.completedAt.month = 0;
        finalResult.data.MediaList.completedAt.year = 0;
      }
      aniListAnime.set(finalResult);
      title.set(
        currentAniListAnime.data.MediaList.media.title.english === ""
          ? currentAniListAnime.data.MediaList.media.title.romaji
          : currentAniListAnime.data.MediaList.media.title.english,
      );
    });
    if (isMalLoggedIn) {
      await GetMyAnimeListAnime(
        currentAniListAnime.data.MediaList.media.idMal,
      ).then((malResult) => {
        malAnime.set(malResult);
      });
    }
    if (isSimklLoggedIn) {
      await SimklSearch(currentAniListAnime.data.MediaList).then(
        (value: SimklAnime) => {
          simklAnime.set(value);
        },
      );
    }
    return "";
  }

  export function loginToSimkl(): void {
    GetSimklLoggedInUser().then((user) => {
      if (Object.keys(user).length === 0) {
        simklLoggedIn.set(false);
      } else {
        simklUser.set(user);
        SimklGetUserWatchlist().then((result) => {
          simklWatchList.set(result);
          simklLoggedIn.set(true);
        });
      }
    });
  }

  export function loginToAniList(): void {
    GetAniListLoggedInUser().then((result) => {
      aniListUser.set(result);
      if (isAniListPrimary) {
        GetAniListUserWatchingList(page, perPage, sort).then((result) => {
          aniListWatchlist.set(result);
          aniListLoggedIn.set(true);
        });
      } else {
        aniListLoggedIn.set(true);
      }
    });
  }

  export function loginToMAL(): void {
    GetMyAnimeListLoggedInUser().then((result) => {
      malUser.set(result);
      malLoggedIn.set(true);
    });
  }

  export function logoutOfAniList(): void {
    LogoutAniList().then((result) => {
      console.log(result);
      if (Object.keys(aniWatchlist).length !== 0) {
        aniListWatchlist.set({} as AniListCurrentUserWatchList);
      }
      aniListUser.set({} as AniListUser);
      aniListLoggedIn.set(false);
    });
  }

  export function logoutOfMAL(): void {
    LogoutMyAnimeList().then((result) => {
      console.log(result);
      malUser.set({} as MyAnimeListUser);
      malLoggedIn.set(false);
    });
  }

  export function logoutOfSimkl(): void {
    LogoutSimkl().then((result) => {
      console.log(result);
      simklUser.set({} as SimklUser);
      simklLoggedIn.set(false);
    });
  }
</script>
