﻿<template>
    <!-- 登录弹窗组件 -->
    <view class="login-modal-mask" v-if="visible" @tap="handleMaskTap">
        <view class="login-modal" :class="{ 'login-modal--center': modalStyle === 'center' }" @tap.stop>
            <!-- 关闭按钮 -->
            <view class="login-modal__close" v-if="showClose" @tap="handleClose">
                <text class="icon-close">×</text>
            </view>

            <!-- 弹窗内容 -->
            <view class="login-modal__content">
                <!-- 头部 -->
                <view class="login-modal__header">
                    <view class="logo-wrapper">
                        <image class="logo-image" src="/static/logo.png" mode="aspectFit" />
                        <text class="app-name">活氧舱</text>
                    </view>
                    <text class="modal-title">{{ title }}</text>
                    <text class="modal-subtitle">{{ subtitle }}</text>
                </view>

                <!-- 一键登录卡片 -->
                <view class="login-card" :class="{ active: activeCard === 'phone' }">
                    <view class="card-body">
                        <text class="card-title">本机号码登录</text>
                        <text class="auth-tip">认证服务由中国移动提供</text>

                        <button class="login-btn primary" :class="{ disabled: isLoading, loading: isLoading }"
                            @tap="handlePhoneLogin" :disabled="isLoading">
                            <text>{{ isLoading ? '登录中...' : '一键登录' }}</text>
                        </button>

                        <button class="login-btn switch-btn" @tap="switchToSms">
                            <text>短信验证码登录</text>
                        </button>
                    </view>
                </view>

                <!-- 短信验证码登录卡片 -->
                <view class="login-card sms-card" :class="{ active: activeCard === 'sms' }">
                    <view class="card-body">
                        <text class="card-title">验证码登录</text>
                        <text class="auth-tip">认证服务由中国移动提供</text>

                        <view class="form-group">
                            <view class="input-wrapper" :class="{ focused: isPhoneFocused }">
                                <input v-model="smsPhone" type="number" placeholder="请输入手机号" maxlength="11"
                                    class="phone-input" confirm-type="next" @focus="isPhoneFocused = true"
                                    @blur="isPhoneFocused = false" />
                            </view>
                        </view>

                        <view class="form-group">
                            <view class="input-wrapper code-input" :class="{ focused: isCodeFocused }">
                                <input v-model="smsCode" type="number" placeholder="请输入验证码" maxlength="6"
                                    class="phone-input" confirm-type="done" @focus="isCodeFocused = true"
                                    @blur="isCodeFocused = false" />
                                <button class="send-code-btn" :class="{ disabled: countdown > 0 || isLoading }"
                                    @tap="handleSendCode" :disabled="countdown > 0 || isLoading">
                                    <text>{{ countdown > 0 ? `${countdown}秒后重发` : '发送验证码' }}</text>
                                </button>
                            </view>
                        </view>

                        <button class="login-btn primary" :class="{ disabled: !canSmsSubmit, loading: isLoading }"
                            @tap="handleSmsLogin" :disabled="!canSmsSubmit || isLoading">
                            <text>{{ isLoading ? '登录中...' : '登录' }}</text>
                        </button>

                        <button class="login-btn switch-btn" @tap="switchToPhone">
                            <text>一键登录</text>
                        </button>
                    </view>
                </view>

                <!-- 协议 -->
                <view class="agreement-text">
                    <checkbox-group @change="onAgreementChange">
                        <checkbox :checked="agreed" value="agreed" color="#FF8C42" />
                    </checkbox-group>
                    <text>登录即表示同意</text>
                    <text class="link" @tap="showAgreement">《用户协议》</text>
                    <text>和</text>
                    <text class="link" @tap="showPrivacy">《隐私政策》</text>
                </view>
            </view>
        </view>

        <!-- Toast提示 -->
        <view class="custom-toast" :class="{ show: toastShow }">
            <text class="toast-text">{{ toastMessage }}</text>
        </view>
    </view>
</template>

<script setup>
import { ref, computed, watch } from 'vue'
import { oneClickLogin, loginWithPhone, sendCode } from '@/api/main.js'

// Props定义
const props = defineProps({
    // 是否显示弹窗
    modelValue: {
        type: Boolean,
        default: false
    },
    // 弹窗标题
    title: {
        type: String,
        default: '登录后享受更多服务'
    },
    // 弹窗副标题
    subtitle: {
        type: String,
        default: '登录即表示同意相关协议'
    },
    // 是否显示关闭按钮
    showClose: {
        type: Boolean,
        default: true
    },
    // 弹窗样式: 'center'居中, 'bottom'底部
    modalStyle: {
        type: String,
        default: 'center'
    },
    // 是否点击遮罩层关闭
    maskClosable: {
        type: Boolean,
        default: true
    },
    // 登录成功回调
    onLoginSuccess: {
        type: Function,
        default: null
    },
    // 登录失败回调
    onLoginError: {
        type: Function,
        default: null
    }
})

// Emits定义
const emit = defineEmits(['update:modelValue', 'loginSuccess', 'loginError', 'close'])

// 响应式状态
const visible = ref(false)
const activeCard = ref('phone') // 'phone'一键登录, 'sms'验证码登录
const isLoading = ref(false)
const isPhoneFocused = ref(false)
const isCodeFocused = ref(false)
const smsPhone = ref('')
const smsCode = ref('')
const countdown = ref(0)
const agreed = ref(false)
const toastShow = ref(false)
const toastMessage = ref('')

// 计算属性
const canSmsSubmit = computed(() => {
    return smsPhone.value.length === 11 && smsCode.value.length === 6 && agreed.value
})

// 监听modelValue变化
watch(() => props.modelValue, (newVal) => {
    visible.value = newVal
    if (newVal) {
        // 打开弹窗时重置状态
        resetState()
    }
}, { immediate: true })

// 重置状态
function resetState() {
    activeCard.value = 'phone'
    isLoading.value = false
    smsPhone.value = ''
    smsCode.value = ''
    countdown.value = 0
    agreed.value = false
}

// 显示Toast
function showToast(message, duration = 2000) {
    toastMessage.value = message
    toastShow.value = true
    setTimeout(() => {
        toastShow.value = false
    }, duration)
}

// 显示用户协议
function showAgreement() {
    uni.showModal({
        title: '用户协议',
        content: '这里是用户协议内容...',
        showCancel: false
    })
}

// 显示隐私政策
function showPrivacy() {
    uni.showModal({
        title: '隐私政策',
        content: '这里隐私政策内容...',
        showCancel: false
    })
}

// 切换到短信登录
function switchToSms() {
    activeCard.value = 'sms'
}

// 切换到一键登录
function switchToPhone() {
    activeCard.value = 'phone'
}

// 协议勾选变化
function onAgreementChange(e) {
    agreed.value = e.detail.value.includes('agreed')
}

// 发送验证码
async function handleSendCode() {
    if (countdown.value > 0 || isLoading.value) return

    if (!smsPhone.value || smsPhone.value.length !== 11) {
        showToast('请输入正确的手机号')
        return
    }

    if (!agreed.value) {
        showToast('请先同意用户协议')
        return
    }

    isLoading.value = true
    try {
        await sendCode({ phone: smsPhone.value })
        showToast('验证码已发送')
        countdown.value = 60
        const timer = setInterval(() => {
            countdown.value--
            if (countdown.value <= 0) {
                clearInterval(timer)
            }
        }, 1000)
    } catch (e) {
        console.error('发送验证码失败:', e)
        showToast(e.message || '发送验证码失败')
    } finally {
        isLoading.value = false
    }
}

// 一键登录
async function handlePhoneLogin() {
    if (isLoading.value) return

    if (!agreed.value) {
        showToast('请先同意用户协议')
        return
    }

    isLoading.value = true

    try {
        // #ifdef APP-PLUS
        // App环境下使用一键登录
        await new Promise((resolve, reject) => {
            uni.login({
                provider: 'univerify',
                univerifyStyle: {
                    fullScreen: false,
                    backgroundColor: '#ffffff',
                    icon: {
                        path: '/static/logo.png'
                    },
                    closeIcon: {
                        path: '/static/close.png'
                    },
                    phoneNum: {
                        color: '#333333',
                        fontSize: '18px'
                    },
                    slogan: {
                        color: '#999999',
                        fontSize: '12px'
                    },
                    authButton: {
                        normalColor: '#FF8C42',
                        highlightColor: '#FF7A2C',
                        disabledColor: '#CCCCCC',
                        textColor: '#FFFFFF',
                        title: '本机号码一键登录'
                    },
                    otherLoginButton: {
                        visible: false
                    },
                    protocols: []
                },
                success: async (res) => {
                    try {
                        // 调用后端API进行一键登录
                        const result = await oneClickLogin({
                            accessToken: res.authResult.access_token,
                            openid: res.authResult.openid
                        })

                        if (result.code === 200 || result.data) {
                            handleLoginSuccess(result)
                            resolve(result)
                        } else {
                            reject(new Error(result.message || '登录失败'))
                        }
                    } catch (e) {
                        reject(e)
                    }
                },
                fail: (err) => {
                    console.error('一键登录失败:', err)
                    reject(new Error(err.errMsg || '一键登录失败'))
                }
            })
        })
        // #endif

        // #ifndef APP-PLUS
        // 非App环境（小程序、H5等）提示使用其他方式
        uni.showToast({
            title: '请使用短信验证码登录',
            icon: 'none'
        })
        activeCard.value = 'sms'
        // #endif

    } catch (e) {
        console.error('一键登录失败:', e)
        showToast(e.message || '一键登录失败')
        if (props.onLoginError) {
            props.onLoginError(e)
        }
        emit('loginError', e)
    } finally {
        isLoading.value = false
    }
}

// 短信验证码登录
async function handleSmsLogin() {
    if (!canSmsSubmit.value || isLoading.value) return

    isLoading.value = true

    try {
        const result = await loginWithPhone({
            phone: smsPhone.value,
            code: smsCode.value
        })

        handleLoginSuccess(result)

    } catch (e) {
        console.error('短信登录失败:', e)
        showToast(e.message || '登录失败')
        if (props.onLoginError) {
            props.onLoginError(e)
        }
        emit('loginError', e)
    } finally {
        isLoading.value = false
    }
}

// 处理登录成功
function handleLoginSuccess(result) {
    console.log('登录成功:', result)
    // 保存token和用户信息到本地缓存
    if (result.data?.token) {
        uni.setStorageSync('token', result.data.token)
    }
    // 直接缓存登录响应数据
    if (result.data) {
        uni.setStorageSync('loginMemberInfo', result.data)
    }

    showToast('登录成功')

    if (props.onLoginSuccess) {
        props.onLoginSuccess(result)
    }
    emit('loginSuccess', result)

    uni.$emit('loginModal:success', result)

    setTimeout(() => {
        handleClose()
    }, 1500)
}

// 关闭弹窗
function handleClose() {
    visible.value = false
    emit('update:modelValue', false)
    emit('close')

    uni.$emit('loginModal:close')
}

// 点击遮罩层
function handleMaskTap() {
    if (props.maskClosable) {
        handleClose()
    }
}

// 对外暴露的方法
defineExpose({
    // 显示弹窗
    show() {
        visible.value = true
        emit('update:modelValue', true)
    },
    // 隐藏弹窗
    hide() {
        handleClose()
    },
    // 切换登录方式
    switchCard(card) {
        activeCard.value = card
    }
})
</script>

<style lang="scss" scoped>
.login-modal-mask {
    position: fixed;
    top: 0;
    left: 0;
    right: 0;
    bottom: 0;
    background: rgba(0, 0, 0, 0.5);
    z-index: 9999;
    display: flex;
    align-items: center;
    justify-content: center;
}

.login-modal {
    position: relative;
    width: 90%;
    max-width: 650rpx;
    background: #fff;
    border-radius: 24rpx;
    overflow: hidden;
    box-shadow: 0 20rpx 60rpx rgba(0, 0, 0, 0.15);

    &--center {
        display: flex;
        flex-direction: column;
        align-items: center;
    }
}

.login-modal__close {
    position: absolute;
    top: 20rpx;
    right: 20rpx;
    width: 50rpx;
    height: 50rpx;
    display: flex;
    align-items: center;
    justify-content: center;
    z-index: 10;

    .icon-close {
        font-size: 48rpx;
        color: #999;
        line-height: 1;
    }
}

.login-modal__content {
    width: 100%;
    padding: 40rpx 50rpx 50rpx;
}

.login-modal__header {
    display: flex;
    flex-direction: column;
    align-items: center;
    margin-bottom: 40rpx;
}

.logo-wrapper {
    display: flex;
    align-items: center;
    gap: 16rpx;
    margin-bottom: 20rpx;

    .logo-image {
        width: 80rpx;
        height: 80rpx;
        border-radius: 16rpx;
    }

    .app-name {
        font-size: 36rpx;
        font-weight: 600;
        color: #333;
    }
}

.modal-title {
    font-size: 32rpx;
    font-weight: 600;
    color: #333;
    margin-bottom: 8rpx;
}

.modal-subtitle {
    font-size: 24rpx;
    color: #999;
}

.login-card {
    display: none;

    &.active {
        display: block;
    }
}

.sms-card {
    display: none;

    &.active {
        display: block;
    }
}

.card-body {
    display: flex;
    flex-direction: column;
    gap: 24rpx;
}

.card-title {
    font-size: 30rpx;
    font-weight: 600;
    color: #333;
    text-align: center;
}

.auth-tip {
    font-size: 22rpx;
    color: #999;
    text-align: center;
}

.form-group {
    width: 100%;
}

.input-wrapper {
    width: 100%;
    height: 88rpx;
    background: #F5F7FA;
    border-radius: 16rpx;
    border: 2rpx solid transparent;
    display: flex;
    align-items: center;
    padding: 0 24rpx;
    box-sizing: border-box;
    transition: all 0.3s;

    &.focused {
        border-color: #FF8C42;
        background: #fff;
    }
}

.phone-input {
    flex: 1;
    height: 100%;
    font-size: 28rpx;
    color: #333;
}

.code-input {
    padding-right: 0;

    .phone-input {
        width: 55%;
    }
}

.send-code-btn {
    width: 40%;
    height: 64rpx;
    line-height: 64rpx;
    background: #FF8C42;
    color: #fff;
    font-size: 24rpx;
    border-radius: 8rpx;
    padding: 0;
    margin: 0;

    &.disabled {
        background: #ccc;
    }

    &::after {
        border: none;
    }
}

.login-btn {
    width: 100%;
    height: 88rpx;
    line-height: 88rpx;
    border-radius: 44rpx;
    font-size: 32rpx;
    font-weight: 600;
    padding: 0;
    margin: 0;

    &.primary {
        background: linear-gradient(135deg, #FF8C42 0%, #FF6B2C 100%);
        color: #fff;
        border: none;
    }

    &.disabled {
        background: #ccc;
        color: #fff;
    }

    &.loading {
        opacity: 0.8;
    }

    &.switch-btn {
        background: transparent;
        color: #FF8C42;
        border: 2rpx solid #FF8C42;
    }

    &::after {
        border: none;
    }
}

.agreement-text {
    display: flex;
    align-items: center;
    justify-content: center;
    flex-wrap: wrap;
    gap: 8rpx;
    margin-top: 24rpx;
    font-size: 22rpx;
    color: #999;

    .link {
        color: #FF8C42;
    }
}

.custom-toast {
    position: fixed;
    top: 50%;
    left: 50%;
    transform: translate(-50%, -50%) scale(0);
    background: rgba(0, 0, 0, 0.8);
    color: #fff;
    padding: 24rpx 48rpx;
    border-radius: 12rpx;
    font-size: 28rpx;
    z-index: 99999;
    opacity: 0;
    transition: all 0.3s;

    &.show {
        transform: translate(-50%, -50%) scale(1);
        opacity: 1;
    }
}
</style>
