import {computed, readonly, watchEffect} from "vue";
import {createEventHook, createGlobalState, useLocalStorage} from "@vueuse/core";
import mxConst from "@/common/mxConst";
import mxConfig from "@/common/mxConfig";
import {getInfo, login, logout, logoutPhysical} from "@/api/login";
import {useCacheStore} from "@/hooks/useCacheStore";
import {mobile} from "@/uni_modules/uv-ui-tools/libs/function/test";
import defaultAvatar from "@/static/personal/avatar_default.png";

export const useUserStore = createGlobalState(() => {
    // user data
    const token = useLocalStorage(mxConst.keyToken, "")
    const data = useLocalStorage(mxConst.keyUserInfo, {})
    const appConfig = useLocalStorage(mxConst.keyAppConfig, {})
    const agreeProtocolUserName = useLocalStorage(mxConst.keyUserAgreed, "")
    const userInfoUpdate = createEventHook()

    // computed
    const isLogin = computed(() => !!token.value)
    const isBind = computed(() => data.value.isBind == 1) // 表示卡登陆/关联，但手机信息不一定完善了
    const isMobileBind = computed(() => isBind.value || mobile(data.value.phonenumber)) // 手机信息已完善情况
    const isCardBind = computed(() => isBind.value || !isMobileBind.value) // 手机信息未完善情况
    const isScoreLocked = computed(() => data.value.scoreLock == mxConst.enum.scoreLock.locked)
    const isScoreUnlocked = computed(() => data.value.scoreLock == mxConst.enum.scoreLock.unlock)
    const isScoreLocking = computed(() => data.value.scoreLock == mxConst.enum.scoreLock.locking)
    const isCultural = computed(() => data.value.examType == 'VHS')
    const enableAuthModify = computed(() => data.value.enableAuthModify)
    const period = computed(() => data.value.period) // 只是为了妆容旧结构，理论上这个值已经没有用了
    // 同意协议需要严格判定，必须和当前用户挂钩
    const isAgreeProtocol = computed(() => data.value.userName == agreeProtocolUserName.value)
    // isK9Sensitive 是旧的store.getters上的属性，继续保留
    const isK9Sensitive = computed(() => data.value.isK9Sensitive)
    const avatar = computed(() => data.value.avatar || defaultAvatar)

    // hooks
    watchEffect(() => mergeAppConfig())

    // methods
    function mergeAppConfig() {
        const overrideConfig = appConfig.value;
        if (!uni.$uv) {
          return;
        }
        const mergedConfig = uni.$uv.deepMerge(mxConfig, overrideConfig);
        Object.assign(mxConfig, mergedConfig);
        // console.log("merge app config: to mx config", overrideConfig, mxConfig);
    }

    const Login = async function (data) {
        const loginRes = await login(data);
        token.value = loginRes.token;
        const infoRes = await GetInfo();
        agreeProtocolUserName.value = infoRes.data.userName;
    };

    const SyncToken = async function (val) {
        // 注册时，注册接口会返回token
        token.value = val
        const infoRes = await GetInfo()
        agreeProtocolUserName.value = infoRes.data.userName
    }

    const GetInfo = async function () {
        const infoRes = await getInfo()
        data.value = infoRes.data
        appConfig.value = infoRes[mxConst.propAppConfig]

        // 每次重新登陆，主动清空所有缓存
        const {clearCache} = useCacheStore()
        clearCache()

        await userInfoUpdate.trigger()
        return infoRes
    };

    const Logout = async function () {
        await logout()
        token.value = ""
        data.value = Object.create(null)
    };

    const LogoutPhysical = async function () {
        await logoutPhysical()
        token.value = ""
        data.value = Object.create(null)
    };

    const clearToken = function () {
        token.value = ''
        data.value = Object.create(null)
    }

    return {
        token: readonly(token),
        currentUser: data,
        appConfig: appConfig,
        isLogin,
        isBind,
        isMobileBind,
        isCardBind,
        isScoreLocked,
        isScoreUnlocked,
        isScoreLocking,
        isCultural,
        enableAuthModify,
        period,
        isAgreeProtocol,
        isK9Sensitive,
        avatar,
        Login,
        SyncToken,
        GetInfo,
        Logout,
        LogoutPhysical,
        clearToken,
        onUserInfoUpdate: userInfoUpdate.on
    };
});
