<script setup lang="ts">
import { Check, Clock3, LibraryBig, LogIn } from "@lucide/vue";
import { computed, onMounted, ref } from "vue";
import { useRoute, useRouter } from "vue-router";
import { apiRequest, ApiError } from "../data/api";
import { useAuthStore } from "../stores/auth";
import { useLedgerStore } from "../stores/ledgers";

type LedgerInvitation = {
  ledgerId: string;
  ledgerName: string;
  inviterName: string | null;
  expiresAt: string;
  status: "valid" | "expired" | "accepted" | "revoked";
};

const route = useRoute();
const router = useRouter();
const auth = useAuthStore();
const ledgerStore = useLedgerStore();
const invitation = ref<LedgerInvitation | null>(null);
const loading = ref(true);
const accepting = ref(false);
const errorMessage = ref("");
const key = computed(() => typeof route.query.key === "string" ? route.query.key : "");

onMounted(async () => {
  if (!key.value) {
    errorMessage.value = "邀请链接不完整";
    loading.value = false;
    return;
  }
  try {
    const result = await apiRequest<{ invitation: LedgerInvitation }>(`/api/ledger-invitations/${encodeURIComponent(key.value)}`);
    invitation.value = result.invitation;
    if (result.invitation.status !== "valid") errorMessage.value = "账本邀请已失效";
  } catch (error) {
    errorMessage.value = error instanceof ApiError ? error.message : "无法读取账本邀请";
  } finally {
    loading.value = false;
  }
});

async function continueToJoin() {
  if (!auth.user) {
    await router.push({ name: "login", query: { redirect: route.fullPath } });
    return;
  }
  await accept();
}

async function accept() {
  if (!invitation.value || accepting.value) return;
  accepting.value = true;
  try {
    const result = await apiRequest<{ ledgerId: string }>(`/api/ledger-invitations/${encodeURIComponent(key.value)}/accept`, { method: "POST" });
    await ledgerStore.reloadLedgers();
    await ledgerStore.setCurrentLedger(result.ledgerId);
    await router.replace("/");
  } catch (error) {
    errorMessage.value = error instanceof ApiError ? error.message : "加入账本失败";
  } finally {
    accepting.value = false;
  }
}
</script>

<template>
  <main class="app-shell join-shell">
    <section class="join-content">
      <div v-if="loading" class="join-state">正在读取账本邀请...</div>
      <template v-else-if="invitation">
        <span class="join-mark"><LibraryBig :size="31" /></span>
        <small>{{ invitation.inviterName ? `${invitation.inviterName} 邀请你加入` : "你被邀请加入" }}</small>
        <h1>{{ invitation.ledgerName }}</h1>
        <span class="join-expiry"><Clock3 :size="14" />邀请链接 7 天内有效</span>
        <p v-if="!auth.user && invitation.status === 'valid'" class="join-account-note">账本邀请仅供已有账户使用。请先登录，成功后会自动返回这里。</p>
        <button v-if="invitation.status === 'valid'" type="button" :disabled="accepting" @click="continueToJoin">
          <Check v-if="auth.user" :size="19" /><LogIn v-else :size="19" />
          {{ accepting ? "正在加入" : auth.user ? "加入账本" : "登录后加入" }}
        </button>
        <p v-if="errorMessage" role="alert">{{ errorMessage }}</p>
      </template>
      <div v-else class="join-state error">{{ errorMessage }}</div>
    </section>
  </main>
</template>

<style scoped>
.join-shell { display:grid; place-items:center; padding:24px; background:#f4f8f7; }
.join-content { width:100%; display:grid; justify-items:center; gap:8px; text-align:center; }
.join-mark { width:72px; height:72px; display:grid; place-items:center; margin-bottom:10px; border:1px solid #b8dad2; border-radius:50%; background:#fff; color:#087f72; box-shadow:0 12px 30px rgba(34,78,68,.12); }
.join-content small { color:#6f7e7a; font-size:13px; }
.join-content h1 { margin:0; color:#1d302b; font-size:25px; letter-spacing:0; }
.join-expiry { display:flex; align-items:center; gap:5px; color:#71827d; font-size:12px; }
.join-account-note { max-width:310px; margin:18px 0 0!important; color:#667772!important; line-height:1.6; }
.join-content button { width:100%; height:50px; display:flex; align-items:center; justify-content:center; gap:7px; margin-top:12px; border:0; border-radius:8px; background:#087f72; color:#fff; font-weight:720; }
.join-content button:disabled { opacity:.5; }
.join-content p,.join-state.error { color:#c74d39; font-size:12px; }
.join-state { color:#6e7f7a; font-size:14px; }
</style>
