import { reactive } from 'vue'
import { v4 } from 'uuid'
import { encryptAES, decryptAES } from '@/utils/crypto'
import { timerTask } from '@/utils/timer'
import { ClientType } from '@/constants/client'
import { queryLoginId, login } from '@/services/api/account'
import { sessionData, localData } from '@/stores/storage'
import { loginStore, enumStore, errorInfoStore, userStore, futuresStore, accountStore } from '@/stores'
import { checkToken, checkTokenLoop } from '@/business/common'
import service from '@/services'
import socket from '@/services/socket'
import eventBus from '@/services/bus'
import cryptojs from 'crypto-js'

export function useLogin() {
    const { logining } = loginStore.$mapState()
    const { token } = loginStore.$mapGetters()

    const formData = reactive<Proto.LoginReq>({
        LoginID: localStorage.getItem('thj_loginId') ?? '',
        LoginPWD: '',
        GUID: v4(),
        LoginType: 0,
        ClientType: ClientType.None,
        Version: '2.0.0.0',
        DeviceID: ''
    })

    const loadBaseData = async () => {
        await service.onReady() // 等待服务初始化
        await Promise.all([
            errorInfoStore.actions.getErrorInfoList(),
            enumStore.actions.getAllEnumList(),
        ])
    }

    const loadUserData = async () => {
        await checkToken() // 令牌校验
        await userStore.actions.getUserData()
        futuresStore.actions.getGoodsList()
        accountStore.actions.getAccountList()
        checkTokenLoop()
    }

    const loginAction = async (params: Proto.LoginReq) => {
        params.GUID = v4()
        await login({
            data: params,
            success: async (res) => {
                const encryptedData = encryptAES(JSON.stringify(params)) // 数据加密
                localData.setValue('autoLoginEncryptedData', encryptedData)
                loginStore.$setState((state) => {
                    state.loginInfo = res
                })
                localStorage.setItem('thj_loginId', formData.LoginID) // 记住登录ID
            }
        })
        await loadUserData()
        eventBus.$emit('LoginNotify') // 登录成功通知
    }

    // 初始化业务数据
    const initBaseData = async (autoLogin = false) => {
        logining.value = true
        try {
            // 等待加载业务数据
            await loadBaseData()
            // 自动登录
            if (autoLogin) {
                const encryptedData = localData.getValue('autoLoginEncryptedData')
                if (encryptedData) {
                    try {
                        const decryptedString = decryptAES(encryptedData)
                        return await loginAction(JSON.parse(decryptedString))
                    } catch (err) {
                        console.error(err)
                        eventBus.$emit('LogoutNotify')
                    }
                }
            }
            if (token.value) {
                await loadUserData()
            }
        } finally {
            logining.value = false
        }
    }

    // 用户登录
    const userLogin = async (clientType: ClientType) => {
        logining.value = true
        formData.ClientType = clientType
        try {
            const params = { ...formData }
            await loadBaseData()
            await queryLoginId({
                username: formData.LoginID
            }).then((res) => {
                params.LoginID = res.data
                params.LoginPWD = cryptojs.SHA256(res.data + formData.LoginPWD).toString()
            })
            return await loginAction(params)
        } finally {
            logining.value = false
        }
    }

    // 用户登出
    const userLogout = (callback?: () => void) => {
        socket.closeAll()
        timerTask.clearAll()
        sessionData.reset()
        localData.reset('autoLoginEncryptedData')
        callback && callback()
    }

    return {
        logining,
        formData,
        initBaseData,
        userLogin,
        userLogout,
    }
}