<script lang="ts" setup>
import { computed, nextTick, onMounted, reactive, ref } from 'vue';

import MarkdownIt from 'markdown-it';
import { markdownItTable } from 'markdown-it-table';

import * as api from '#/api';

const md = new MarkdownIt({
  html: true,
  linkify: true,
  typographer: true,
}).use(markdownItTable);
// AI 实体
interface AgentItem {
  id: string;
  title: string;
  welcome_words: string;
}
// 输入框内容
const inputMessage = ref('');

// 对话列表
const conversations = ref<AgentItem[]>([]);
// AI列表
const aiOptions = ref<AgentItem[]>([]);

// 当前选中的AI
const selectedAI = ref<AgentItem | null>(null);
// 当前选中的对话
const currentSession = ref<null | string>(null);

// 聊天记录
const messages = reactive<{ content: string; sender: 'ai' | 'user' }[]>([]);

// 计算第一次聊天状态
const isInitial = computed(() => messages.length === 0);

function handleEnter(e: KeyboardEvent) {
  if (e.ctrlKey) {
    // Ctrl + Enter 换行
    const target = e.target as HTMLTextAreaElement;
    const start = target.selectionStart;
    const end = target.selectionEnd;
    target.value = `${target.value.slice(0, Math.max(0, start))}\n${target.value.slice(Math.max(0, end))}`;
    target.selectionStart = target.selectionEnd = start + 1;
    inputMessage.value = target.value;
  } else {
    // Enter 发送
    sendMessage();
  }
}

function autoResize(e: Event) {
  const target = e.target as HTMLTextAreaElement;
  if (!target) return;
  target.style.height = 'auto';
  target.style.height = `${target.scrollHeight}px`;
}

// 滚动到底部
function scrollToBottom() {
  const container = document.querySelector('#chat-container');
  if (container)
    container.scrollTo({ top: container.scrollHeight, behavior: 'smooth' });
}

// 模拟接口获取对话列表
async function getSessions() {
  conversations.value = await api.getSessionsForService();
}

// 模拟接口获取聊天记录
async function fetchMessages(conversationId: string) {
  messages.splice(0);
  const msg = await api.getHistory(conversationId);
  messages.push(...msg);
}

// 点击对话加载聊天记录
async function loadConversation(id: string) {
  currentSession.value = id;
  await fetchMessages(id);
  nextTick(() => scrollToBottom());
}

// 发送消息
async function sendMessage() {
  const content = inputMessage.value.trim();
  if (!content) return;

  messages.push({ type: 'human', content });
  inputMessage.value = '';

  nextTick(() => scrollToBottom());

  // 发送消息
  const answer = await api.chatWithService(
    selectedAI.value?.id || '',
    currentSession.value,
    content,
  );
  currentSession.value = answer.sessionId;
  if (answer.isNewSession) {
    conversations.value.unshift({
      id: answer.sessionId,
      updatedAt: formatDate(new Date()),
      title: answer.sessionName,
    });
  }
  messages.push({ type: 'ai', content: answer.content });
  nextTick(() => scrollToBottom());
  // 焦点回到输入框
  const textarea = document.querySelector(
    'textarea[placeholder="输入消息开始聊天..."], textarea[placeholder="输入消息..."]',
  ) as HTMLTextAreaElement;
  if (textarea) {
    textarea.focus();
  }
}

// 新建聊天
function createNewConversation() {
  currentSession.value = null;
  messages.splice(0);
}

// 获取AI列表
const fetchOptions = async () => {
  try {
    aiOptions.value = await api.getAIBotListForService();
    if (aiOptions.value.length > 0 && aiOptions.value[0] !== undefined) {
      selectedAI.value = aiOptions.value[0]!;
    }
  } catch (error) {
    console.error('获取下拉选项失败:', error);
  }
};
function formatDate(date: Date): string {
  const pad = (n: number) => n.toString().padStart(2, '0');

  return (
    `${date.getFullYear()}-${pad(date.getMonth() + 1)}-${pad(date.getDate())} ` +
    `${pad(date.getHours())}:${pad(date.getMinutes())}:${pad(date.getSeconds())}`
  );
}
// 页面加载时调用接口
onMounted(() => {
  fetchOptions();
  getSessions();
});
</script>

<template>
  <div class="flex h-[90dvh] bg-gray-50">
    <!-- 左侧对话列表 -->
    <div
      class="flex h-full w-64 flex-shrink-0 flex-col border-r border-gray-200 bg-white"
    >
      <div class="flex items-center space-x-2 border-b border-gray-200 p-4">
        <button
          @click="createNewConversation"
          class="flex items-center rounded bg-blue-500 px-3 py-1 text-white transition-colors hover:bg-blue-600"
        >
          <svg
            xmlns="http://www.w3.org/2000/svg"
            class="mr-1 h-4 w-4"
            fill="none"
            viewBox="0 0 24 24"
            stroke="currentColor"
          >
            <path
              stroke-linecap="round"
              stroke-linejoin="round"
              stroke-width="2"
              d="M12 4v16m8-8H4"
            />
          </svg>
          新聊天
        </button>

        <!-- 下拉框 -->
        <select
          v-model="selectedAI"
          class="flex-1 rounded border border-gray-300 p-1"
        >
          <option v-for="item in aiOptions" :key="item.id" :value="item">
            {{ item.title }}
          </option>
        </select>
      </div>
      <ul class="flex-1 divide-y divide-gray-200 overflow-y-auto">
        <li
          v-for="conv in conversations"
          :key="conv.id"
          @click="loadConversation(conv.id)"
          class="cursor-pointer p-4 transition-colors hover:bg-gray-50"
          :class="{
            'bg-gray-100 font-semibold': currentSession === conv.id,
          }"
        >
          <div class="flex items-center justify-between">
            <span class="truncate">{{ conv.title }}</span>
            <span class="ml-2 text-xs text-gray-400">{{ conv.updatedAt }}</span>
          </div>
        </li>
      </ul>
    </div>

    <!-- 右侧聊天区 -->
    <div class="relative flex flex-1 flex-col">
      <!-- 聊天记录 -->
      <div
        id="chat-container"
        class="flex flex-1 flex-col space-y-4 overflow-y-auto p-4 transition-all duration-300"
        :class="{
          'items-center justify-center': isInitial,
          'justify-start': !isInitial,
        }"
      >
        <template v-if="isInitial">
          <div class="flex w-full flex-col items-center space-y-4">
            <!-- 欢迎词 -->
            <div class="text-center text-lg text-gray-700">
              {{ selectedAI?.welcome_words }}
            </div>

            <!-- 输入框 -->
            <textarea
              v-model="inputMessage"
              placeholder="输入消息开始聊天..."
              rows="1"
              class="w-1/2 resize-none overflow-hidden rounded-lg border border-gray-300 p-3 focus:outline-none focus:ring-2 focus:ring-blue-400"
              @keydown.enter.prevent="handleEnter($event)"
              @input="autoResize($event)"
            ></textarea>
          </div>
        </template>
        <template v-else>
          <div class="flex w-full flex-col items-center space-y-4">
            <div
              v-for="(msg, idx) in messages"
              :key="idx"
              class="animate-fadeIn flex w-full transition-opacity duration-500"
              :class="msg.type === 'ai' ? 'justify-start' : 'justify-end'"
            >
              <div
                class="prose inline-block max-w-[80%] break-words rounded-lg p-3"
                :class="
                  msg.type === 'ai'
                    ? 'bg-blue-100 text-gray-800'
                    : 'bg-gray-200 text-gray-800'
                "
                v-html="md.render(msg.content)"
              ></div>
            </div>
          </div>
        </template>
      </div>

      <!-- 输入框固定底部 -->
      <div v-if="!isInitial" class="flex border-t border-gray-200 bg-white p-4">
        <textarea
          v-model="inputMessage"
          @keyup.enter="sendMessage"
          rows="1"
          placeholder="输入消息..."
          class="flex-1 resize-none overflow-hidden rounded-md border border-gray-300 p-2 focus:outline-none focus:ring-2 focus:ring-blue-400"
          @input="
            $event.target.style.height = 'auto';
            $event.target.style.height = `${$event.target.scrollHeight}px`;
          "
        ></textarea>
        <button
          @click="sendMessage"
          class="ml-2 rounded-md bg-blue-500 px-4 py-2 text-white transition-colors hover:bg-blue-600"
        >
          发送
        </button>
      </div>
    </div>
  </div>
</template>

<style scoped>
@keyframes fadeIn {
  from {
    opacity: 0;
    transform: translateY(5px);
  }

  to {
    opacity: 1;
    transform: translateY(0);
  }
}

html,
body,
#app {
  height: 100%;
  padding: 0;
  margin: 0;
}

.animate-fadeIn {
  animation: fadeIn 0.3s forwards;
}
</style>
