import { reactive, shallowRef } from 'vue'
import { timerTask } from '@/utils/timer'
import { getCheckSign } from '@/services/api/common'
import { login, loginIn, checkToken } from '@/services/api/user'
import { useLoginStore, useUserStore, useRouterStore } from '@/stores'
import service from '@/services'
import tradeSocket from '@/services/websocket/trade'
import quoteSocket from '@/services/websocket/quote'
import eventBus from '@/services/bus'
import cryptojs from 'crypto-js'

/**
 * 登录业务
 * @returns 
 */
export function useLogin() {
    const loginStore = useLoginStore()
    const userStore = useUserStore()
    const routerStore = useRouterStore()
    const loading = shallowRef(false)

    const formData = reactive<Model.LoginInReq>({
        accountCode: localStorage.getItem('app_loginName') ?? '',
        password: '',
        key: '',
        verifyCode: ''
    })

    // 加载初始数据
    const loadBaseData = async () => {
        await service.onReady() // 等待服务初始化
        await getCheckSign().then((res) => {
            loginStore.setSecretkey(res.data)
        })
    }

    // 加载用户数据
    const loadUserData = async () => {
        await Promise.all([
            routerStore.getUserRoutes()
        ])
        // 这里可以加载登录后的数据
        eventBus.$emit('Login') // 登录成功通知
    }

    // 用户登录
    const userLogin = async (autoLogin = false) => {
        try {
            loading.value = true
            const payload = await new Promise<Model.LoginReq>((resolve, reject) => {
                if (autoLogin) {
                    const params = loginStore.getAutoLoginData()
                    if (params) {
                        resolve(params)
                    } else {
                        reject('自动登录失败')
                    }
                } else {
                    resolve({
                        username: formData.accountCode,
                        password: cryptojs.SHA256(formData.accountCode + formData.password).toString()
                    })
                }
            })
            await loadBaseData()
            await login({
                data: payload
            }).then(async (res) => {
                loginStore.setToken(res.data)
                await loginIn({
                    data: {
                        ...formData,
                        password: payload.password
                    }
                }).then(async (res) => {
                    loginStore.setAutoLoginData(payload)
                    userStore.setLoginInfo(res.data)
                    localStorage.setItem('app_loginName', payload.username) // 记住登录名
                    await loadUserData()
                })
            })
        } finally {
            loading.value = false
        }
    }

    // 用户登出
    const userLogout = (callback?: () => void) => {
        tradeSocket.close()
        quoteSocket.close()
        timerTask.clearAll()
        loginStore.clearAutoLoginData()
        loginStore.clearLoginInfo()
        callback && callback()
    }

    // 初始化业务数据
    const initBaseData = async (autoLogin = false) => {
        try {
            loading.value = true
            await loadBaseData()
            await checkToken().then(async () => {
                await loadUserData()
            }).catch(async () => {
                if (autoLogin && loginStore.getAutoLoginData()) {
                    await userLogin(true)
                } else {
                    loginStore.clearLoginInfo()
                }
            })
        } finally {
            loading.value = false
        }
    }

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