<script setup lang="ts">
import { useRouter } from "vue-router";
import { message } from "@/utils/message";
import { useNav } from "@/layout/hooks/useNav";
import { useEventListener } from "@vueuse/core";
import type { FormInstance } from "element-plus";
import { useLayout } from "@/layout/hooks/useLayout";
import { useUserStoreHook } from "@/store/modules/user";
import { initRouter, getTopMenu } from "@/router/utils";
import { avatar } from "./utils/static";
import { ref, reactive, computed } from "vue";
import { useRenderIcon } from "@/components/ReIcon/src/hooks";
import { useDataThemeChange } from "@/layout/hooks/useDataThemeChange";
import LoginCharacters from "./components/LoginCharacters.vue";

import dayIcon from "@/assets/svg/day.svg?component";
import darkIcon from "@/assets/svg/dark.svg?component";
import Lock from "~icons/ri/lock-fill";
import User from "~icons/ri/user-3-fill";

import { JSEncrypt } from "jsencrypt";

const encryptPassword = (password: string) => {
  const encryptor = new JSEncrypt();
  const publicKey = import.meta.env.VITE_PUBLIC_KEY || "";
  encryptor.setPublicKey(publicKey);
  return encryptor.encrypt(password) || password;
};

defineOptions({ name: "Login" });

const router = useRouter();
const loading = ref(false);
const disabled = ref(false);
const ruleFormRef = ref<FormInstance>();

const { initStorage } = useLayout();
initStorage();
const { dataTheme, themeMode, dataThemeChange } = useDataThemeChange();
dataThemeChange(themeMode.value);
const { title } = useNav();

const ruleForm = reactive({ username: "", password: "" });

// 角色动画状态
const isTyping = ref(false);
const showPassword = ref(false);
const passwordLength = computed(() => ruleForm.password.length);

// 监听密码可见性 (Element Plus show-password 切换)
function onPasswordToggle() {
  showPassword.value = !showPassword.value;
}

const onLogin = async (formEl: FormInstance | undefined) => {
  if (!formEl) return;
  await formEl.validate((valid) => {
    if (valid) {
      loading.value = true;
      useUserStoreHook()
        .loginByUsername({
          mobilePhone: ruleForm.username,
          password: encryptPassword(ruleForm.password),
        })
        .then((res) => {
          if (res.success) {
            return initRouter().then(() => {
              disabled.value = true;
              const topMenu = getTopMenu(true);
              const targetPath = topMenu?.path || "/admin/dashboard";
              router
                .push(targetPath)
                .then(() => {
                  message("登录成功", { type: "success" });
                })
                .finally(() => (disabled.value = false));
            });
          } else {
            message("登录失败", { type: "error" });
          }
        })
        .catch((error) => {
          message(error?.message || "登录失败", { type: "error" });
        })
        .finally(() => (loading.value = false));
    }
  });
};

useEventListener(document, "keydown", ({ code }) => {
  if (["Enter", "NumpadEnter"].includes(code) && !disabled.value && !loading.value)
    onLogin(ruleFormRef.value);
});
</script>

<template>
  <div class="login-page">
    <div class="login-brand-panel">
      <div class="login-brand-logo">
        <component :is="avatar" />
        <span>{{ title }}</span>
      </div>
      <div class="login-characters-area">
        <LoginCharacters
          :is-typing="isTyping"
          :show-password="showPassword"
          :password-length="passwordLength"
        />
      </div>
      <div class="login-brand-footer">
        <span>&copy; {{ new Date().getFullYear() }} {{ title }}</span>
        <span class="login-icp-separator">|</span>
        <a href="https://beian.miit.gov.cn" target="_blank" rel="noopener">粤ICP备2025408522号-2</a>
      </div>
      <div class="login-brand-grid" />
      <div class="login-brand-orb login-brand-orb--1" />
      <div class="login-brand-orb login-brand-orb--2" />
    </div>

    <div class="login-form-panel">
      <div class="absolute right-5 top-3" style="z-index: 10">
        <el-switch
          v-model="dataTheme"
          inline-prompt
          :active-icon="dayIcon"
          :inactive-icon="darkIcon"
          @change="dataThemeChange"
        />
      </div>
      <div class="login-form-wrap">
        <div class="login-card">
          <div class="login-mobile-logo">
            <component :is="avatar" />
            <span>{{ title }}</span>
          </div>
          <div class="login-header">
            <h1>欢迎回来</h1>
            <p>请输入您的账号信息</p>
          </div>
          <el-form ref="ruleFormRef" :model="ruleForm" class="login-form" size="large">
            <el-form-item :rules="[{ required: true, message: '请输入用户名', trigger: 'blur' }]" prop="username">
              <el-input v-model="ruleForm.username" clearable placeholder="请输入用户名" :prefix-icon="useRenderIcon(User)" @focus="isTyping = true" @blur="isTyping = false" />
            </el-form-item>
            <el-form-item :rules="[{ required: true, message: '请输入密码', trigger: 'blur' }]" prop="password">
              <el-input v-model="ruleForm.password" clearable show-password placeholder="请输入密码" :prefix-icon="useRenderIcon(Lock)" @click="onPasswordToggle" />
            </el-form-item>
            <el-form-item>
              <el-button type="primary" :loading="loading" :disabled="disabled" style="width: 100%" @click="onLogin(ruleFormRef)">登录</el-button>
            </el-form-item>
          </el-form>
        </div>
        <div class="login-icp-footer-mobile">
          <a href="https://beian.miit.gov.cn" target="_blank" rel="noopener">粤ICP备2025408522号-2</a>
        </div>
      </div>
    </div>
  </div>
</template>

<style>
@import url("@/style/login.css");
</style>
