<script setup lang="ts">
import { Pencil, Plus, Trash2, X } from "@lucide/vue";
import { computed, ref, watch } from "vue";

import type { ChatSession } from "../types/api";
import AppDialog from "./AppDialog.vue";

const props = defineProps<{
  open: boolean;
  sessions: ChatSession[];
  activeSessionId: number | null;
  loading: boolean;
  operationPending: boolean;
}>();

const emit = defineEmits<{
  close: [];
  select: [sessionId: number];
  create: [];
  rename: [sessionId: number, title: string, done: (success: boolean) => void];
  delete: [sessionId: number, done: (success: boolean) => void];
}>();

const renaming = ref<ChatSession | null>(null);
const renameTitle = ref("");
const deleting = ref<ChatSession | null>(null);

watch(() => props.open, (open) => {
  document.body.classList.toggle("drawer-open", open);
}, { immediate: true });

const validRename = computed(() => renameTitle.value.trim().length > 0);

function openRename(session: ChatSession) {
  renaming.value = session;
  renameTitle.value = session.title;
}

function submitRename() {
  if (!renaming.value || !validRename.value || props.operationPending) return;
  emit("rename", renaming.value.id, renameTitle.value.trim(), (success) => {
    if (success) renaming.value = null;
  });
}

function submitDelete() {
  if (!deleting.value || props.operationPending) return;
  emit("delete", deleting.value.id, (success) => {
    if (success) deleting.value = null;
  });
}

function formatTime(value: string) {
  const date = new Date(value);
  if (Number.isNaN(date.getTime())) return "";
  const now = new Date();
  const today = new Date(now.getFullYear(), now.getMonth(), now.getDate());
  const target = new Date(date.getFullYear(), date.getMonth(), date.getDate());
  const days = Math.round((today.getTime() - target.getTime()) / 86_400_000);
  const time = new Intl.DateTimeFormat("zh-CN", { hour: "2-digit", minute: "2-digit", hour12: false }).format(date);
  if (days === 0) return time;
  if (days === 1) return `昨天 ${time}`;
  return `${String(date.getMonth() + 1).padStart(2, "0")}/${String(date.getDate()).padStart(2, "0")} ${time}`;
}
</script>

<template>
  <div class="history-mask" :class="{ visible: open }" @click="emit('close')"></div>
  <aside class="history-drawer" :class="{ open }" :aria-hidden="!open">
    <header class="history-header">
      <h2>历史会话</h2>
      <button type="button" aria-label="关闭历史会话" @click="emit('close')">
        <X :size="22" aria-hidden="true" />
      </button>
    </header>

    <button type="button" class="new-chat-button" :disabled="operationPending" @click="emit('create')">
      <Plus :size="20" aria-hidden="true" />
      新聊天
    </button>

    <div class="history-list">
      <div v-if="loading" class="history-state">正在加载历史会话...</div>
      <div v-else-if="sessions.length === 0" class="history-state">暂无历史会话</div>
      <article
        v-for="session in sessions"
        v-else
        :key="session.id"
        class="history-item"
        :class="{ active: session.id === activeSessionId }"
      >
        <button type="button" class="history-main" @click="emit('select', session.id)">
          <strong>{{ session.title }}</strong>
          <time :datetime="session.updatedAt">{{ formatTime(session.updatedAt) }}</time>
          <span>{{ session.messageCount }} 条消息</span>
        </button>
        <div class="history-actions">
          <button type="button" @click="openRename(session)">
            <Pencil :size="15" aria-hidden="true" />改名
          </button>
          <button type="button" class="danger" @click="deleting = session">
            <Trash2 :size="15" aria-hidden="true" />删除
          </button>
        </div>
      </article>
    </div>
  </aside>

  <AppDialog v-if="renaming" title="修改会话名称" labelled-by="rename-session-title" @close="renaming = null">
    <form class="session-dialog-form" @submit.prevent="submitRename">
      <label for="session-title-input">会话名称</label>
      <input id="session-title-input" v-model="renameTitle" maxlength="50" autocomplete="off" autofocus />
      <p>{{ renameTitle.trim().length }}/50</p>
    </form>
    <template #footer>
      <div class="dialog-actions">
        <button type="button" class="dialog-secondary" :disabled="operationPending" @click="renaming = null">取消</button>
        <button type="button" class="dialog-primary" :disabled="!validRename || operationPending" @click="submitRename">
          {{ operationPending ? "保存中..." : "保存" }}
        </button>
      </div>
    </template>
  </AppDialog>

  <AppDialog v-if="deleting" title="删除会话" labelled-by="delete-session-title" @close="deleting = null">
    <p class="confirm-copy">确定删除这个会话吗？删除后无法恢复。</p>
    <template #footer>
      <div class="dialog-actions">
        <button type="button" class="dialog-secondary" :disabled="operationPending" @click="deleting = null">取消</button>
        <button type="button" class="dialog-danger" :disabled="operationPending" @click="submitDelete">
          {{ operationPending ? "删除中..." : "删除" }}
        </button>
      </div>
    </template>
  </AppDialog>
</template>
