<template>
    <div class="login">
        <div class="top-bg"></div>
        <div class="login-con">
            <span class="login-title">欢迎登录后台管理系统</span>
            <el-form
                ref="loginFormRef"
                :model="loginForm"
                :rules="loginRules"
                class="login-container"
                auto-complete="on"
                label-position="left"
            >
                <div class="title">iBit 让数字生活更美好</div>
                <div class="label-name">用户名</div>
                <el-form-item prop="username">
                    <el-input
                        ref="username"
                        v-model="loginForm.username"
                        placeholder="请输入您的用户名"
                        name="username"
                        type="text"
                        tabindex="1"
                        auto-complete="on"
                        clearable
                    >
                    </el-input>
                </el-form-item>
                <div class="label-name">密码</div>
                <el-tooltip
                    :disabled="capslockTooltipDisabled"
                    content="Caps lock is On"
                    placement="right"
                >
                    <el-form-item prop="password">
                        <el-input
                            ref="passwordRef"
                            :key="passwordType"
                            v-model="loginForm.password"
                            :type="passwordType"
                            placeholder="请输入您的密码"
                            name="password"
                            tabindex="2"
                            auto-complete="on"
                            @keyup="checkCapslock"
                            @blur="capslockTooltipDisabled = true"
                            @keyup.enter="handleLogin"
                        />
                        <span class="show-pwd" @click="showPwd">
                            <svg-icon
                                :icon-class="
                                    passwordType === 'password'
                                        ? 'eye'
                                        : 'eye-open'
                                "
                            />
                        </span>
                    </el-form-item>
                </el-tooltip>
                <!-- 验证码 -->
                <div class="label-name">验证码</div>
                <el-form-item prop="captcha">
                    <el-input
                        v-model="loginForm.captcha"
                        auto-complete="off"
                        placeholder="请输入验证码"
                        style="width: 58%"
                        @keyup.enter="handleLogin"
                    />
                    <div class="captcha">
                        <img :src="captchaImg" @click="handleCaptchaGenerate" />
                    </div>
                </el-form-item>
                <el-button
                    size="default"
                    :loading="loading"
                    type="primary"
                    class="login-btn"
                    @click.prevent="handleLogin"
                    >登 录
                </el-button>
                <div class="borderInner"></div>
                <div class="login-container_2"></div>
                <div class="login-container_3"></div>
                <div class="login-container_5"></div>
            </el-form>
        </div>
    </div>

    <!-- 谷歌验证绑定弹窗（未绑定用户登录后展示） -->
    <el-dialog
        v-model="state.bindDialogVisible"
        title="谷歌二次验证绑定"
        width="420px"
        :close-on-click-modal="false"
        :show-close="false"
    >
        <div class="google-dialog">
            <p class="google-tip">为保证账户安全，请完成谷歌验证绑定</p>
            <div class="google-secret-row">
                <span class="secret-label">秘钥：</span>
                <span class="secret-value">{{ state.bindSecret }}</span>
                <el-button link @click="copySecret" style="margin-left:8px">
                    <el-icon><CopyDocument /></el-icon>
                </el-button>
            </div>
            <div class="google-qr" v-if="state.bindQrDataUrl">
                <img :src="state.bindQrDataUrl" alt="QR Code" />
                <div class="qr-label">扫码绑定</div>
            </div>
            <div class="google-input-label">请输入6位数谷歌验证码</div>
            <el-input
                v-model="state.bindGoogleCode"
                placeholder="请输入验证码"
                maxlength="6"
                @keyup.enter="handleBind"
            />
            <el-button
                type="primary"
                class="google-btn"
                :loading="state.bindLoading"
                @click="handleBind"
            >完成绑定</el-button>
            <p class="google-warn">※密钥用于手机更换或遗失时找回验证器，绑定前请务必将上述密钥备份保存。</p>
        </div>
    </el-dialog>

    <!-- 谷歌验证弹窗（已绑定用户登录时二次验证） -->
    <el-dialog
        v-model="state.verifyDialogVisible"
        title="谷歌二次验证"
        width="380px"
        :close-on-click-modal="false"
        :show-close="true"
    >
        <div class="google-dialog">
            <div class="google-input-label">请输入6位数谷歌验证码</div>
            <el-input
                v-model="state.verifyGoogleCode"
                placeholder="请输入验证码"
                maxlength="6"
                @keyup.enter="handleGoogleVerify"
            />
            <el-button
                type="primary"
                class="google-btn"
                :loading="state.verifyLoading"
                @click="handleGoogleVerify"
            >确认</el-button>
        </div>
    </el-dialog>
</template>
<script setup lang="ts">
import { onMounted, reactive, ref, toRefs, watch, nextTick } from "vue";
import QRCode from "qrcode";

// 组件依赖
import { ElForm, ElInput, ElMessage } from "element-plus";
import { CopyDocument } from "@element-plus/icons-vue";
import router from "@/router";
import SvgIcon from "@/components/SvgIcon/index.vue";

// 状态管理依赖
import useStore from "@/store";

// API依赖
import { useRoute } from "vue-router";
import { LoginFormData } from "@/types/api/system/login";
import { getGoogleInfo, bindGoogle } from "@/api/login";
import { localStorage as storage } from "@/utils/storage";

const { user } = useStore();
const route = useRoute();

const loginFormRef = ref(ElForm);
const passwordRef = ref(ElInput);

const state = reactive({
    redirect: "",
    loginForm: {
        username: "",
        password: "",
        captcha: "",
    } as LoginFormData,
    loginRules: {
        username: [{ required: true, trigger: "blur", message: "用户名不能为空" }],
        password: [{ required: true, trigger: "blur", message: "密码不能为空" }],
        captcha: [{ required: true, trigger: "blur", message: "验证码不能为空" }],
    },
    loading: false,
    passwordType: "password",
    captchaImg: `${import.meta.env.VITE_APP_BASE_API || 'https://apitest.coinvisoncex.top/api'}/admin/captcha`,
    capslockTooltipDisabled: true,
    otherQuery: {},
    clientHeight: document.documentElement.clientHeight,

    // 谷歌绑定弹窗（未绑定时登录后展示）
    bindDialogVisible: false,
    bindGoogleCode: "",
    bindSecret: "",
    bindQrDataUrl: "",
    bindLoading: false,

    // 谷歌验证弹窗（已绑定时登录前展示）
    verifyDialogVisible: false,
    verifyGoogleCode: "",
    verifyLoading: false,
});

const {
    loginForm,
    loginRules,
    loading,
    passwordType,
    captchaImg,
    capslockTooltipDisabled,
} = toRefs(state);

function checkCapslock(e: any) {
    const { key } = e;
    state.capslockTooltipDisabled =
        key && key.length === 1 && key >= "A" && key <= "Z";
}

function showPwd() {
    if (state.passwordType === "password") {
        state.passwordType = "";
    } else {
        state.passwordType = "password";
    }
    nextTick(() => {
        passwordRef.value.focus();
    });
}

function handleLogin() {
    if (state.loading) return;
    loginFormRef.value.validate((valid: boolean) => {
        if (valid) {
            state.loading = true;
            user.login(state.loginForm)
                .then((res: any) => {
                    const { googleState, tempToken } = res;
                    if (googleState === 1) {
                        state.loading = false;
                        state.verifyGoogleCode = "";
                        state.verifyDialogVisible = true;
                    } else {
                        user.signIn(tempToken)
                            .then(() => {
                                state.loading = false;
                                loadGoogleBindInfo();
                            })
                            .catch(() => {
                                state.loading = false;
                                handleCaptchaGenerate();
                            });
                    }
                })
                .catch(() => {
                    state.loading = false;
                    handleCaptchaGenerate();
                });
        }
    });
}

// 加载谷歌绑定信息（密钥+二维码）
function loadGoogleBindInfo() {
    getGoogleInfo().then((res: any) => {
        const { secret, qrUrl } = res.data;
        state.bindSecret = secret;
        state.bindGoogleCode = "";
        QRCode.toDataURL(qrUrl, { width: 180, margin: 1 }).then((dataUrl: string) => {
            state.bindQrDataUrl = dataUrl;
            state.bindDialogVisible = true;
        });
    }).catch(() => {
        // 即使获取失败也放行进入系统（旧账号首次升级）
        enterSystem();
    });
}

// 复制密钥
async function copySecret() {
    if (!state.bindSecret) return;
    try {
        await navigator.clipboard.writeText(state.bindSecret);
        ElMessage.success("密钥已复制");
    } catch {
        ElMessage({
            type: 'warning',
            duration: 8000,
            showClose: true,
            dangerouslyUseHTMLString: true,
            message: '剪贴板权限未开启，无法自动复制。<br/>请点击浏览器地址栏左侧的 🔒 图标 → 网站设置 → 将「剪贴板」设为「允许」，然后重新点击复制。'
        });
    }
}

// 提交绑定
function handleBind() {
    if (state.bindLoading) return;
    if (!state.bindGoogleCode) {
        ElMessage.warning("请输入谷歌验证码");
        return;
    }
    state.bindLoading = true;
    bindGoogle(state.bindGoogleCode)
        .then(() => {
            state.bindLoading = false;
            state.bindDialogVisible = false;
            ElMessage.success("谷歌验证绑定成功");
            enterSystem();
        })
        .catch(() => {
            state.bindLoading = false;
        });
}

// 已绑定用户：提交谷歌验证 + tempToken 完成登录
function handleGoogleVerify() {
    if (state.verifyLoading) return;
    if (!state.verifyGoogleCode) {
        ElMessage.warning("请输入谷歌验证码");
        return;
    }
    let tempToken = '';
    try {
        const t = storage.get('tempToken');
        if (typeof t === 'string' && t) {
            tempToken = t;
        }
    } catch {
        tempToken = '';
    }
    if (!tempToken) {
        ElMessage.error("登录会话已过期，请重新验证");
        state.verifyLoading = false;
        state.verifyDialogVisible = false;
        handleCaptchaGenerate();
        return;
    }
    state.verifyLoading = true;
    user.signInWithGoogle(tempToken, state.verifyGoogleCode)
        .then(() => {
            state.verifyLoading = false;
            state.verifyDialogVisible = false;
            enterSystem();
        })
        .catch(() => {
            state.verifyLoading = false;
        });
}

function enterSystem() {
    router.push({ path: state.redirect || "/", query: state.otherQuery });
    window.location.reload();
}

// 获取验证码
function handleCaptchaGenerate() {
    const baseApi = import.meta.env.VITE_APP_BASE_API || 'https://apitest.coinvisoncex.top/api';
    state.captchaImg = `${baseApi}/admin/captcha?t=${Date.now()}&a=${Math.random().toFixed(2)}`;
}

watch(
    route,
    () => {
        const query = route.query;
        if (query) {
            state.redirect = query.redirect as string;
            state.otherQuery = getOtherQuery(query);
        }
    },
    { immediate: true }
);

function getOtherQuery(query: any) {
    return Object.keys(query).reduce((acc: any, cur: any) => {
        if (cur !== "redirect") {
            acc[cur] = query[cur];
        }
        return acc;
    }, {});
}

onMounted(() => {
    handleCaptchaGenerate();
    window.onresize = () => {};
});
</script>

<style lang="scss" scoped>
.login {
    font-family: "PingFang SC";
    width: 100%;
    height: 100%;
    display: flex;
    align-items: center;
    background-image: url("@/assets/login/loginBackground.png");
    background-repeat: no-repeat;
    background-position: center right;
    background-size: 100% 100%;
    .top-bg {
        width: 100%;
        height: 43px;
        background: url("@/assets/login/loginTopLine.png") no-repeat;
        position: absolute;
        top: 0;
        right: 0;
        z-index: 999;
        background-size: 100% 100%;
    }

    &-con {
        display: inline-block;
        margin-top: 5%;
        width: 400px;
        margin: auto;
        background-color: #fff;
        position: relative;
        display: flex;
        flex-direction: column;
        padding: 30px;
        box-shadow: 1px 1px 10px rgba(59, 54, 34, 0.2);
        border-radius: 20px;
        overflow: hidden;
        .login-title {
            color: #121212;
            text-align: center;
            font-size: 18px;
            font-weight: 500;
            margin-bottom: 8px;
        }
        
        .login-container {
            text-align: left;
            width: 100%;
            .label-name {
                font-size: 14px;
                font-weight: 500;
                color: #121212;
                margin-bottom: 8px;
            }
            .captcha {
                width: 38%;
                height: 40px;
                margin-left: 4%;
                img {
                    width: 100%;
                    height: 40px;
                }
            }

            .login-btn {
                width: 100%;
                height: 40px;
                border-radius: 4px;
                margin-top: 8px;
                margin-bottom: 10px;
                font-size: 14px;
                border: 0px;
                font-weight: bold;
                background-color: #121212;
            }
        }

        .title {
            margin: 0px auto 40px auto;
            color: #B8B8B8;
            text-align: center;
            font-size: 14px;
            font-weight: 500;
            letter-spacing: 3px;
        }

        .show-pwd {
            position: absolute;
            right: 0;
            width: 40px;
            height: 32px;
            cursor: pointer;
            text-align: center;
            text-align-last: center;
            vertical-align: middle;
        }

        &-header {
            font-size: 16px;
            font-weight: 300;
            text-align: center;
            padding: 30px 0;
        }

        .form-con {
            padding: 10px 0 0;
        }
    }
}
::v-deep .el-input__wrapper {
    width: 320px;
    height: 40px;
    background: #F7F7F7;
    .el-input__inner {
        color: #121212;
    }
    &.is-focus {
        box-shadow: 0 0 0 1px #121212 inset;
    }
}
::v-deep .el-input .el-input__clear {
    color: #121212;
}
</style>

<style lang="scss">
.google-dialog {
    display: flex;
    flex-direction: column;
    align-items: center;
    gap: 14px;
    padding: 4px 0;

    .google-tip {
        font-size: 13px;
        color: #666;
        margin: 0;
    }

    .google-secret-row {
        display: flex;
        align-items: center;
        background: #f5f5f5;
        padding: 6px 12px;
        border-radius: 6px;
        width: 100%;
        box-sizing: border-box;

        .secret-label { color: #888; font-size: 13px; }
        .secret-value { font-weight: bold; font-size: 14px; letter-spacing: 1px; flex: 1; }
    }

    .google-qr {
        display: flex;
        flex-direction: column;
        align-items: center;
        gap: 6px;

        img { width: 180px; height: 180px; }
        .qr-label { font-size: 12px; color: #999; }
    }

    .google-input-label {
        font-size: 13px;
        color: #333;
        align-self: flex-start;
    }

    .el-input { width: 100%; }
    ::v-deep(.el-input__wrapper) { width: 100%; height: 40px; background: #f7f7f7; }

    .google-btn {
        width: 100%;
        height: 40px;
        background: #121212;
        border-color: #121212;
        font-weight: bold;
    }

    .google-warn {
        font-size: 12px;
        color: #f56c6c;
        margin: 0;
        text-align: left;
        line-height: 1.6;
    }
}
</style>
