<script setup lang="ts">
import { Eye, EyeOff, KeyRound, LogIn, UserRound } from "@lucide/vue";
import { computed, ref } from "vue";
import { useRoute, useRouter } from "vue-router";
import { ApiError } from "../data/api";
import { useAuthStore } from "../stores/auth";
import { useLedgerStore } from "../stores/ledgers";

const route = useRoute();
const router = useRouter();
const auth = useAuthStore();
const ledgerStore = useLedgerStore();
const name = ref("");
const password = ref("");
const passwordVisible = ref(false);
const submitting = ref(false);
const errorMessage = ref("");
const redirect = computed(() => typeof route.query.redirect === "string" && route.query.redirect.startsWith("/")
  ? route.query.redirect
  : "/");
const joiningLedger = computed(() => redirect.value.startsWith("/join-ledger?"));

async function login() {
  if (!name.value.trim() || !password.value || submitting.value) return;
  submitting.value = true;
  errorMessage.value = "";
  try {
    await auth.login(name.value.trim(), password.value);
    await ledgerStore.reloadLedgers();
    await router.replace(redirect.value);
  } catch (error) {
    errorMessage.value = error instanceof ApiError ? error.message : "暂时无法登录";
  } finally {
    submitting.value = false;
  }
}
</script>

<template>
  <main class="app-shell login-shell">
    <header><span><KeyRound :size="18" /></span><strong>Cents</strong></header>
    <section class="login-content">
      <div class="login-heading">
        <h1>登录</h1>
        <p>{{ joiningLedger ? "登录已有账户后加入受邀账本" : "继续使用家庭账本" }}</p>
      </div>
      <form @submit.prevent="login">
        <label><span>姓名</span><div><UserRound :size="19" /><input v-model="name" maxlength="40" autocomplete="username" /></div></label>
        <label><span>密码</span><div><KeyRound :size="19" /><input v-model="password" :type="passwordVisible ? 'text' : 'password'" maxlength="128" autocomplete="current-password" /><button type="button" :aria-label="passwordVisible ? '隐藏密码' : '显示密码'" :title="passwordVisible ? '隐藏密码' : '显示密码'" @click="passwordVisible = !passwordVisible"><EyeOff v-if="passwordVisible" :size="19" /><Eye v-else :size="19" /></button></div></label>
        <p v-if="errorMessage" role="alert">{{ errorMessage }}</p>
        <button class="login-submit" type="submit" :disabled="submitting || !name.trim() || !password"><LogIn :size="19" />{{ submitting ? "正在登录" : "登录" }}</button>
      </form>
      <small v-if="joiningLedger">账本邀请不能创建账户。没有账户时，请先向管理员获取应用邀请。</small>
      <small v-else>没有账号时，需要先打开应用邀请链接</small>
    </section>
  </main>
</template>

<style scoped>
.login-shell { background:#f4f8f7; }
.login-shell > header { height:64px; display:flex; align-items:center; justify-content:center; gap:8px; border-bottom:1px solid #dce8e5; background:#fff; color:#087f72; }
.login-shell > header span { width:30px; height:30px; display:grid; place-items:center; border-radius:50%; background:#e5f5f1; }
.login-content { height:calc(100% - 64px); display:flex; flex-direction:column; padding:58px 24px 32px; overflow-y:auto; }
.login-heading { display:grid; gap:5px; }
.login-heading h1 { margin:0; color:#1d302b; font-size:27px; letter-spacing:0; }
.login-heading p { margin:0; color:#71807c; font-size:14px; }
.login-content form { display:grid; gap:16px; margin-top:30px; }
.login-content label { display:grid; gap:7px; color:#64746f; font-size:12px; }
.login-content label > div { height:52px; display:grid; grid-template-columns:30px minmax(0,1fr) auto; align-items:center; border:1px solid #cbdad6; border-radius:8px; padding:0 11px; background:#fff; color:#70817c; }
.login-content input { min-width:0; border:0; outline:0; color:#1e312c; font-size:16px; }
.login-content label button { width:38px; height:38px; display:grid; place-items:center; border:0; background:transparent; color:#61756f; }
.login-content form > p { margin:0; color:#c74d39; font-size:12px; }
.login-submit { height:52px; display:flex; align-items:center; justify-content:center; gap:7px; border:0; border-radius:8px; background:#087f72; color:#fff; font-weight:720; }
.login-submit:disabled { opacity:.5; }
.login-content > small { margin-top:18px; color:#7a8985; font-size:11px; text-align:center; }
</style>
