import '@/types/Store/User';
import '@/types/User';
import moment from 'moment-mini';
import lodash from 'lodash';
import { useUserStore } from '@/vue/pinia/user';
import { useUsageStore } from '@/vue/pinia/usage';
import {
  userSetting, indentifySetting,
} from '@/plugins/setting';
import { loginUser, getUserInfo, registerUser } from '@/api/autoshopee/user';
import i18n from '@/vue/i18n';
import { getKeyProductClone, getGptWriterUserPlanAllow } from './utils';
import { cacheDestroyAll } from '@/plugins/store/cache';
import { destroyAllDatabase, pullAllDatabaseRemote } from '@/models/loader';
import { loggerVue } from '@/plugins/logger';

/** @type {VuexStoreModule} */
export const userStore = {
  state() {
    return {
      userData: userSetting.userData.get(),
      id: userSetting.userId.get(),
      extensionPlan: userSetting.userExtensionPlan.get(),
      token: userSetting.userToken.get(),
      username: userSetting.userName.get(),
      password: userSetting.userPassword.get(),
    };
  },

  mutations: {
    /**
     * @param {StateUser} state @param {string} token
     * @param token
     */
    SET_USER_TOKEN(state, token) {
      state.token = token;
      userSetting.userToken.set(token);
    },

    /**
     * @param {StateUser} state @param {UserData} userData
     * @param userData
     */
    SET_USER_DATA(state, userData) {
      state.userData = userData;
      state.id = userData._id;
      userSetting.userData.set(userData);
      userSetting.userId.set(userData._id);

      if (userData.extensionPlan) {
        const { extensionPlan } = userData;
        state.extensionPlan = extensionPlan;
        userSetting.userExtensionPlan.set(extensionPlan);
      }
    },

    /**
     * @param {StateUser} state @param {object} root @param {string} root.username @param {string} root.password
     * @param root0
     * @param root0.username
     * @param root0.password
     */
    SET_USER_LOGIN(state, { username, password }) {
      state.username = username;
      state.password = password;
      userSetting.userPassword.set(password);
      userSetting.userName.set(username);
    },

    /** @param {StateUser} state */
    SET_USER_LOGOUT(state) {
      state.token = '';
      state.id = '';
      state.userData = {};
      state.extensionPlan = 'Free';
    },

    /**
     * @param {StateUser} state @param {string} platform
     * @param platform
     */
    DECREASE_USER_SCORE(state, platform) {
      const key = getKeyProductClone(platform);
      const set = lodash.get(state, key, 0) - 1;
      lodash.set(state, key, set);
    },

  },

  getters: {
    /** @param {StateUser} state */
    getToken(state) {
      return !!state.token;
    },

    /** @param {StateUser} state */
    getIsAuthed(state) {
      return !!(state.id && state.token);
    },

    /** @param {StateUser} state */
    getUserPlan(state) {
      return state.extensionPlan;
    },

    /** @param {StateUser} state */
    getTimeExpried(state) {
      return state.userData && state.userData.timeExpired
        ? moment(state.userData.timeExpired).format('DD/MM/YYYY').toString()
        : '';
    },

    /** @param {StateUser} state */
    getUsername(state) {
      return state.username;
    },

    /** @param {StateUser} state */
    getScoreClone(state) {
      return (platform) => {
        return lodash.get(state, getKeyProductClone(platform), 0);
      };
    },

    /** @param {StateUser} state */
    getPassword(state) {
      return state.password;
    },

    /** @param {StateUser} state */
    getUserData(state) {
      return state.userData;
    },

    /** @param {StateUser} state */
    getUserId(state) {
      return state.id;
    },

    /** @param {StateUser} state */
    getIsVipPlus(state) {
      return state.extensionPlan === 'VipPlus';
    },

    /** @param {StateUser} state */
    getIsPaidVip(state) {
      return ['Vip', 'VipPlus'].includes(state.extensionPlan);
    },

    /** @param {StateUser} state */
    getIsPaidPlan(state) {
      return state.extensionPlan !== 'Free';
    },

    /** @param {StateUser} state */
    getUsageGptWriter(state) {
      const allow = getGptWriterUserPlanAllow(state.extensionPlan);
      return {
        allow,
        text: !allow ? i18n.t('AI_GPT_FUNCTION_REQURIED_HIGH_PLAN') : '',
      };
    },
  },

  actions: {
    SetToken({ commit }, token) {
      commit('SET_USER_TOKEN', token);
    },

    SetUser({ commit }, user) {
      commit('SET_USER_DATA', user);
    },

    SetLogin({ commit }, { username, password }) {
      commit('SET_USER_LOGIN', { username, password });
    },

    UserStore({ state }) {
      const userStore = useUserStore();
      userStore.setUsername(state.username);
      userStore.setUserId(state.id);
      userStore.setUserToken(state.token);
      userStore.setUserData(state.userData);
    },

    async UserLogin({ commit, dispatch }, { username, password }) {
      const profileId = indentifySetting.profileId.get();

      /** @type {UserLogin} */
      const loginResult = await loginUser(username, password, profileId);

      if (loginResult.success && loginResult.token) {
        commit('SET_USER_LOGIN', { username, password });
        commit('SET_USER_TOKEN', loginResult.token);
        commit('SET_USER_DATA', loginResult.data);

        dispatch('UserStore');
        dispatch('UserFetch');
        dispatch('UserSyncRemote');
        useUsageStore().resetUsage();
      }

      return loginResult;
    },

    async UserRegister(_, {
      email, username, password, fullname, phoneNumber, trialRequest,
    }) {
      return registerUser(email, username, password, fullname, phoneNumber, trialRequest);
    },

    async UserFetch({ commit, dispatch }) {
      const userInfo = await getUserInfo();

      if (userInfo.success && userInfo.data && userInfo.data.username) {
        commit('SET_USER_DATA', userInfo.data);
      }

      if (userInfo && userInfo.error && userInfo.error === 403) {
        dispatch('PushMessageError', i18n.t('USER_LOGIN_WAS_LOGOUT'));
        setTimeout(() => {
          dispatch('UserLogout');
        }, 1000);
      }

      return userInfo;
    },

    UseScoreClone({ commit }, platform) {
      commit('DECREASE_USER_SCORE', platform);
    },

    UserLogout({ commit, dispatch, rootState }) {
      commit('SET_USER_LOGOUT');

      userSetting.userExtensionPlan.set('Free');
      userSetting.userId.remove();
      userSetting.userToken.remove();
      userSetting.userData.remove();

      try {
        cacheDestroyAll();
        destroyAllDatabase();

        if (rootState?.lazada?.shop) {
          rootState.lazada.shop.list = [];
          rootState.lazada.shop.selected = '';
        }

        if (rootState?.tiktok?.shop) {
          rootState.tiktok.shop.list = [];
          rootState.tiktok.shop.selected = '';
        }

        if (rootState?.tiktok?.warehouse) {
          rootState.tiktok.warehouse.list = [];
          rootState.tiktok.warehouse.selected = '';
        }

        if (rootState?.shopee_seller?.shopSync) {
          rootState.shopee_seller.shopSync = {};
          rootState.shopee_seller.ref = '';
        }
      } catch (error) {
        loggerVue.error({
          msg: 'SET_USER_LOGUT_ERROR',
          error,
        });
      }

      return dispatch('RouterTo', 'login');
    },

    async UserSyncRemote({ getters }) {
      if (!getters.getIsAuthed) {
        return null;
      }
      return pullAllDatabaseRemote();
    },
  },
};
