import { TFunction } from "i18next";
import { toast } from "react-toastify";
import { sprintf } from "sprintf-js";
import CryptoJS from "crypto-js";
import { getMillis } from "taehui-ts/date";

import { wwwAXIOS } from "src/Www";

export default function setAvatarStore() {
  return {
    totem: "",
    taehuiAvatarID: "",
    taehuiAvatarName: "",
    taehuiLevel: 0,
    taehuiFax: "",
    taehuiAvatarIntro: "",

    setSession({
      totem,
      avatarID,
      avatarName,
      level,
      fax,
      avatarIntro,
    }: {
      totem: string;
      avatarID: string;
      avatarName: string;
      level: number;
      fax: string;
      avatarIntro: string;
    }) {
      this.totem = totem;
      this.taehuiAvatarID = avatarID;
      this.taehuiAvatarName = avatarName;
      this.taehuiLevel = level;
      this.taehuiFax = fax;
      this.taehuiAvatarIntro = avatarIntro;
    },

    saveTotem() {
      window.sessionStorage.setItem("totem", this.totem);
    },

    async loadTotem() {
      const totem = window.sessionStorage.getItem("totem");
      if (totem) {
        const { status, data } = await wwwAXIOS.patch("/avatar/totem", null, {
          headers: { millis: getMillis(), totem },
        });
        if (status === 201) {
          this.setSession({ totem, ...data });
        }
      }
    },

    async postAvatar(
      t: TFunction,
      avatarID: string,
      avatarCipher: string,
      avatarName: string,
      fax: string,
    ) {
      const { status } = await wwwAXIOS.post(
        "/avatar",
        {
          avatarID,
          avatarCipher,
          avatarName,
          fax,
        },
        {
          headers: {
            millis: getMillis(),
          },
        },
      );
      switch (status) {
        case 201:
          this.signIn(t, avatarID, avatarCipher);
          break;
        case 403:
          toast.error(t("alreadyAvatarID"));
          break;
      }
    },

    async signIn(t: TFunction, avatarID: string, avatarCipher: string) {
      const { status, data } = await wwwAXIOS.post(
        "/avatar/getTotem",
        {
          avatarID,
          avatarCipher,
        },
        {
          headers: {
            millis: getMillis(),
          },
        },
      );
      if (status === 200) {
        this.setSession(data);
        this.saveTotem();
        toast.success(sprintf(t("signedInText"), this.taehuiAvatarName));
        return true;
      } else {
        toast.warning(t("wrongAvatar"));
        return false;
      }
    },

    async notSignIn(t: TFunction) {
      const { status } = await wwwAXIOS.delete("/avatar/totem", {
        headers: {
          millis: getMillis(),
          totem: this.totem,
        },
      });
      if (status === 204) {
        toast.success(sprintf(t("notSignedInText"), this.taehuiAvatarName));
        this.setSession({
          totem: "",
          avatarID: "",
          avatarName: "'",
          level: 0,
          fax: "",
          avatarIntro: "",
        });
        this.saveTotem();
        return true;
      } else {
        return false;
      }
    },

    async autoSignIn(t: TFunction) {
      if (window.localStorage.getItem("autoSignIn") === "true") {
        this.signIn(
          t,
          window.localStorage.getItem("avatarID") ?? "",
          CryptoJS.AES.decrypt(
            window.localStorage.getItem("avatarCipher") ?? "",
            "591A6F91-2A27-4A88-88FA-0FEB7CB5FD94",
          ).toString(CryptoJS.enc.Utf8),
        );
      }
    },

    get isTaehui() {
      return this.taehuiLevel === 2;
    },
  };
}
