<template>
    <view class="bg-white login flex flex-col items-center px-[40rpx] box-border mt-[100rpx]">
        <view>
            <u-image :src="appStore.config.website.logo" mode="widthFix" height="240" width="240" />
        </view>
        <view class="mt-4 text-[36rpx] font-medium">{{ appStore.config.website.name }}</view>
        <view class="w-full">
            <!-- 账号登录 -->
            <u-form borderBottom>
                <!-- #ifdef MP-WEIXIN || H5 -->
                <!-- 当前只支持微信登陆 或 手机登陆， 而注册只支持微信注册 -->
                <view class="mt-[0rpx]" v-if="isOpenOtherAuth &&
                    isWeixin &&
                    !(loginWay == LoginWayEnum.MOBILE && includeLoginWay(LoginWayEnum.MOBILE))
                    ">
                    <view class="weixinLogin bg-primary flex justify-center items-center mt-[80rpx] mb-[40rpx] h-[100rpx] rounded-[50rpx]">
                        <view v-if="includeAuthWay(LoginAuthEnum.WX) && isWeixin" class="flex flex-col items-center">
                            <!-- <view class="text-lg text-white leading-[80rpx] h-[80rpx]">
                                微信登录
                            </view> -->
                            <u-button :custom-style="btnStyle" :hair-line="false" hover-class="none" class="login-btn"
                                open-type="getPhoneNumber" @getphonenumber="wxLogin" v-show="isCheckAgreement">
                                手机号快捷登录
                            </u-button>
                            <u-button :custom-style="btnStyle" :hair-line="false" hover-class="none" class="login-btn"
                                v-if="!isCheckAgreement" @click="checkAgreement">
                                手机号快捷登录
                            </u-button>
                        </view>
                    </view>
                </view>

                <!-- #endif -->

                <!-- #ifdef MP-TOUTIAO -->
                <view class="mt-[0rpx]" v-if="isOpenOtherAuth &&
                    isWeixin &&
                    !(loginWay == LoginWayEnum.MOBILE && includeLoginWay(LoginWayEnum.MOBILE))
                    ">
                    <view class="weixinLogin bg-primary flex justify-center mt-[80rpx] mb-[40rpx]" @click="dyLogin">
                        <view class="flex flex-col items-center">
                            <view class="text-lg text-white leading-[80rpx] h-[80rpx]">
                                抖音登录
                            </view>
                        </view>
                    </view>
                </view>
                <!-- #endif -->

                <template v-if="loginWay == LoginWayEnum.MOBILE && includeLoginWay(LoginWayEnum.MOBILE)">
                    <u-form-item borderBottom>
                        <u-icon class="mr-2" :size="36" name="/static/images/icon/icon_mobile.png" />
                        <u-input class="flex-1" v-model="formData.mobile" :border="false" placeholder="请输入手机号码" />
                    </u-form-item>
                    <u-form-item borderBottom>
                        <u-icon class="mr-2" :size="36" name="/static/images/icon/icon_code.png" />
                        <u-input class="flex-1" v-model="formData.code" placeholder="请输入验证码" :border="false" />
                        <view class="border-l border-solid border-0 border-light pl-3 leading-4 ml-3 w-[180rpx]"
                            @click="sendSms">
                            <u-verification-code ref="uCodeRef" :seconds="60" @change="codeChange" change-text="x秒" />
                            <text :class="formData.mobile ? 'text-primary' : 'text-muted'">
                                {{ codeTips }}
                            </text>
                        </view>
                    </u-form-item>
                </template>
            </u-form>
            <view class="mt-[60rpx]" v-if="loginWay == LoginWayEnum.MOBILE">
                <u-button type="primary" shape="circle" @click="handleLogin(formData.scene)">
                    登 录
                </u-button>
            </view>
            <view class="text-content flex justify-center items-center mt-[40rpx]">
                <view class="items-center justify-center">
                    <!-- #ifdef MP-TOUTIAO -->
                    <view v-if="loginWay == LoginWayEnum.MOBILE && includeLoginWay(LoginWayEnum.ACCOUNT)
                        " @click="changeLoginWay(LoginTypeEnum.ACCOUNT, LoginWayEnum.ACCOUNT)">
                        抖音登录
                    </view>
                    <!-- #endif -->
                    <!-- #ifndef MP-TOUTIAO -->
                    <view v-if="loginWay == LoginWayEnum.MOBILE && includeLoginWay(LoginWayEnum.ACCOUNT)
                        " @click="changeLoginWay(LoginTypeEnum.ACCOUNT, LoginWayEnum.ACCOUNT)">
                        快捷登录
                    </view>
                    <!-- #endif -->

                    <!-- <view
                        v-if="
                            loginWay == LoginWayEnum.ACCOUNT && includeLoginWay(LoginWayEnum.MOBILE)
                        "
                        @click="changeLoginWay(LoginTypeEnum.MOBILE, LoginWayEnum.MOBILE)"
                    >
                        短信验证码登录
                    </view> -->
                </view>

                <!-- <navigator url="/pages/register/register" hover-class="none">注册账号</navigator> -->
            </view>
        </view>
    </view>
    <view class="agreement" v-if="isOpenAgreement" data-name="wrapper" @click.prevent="handleAgreement">
        <u-checkbox v-model="isCheckAgreement" shape="circle">
            <view class="flex text-[36rpx]">
                同意
                <view @click.stop>
                    <navigator class="text-primary" hover-class="none" url="/pages/agreement/agreement?type=service">
                        《服务协议》
                    </navigator>
                </view>

                和
                <view @click.stop>
                    <navigator class="text-primary" hover-class="none" url="/pages/agreement/agreement?type=privacy">
                        《隐私协议》
                    </navigator>
                </view>
            </view>
        </u-checkbox>
        <mplogin-popup v-model:show="showLoginPopup" :logo="websiteConfig.logo" :title="websiteConfig.name"
            @update="handleUpdateUser" />
    </view>
</template>

<script setup lang="ts">
import { login } from '@/api/account'
import { smsSend } from '@/api/app'
import { SMSEnum } from '@/enums/appEnums'
import { updateUser } from '@/api/user'
import { BACK_URL } from '@/enums/cacheEnums'
import { useLockFn } from '@/hooks/useLockFn'
import { useAppStore } from '@/stores/app'
import { useUserStore } from '@/stores/user'
import cache from '@/utils/cache'
import { isWeixinClient } from '@/utils/client'
import { currentPage } from '@/utils/util'
// #ifdef H5
import wechatOa from '@/utils/wechat'
// #endif
import { onLoad, onShow } from '@dcloudio/uni-app'
import { computed, reactive, ref, shallowRef, watch } from 'vue'
// import { onClickOutside } from '@vueuse/core'

enum LoginTypeEnum {
    MOBILE = 'mobile',
    ACCOUNT = 'account',
    MNP = 'mnp',
    DY = 'byte'
}

enum LoginWayEnum {
    ACCOUNT = 1,
    MOBILE = 2
}

enum LoginAuthEnum {
    WX = 1,
    QQ = 2
}
const isWeixin = ref(true)
// #ifdef H5
isWeixin.value = isWeixinClient()
// #endif

const userStore = useUserStore()
const appStore = useAppStore()

const uCodeRef = shallowRef()
const loginWay = ref<LoginWayEnum>()
const codeTips = ref('')
const showLoginPopup = ref(false)
const isCheckAgreement = ref(false)
const loginData = ref()
const wxLoginCode = ref()

const formData = reactive({
    scene: '',
    username: '',
    password: '',
    code: '',
    mobile: '',
    nickName: '',
    avatarUrl: ''
})

const codeChange = (text: string) => {
    codeTips.value = text
}

const websiteConfig = computed(() => appStore.getWebsiteConfig)
/**点击空白处 */
const handleAgreement = (e) => {
    if (e.target.dataset.name) {
        isCheckAgreement.value = !isCheckAgreement.value
    }
}
const sendSms = async () => {
    if (!formData.mobile) return
    if (uCodeRef.value?.canGetCode) {
        await smsSend({
            scene: SMSEnum.LOGIN,
            mobile: formData.mobile
        })
        uni.$u.toast('发送成功')
        uCodeRef.value?.start()
    }
}

const changeLoginWay = (type: LoginTypeEnum, way: LoginWayEnum) => {
    formData.scene = type
    loginWay.value = way
}

const includeLoginWay = (way: LoginWayEnum) => {
    return appStore.getLoginConfig.loginWay.includes(way)
}

const includeAuthWay = (way: LoginAuthEnum) => {
    return appStore.getLoginConfig.autoLoginAuth.includes(way)
}

const isOpenAgreement = computed(() => appStore.getLoginConfig.openAgreement == 1)

const isOpenOtherAuth = computed(() => appStore.getLoginConfig.openOtherAuth == 1)
const isForceBindMobile = computed(() => appStore.getLoginConfig.forceBindMobile == 1)

const loginFun = async (scene: LoginTypeEnum, code?: string) => {
    if (!isCheckAgreement.value && isOpenAgreement.value)
        return uni.$u.toast('请勾选已阅读并同意《服务协议》和《隐私协议》')
    if (scene == LoginTypeEnum.ACCOUNT) {
        if (!formData.username) return uni.$u.toast('请输入账号/手机号码')
        if (!formData.password) return uni.$u.toast('请输入密码')
    }
    if (scene == LoginTypeEnum.MOBILE) {
        if (!formData.mobile) return uni.$u.toast('请输入手机号码')
        if (!formData.code) return uni.$u.toast('请输入验证码')
    }
    const params = {
        ...formData,
        scene
    }
    if (code) params.code = code
    uni.showLoading({
        title: '请稍后...'
    })
    try {
        const data = await login(params)
        loginHandle(data)
    } catch (error: any) {
        uni.hideLoading()
        uni.$u.toast(error)
    }
}

/**
 * 登录处理
 * @param data 
 */
const loginHandle = async (data: any) => {
    // 从数据中取出token和是否绑定手机标志
    const { token, isBindMobile } = data

    // 如果未绑定手机且需要强制绑定,则跳转到绑定页
    if (!isBindMobile && isForceBindMobile.value) {
        userStore.temToken = token
        uni.navigateTo({
            url: '/pages/bind_mobile/bind_mobile'
        })
        uni.hideLoading()
        return
    }

    // 保存登录的token
    userStore.login(data.token)

    // 获取用户信息
    await userStore.getUser()
    // #ifdef MP-WEIXIN
    /**绑定分销人员 */
    if (userStore.distId == 0 || userStore.distId) {
        userStore.bindingDistId()
    }
    // #endif

    // 显示登录成功提示
    uni.$u.toast('登录成功')

    // 隐藏登录加载框
    uni.hideLoading()
    // 如果有登录前要打开的页面,则跳转到该页面
    if (cache.get(BACK_URL)) {
        uni.redirectTo({ url: cache.get(BACK_URL) })
    }
    // 如果不在首页,则返回上一页
    else if (getCurrentPages().length > 1) {
        uni.navigateBack({
            success: () => {
                // @ts-ignore
                const { onLoad, options } = currentPage()
                // 刷新上一个页面
                onLoad && onLoad(options)
            }
        })
    }

    // 否则跳转到首页
    else {
        uni.reLaunch({
            url: '/pages/index/index'
        })
    }
    cache.remove(BACK_URL)
}

const { lockFn: handleLogin } = useLockFn(loginFun)

/**
 * 微信获取手机号码快捷登录
 */
const { lockFn: wxLogin } = useLockFn(async (e) => {
    if (e.detail.errMsg === 'getPhoneNumber:ok') {
        try {
            // #ifdef MP-WEIXIN
            uni.showLoading({
                title: '请稍后...'
            })

            // 获取登录code
            const { code }: any = await uni.login({
                provider: 'weixin'
            })

            // 调用登录接口
            const data = await login({
                code: wxLoginCode.value,
                scene: LoginTypeEnum.MNP,
                iv: e.detail.iv,
                encryptedData: e.detail.encryptedData
            })

            // 保存登录数据
            loginData.value = data

            // 如果是初次登录
            if (data.isNew) {
                uni.hideLoading()
                userStore.temToken = data.token
                showLoginPopup.value = true
                return
            }

            // 登录处理
            loginHandle(data)
            // #endif
            // #ifdef H5
            if (isWeixin.value) {
                wechatOa.getUrl()
            }
            // #endif
        } catch (error) {
            uni.$u.toast(error)
        }
    } else {
        return
    }
})

// #ifdef MP-TOUTIAO

/**
 * 获取用户信息后登录
 * @param {string} code - 登录code
 */
const getUserProfile = async code => {
    // 调用微信接口获取用户信息
    tt.getUserInfo({
        // 需要使用带sessionId的cookie
        withCredentials: true,
        // 强制获取用户信息,不弹窗
        force: true,
        success(res) {
            // 获取到的用户信息
            const userInfo = res.userInfo
            // console.log(`getUserInfo 调用成功 ${userInfo}`)

            // 设置用户昵称和头像
            formData.nickName = userInfo?.nickName
            formData.avatarUrl = userInfo?.avatarUrl
        },

        fail(res) {
            console.log(`getUserInfo 调用失败`, res)
        },

        // 获取用户信息完成后,进行登录
        complete() {
            handleLogin(LoginTypeEnum.DY, code)
        }
    })
}

const dyLogin = async () => {
    // /api/byte/jsConfig  appId和secret是多少
    // /api/login/check
    tt.login({
        force: true,
        success(res) {
            const { code, errMsg, anonymousCode, isLogin } = res
            console.log(`tt-login success`, errMsg)
            console.log(`code(临时登录凭证, 有效期 3 分钟) : `, code)
            console.log(
                `anonymousCode(用于标识当前设备, 无论登录与否都会返回, 有效期 3 分钟) : `,
                anonymousCode
            )
            console.log(`isLogin(判断在当前 APP（头条、抖音等）是否处于登录状态) : `, isLogin)
            console.log('登录成功')

            if (isLogin) {
                getUserProfile(code)
            } else {
                uni.$u.toast('请先登录抖音宿主账号！')
            }

            // 获取用户信息再登录
            // 直接登录
            // handleLogin(LoginTypeEnum.DY, code)
        },
        fail(err) {
            console.log(`tt-login failed`, err.errMsg)
        },
        complete(res) {
            console.log(`tt-login completed`)
        }
    })
}
// #endif

const handleUpdateUser = async (value: any) => {
    await updateUser(value, { token: userStore.temToken })
    showLoginPopup.value = false
    loginHandle(loginData.value)
}

watch(
    () => appStore.getLoginConfig,
    value => {
        if (value.loginWay) {
            loginWay.value = value.loginWay[0]
            //@ts-ignore
            formData.scene = LoginTypeEnum[LoginWayEnum[loginWay.value]]
        }
    },
    {
        immediate: true
    }
)

onShow(async () => {
    try {
        //
        if (userStore.isLogin) {
            uni.showLoading({
                title: '请稍后...'
            })
            await userStore.getUser()
            uni.hideLoading()
            uni.navigateBack()
        }
    } catch (error: any) {
        uni.hideLoading()
    }
})

onLoad(async options => {
    if (userStore.isLogin) {
        // 已经登录 => 首页
        uni.reLaunch({
            url: '/pages/index/index'
        })
        return
    }

    uni.login({
        provider: 'weixin',
        success: function (loginRes) {
            // 用户code
            console.log('登录', loginRes.code)
            wxLoginCode.value = loginRes.code
        }
    })

    // #ifdef H5
    const { code } = options
    if (code) {
        uni.showLoading({
            title: '请稍后...'
        })

        try {
            const data = await wechatOa.authLogin(code)
            loginHandle(data)
        } catch (error: any) {
            uni.hideLoading()
            throw new Error(error)
        }
    }
    // #endif
})

const checkAgreement = () => {
    uni.$u.toast('请勾选已阅读并同意《服务协议》和《隐私协议》')
}

// 微信登陆u-button的风格
const btnStyle = ref()
btnStyle.value = {
    background: 'transparent',
    color: '#fff',
    border: 'none',
    outline: 'none',
    width: '600rpx',
}
</script>

<style lang="scss">
page {
    height: 100vh;
    background: #fff;
    position: absolute;
    top: 60%;
    transform: translateY(-55%);
    overflow: hidden;
}

.weixinLogin {
    width: 100%;
    // border-radius: 40rpx;
}

.agreement {
    // position: fixed;
    // bottom: 48rpx;
    display: flex;
    justify-content: center;
    align-items: center;
    // height: 126rpx;
    width: 750rpx;
    z-index: 99;
    font-size: 50rpx;
}
.rounded {
    border-radius: 50rpx;
    font-size: 44rpx;
}
:deep(.login-btn) {
    .u-btn {
        font-size: 36rpx!important;
    }
}
</style>
