<template>
  <div class="chat-container">
    <!-- 头部区域 -->
    <header class="chat-header">
      <div class="logo">
        <svg
          xmlns="http://www.w3.org/2000/svg"
          viewBox="0 0 24 24"
          fill="none"
          stroke="currentColor"
          stroke-width="2"
          stroke-linecap="round"
          stroke-linejoin="round"
          class="logo-icon"
        >
          <circle cx="12" cy="12" r="10"></circle>
          <path d="M9 12h6"></path>
          <path d="M12 9v6"></path>
        </svg>
        <span>智能停车助手</span>
      </div>
      <div class="header-actions">
        <button class="theme-toggle" @click="toggleTheme">
          <svg
            v-if="isDarkMode"
            xmlns="http://www.w3.org/2000/svg"
            viewBox="0 0 24 24"
            fill="none"
            stroke="currentColor"
            stroke-width="2"
            stroke-linecap="round"
            stroke-linejoin="round"
          >
            <circle cx="12" cy="12" r="5"></circle>
            <line x1="12" y1="1" x2="12" y2="3"></line>
            <line x1="12" y1="21" x2="12" y2="23"></line>
            <line x1="4.22" y1="4.22" x2="5.64" y2="5.64"></line>
            <line x1="18.36" y1="18.36" x2="19.78" y2="19.78"></line>
            <line x1="1" y1="12" x2="3" y2="12"></line>
            <line x1="21" y1="12" x2="23" y2="12"></line>
            <line x1="4.22" y1="19.78" x2="5.64" y2="18.36"></line>
            <line x1="18.36" y1="5.64" x2="19.78" y2="4.22"></line>
          </svg>
          <svg
            v-else
            xmlns="http://www.w3.org/2000/svg"
            viewBox="0 0 24 24"
            fill="none"
            stroke="currentColor"
            stroke-width="2"
            stroke-linecap="round"
            stroke-linejoin="round"
          >
            <path d="M21 12.79A9 9 0 1 1 11.21 3 7 7 0 0 0 21 12.79z"></path>
          </svg>
        </button>
        <button class="clear-button" @click="clearMessages">
          <svg
            xmlns="http://www.w3.org/2000/svg"
            viewBox="0 0 24 24"
            fill="none"
            stroke="currentColor"
            stroke-width="2"
            stroke-linecap="round"
            stroke-linejoin="round"
          >
            <polyline points="3 6 5 6 21 6"></polyline>
            <path
              d="M19 6v14a2 2 0 0 1-2 2H7a2 2 0 0 1-2-2V6m3 0V4a2 2 0 0 1 2-2h4a2 2 0 0 1 2 2v2"
            ></path>
          </svg>
        </button>
      </div>
    </header>

    <!-- 消息区域 -->
    <div class="messages-container" ref="messagesContainer">
      <!-- 欢迎消息 -->
      <div class="welcome-message" v-if="displayMessages.length === 0">
        <h1>欢迎使用智能停车助手</h1>
        <p>告诉我您的位置和需求，我会为您推荐最合适的停车位</p>
      </div>

      <!-- 消息列表 -->
      <div class="message-list">
        <div
          v-for="message in displayMessages"
          :key="message.id"
          :class="['message', message.type]"
        >
          <div class="message-avatar">
            <svg
              v-if="message.type === 'ai'"
              xmlns="http://www.w3.org/2000/svg"
              viewBox="0 0 24 24"
              fill="none"
              stroke="currentColor"
              stroke-width="2"
              stroke-linecap="round"
              stroke-linejoin="round"
            >
              <circle cx="12" cy="12" r="10"></circle>
              <path d="M9 12h6"></path>
              <path d="M12 9v6"></path>
            </svg>
            <svg
              v-else
              xmlns="http://www.w3.org/2000/svg"
              viewBox="0 0 24 24"
              fill="none"
              stroke="currentColor"
              stroke-width="2"
              stroke-linecap="round"
              stroke-linejoin="round"
            >
              <path d="M20 21v-2a4 4 0 0 0-4-4H8a4 4 0 0 0-4 4v2"></path>
              <circle cx="12" cy="7" r="4"></circle>
            </svg>
          </div>
          <div class="message-content">
            <div class="message-header">
              <span class="message-sender">{{
                message.type === "ai" ? "智能助手" : "您"
              }}</span>
              <span class="message-time">{{
                formatTime(message.timestamp)
              }}</span>
            </div>
            <div
              class="message-text"
              v-html="formatMessage(message.text)"
            ></div>
          </div>
        </div>
      </div>

      <!-- 输入区域 -->
      <div class="input-container">
        <div class="typing-indicator" v-if="isLoading">
          <span></span>
          <span></span>
          <span></span>
        </div>
        <div class="input-wrapper">
          <textarea
            ref="inputField"
            v-model="userInput"
            @keyup.enter.exact.prevent="handleUserInput"
            placeholder="请输入您的停车需求..."
            :disabled="isLoading"
            rows="1"
            @input="autoResize"
          ></textarea>
          <button
            class="send-button"
            @click="handleUserInput"
            :disabled="!userInput.trim() || isLoading"
          >
            <svg
              xmlns="http://www.w3.org/2000/svg"
              viewBox="0 0 24 24"
              fill="none"
              stroke="currentColor"
              stroke-width="2"
              stroke-linecap="round"
              stroke-linejoin="round"
            >
              <line x1="22" y1="2" x2="11" y2="13"></line>
              <polygon points="22 2 15 22 11 13 2 9 22 2"></polygon>
            </svg>
          </button>
        </div>
        <div class="suggestions" v-if="displayMessages.length === 0">
          <button
            @click="insertSuggestion('我在上海徐家汇附近，需要停车2小时')"
          >
            我在上海徐家汇附近，需要停车2小时
          </button>
          <button @click="insertSuggestion('北京王府井附近有便宜的停车场吗')">
            北京王府井附近有便宜的停车场吗
          </button>
          <button @click="insertSuggestion('杭州西湖景区周边停车攻略')">
            杭州西湖景区周边停车攻略
          </button>
        </div>
      </div>
    </div>
  </div>
</template>

<script>
import axios from "axios";

export default {
  data() {
    return {
      userInput: "",
      displayMessages: [], // 用于显示的消息
      apiMessages: [
        // 用于发送到API的消息数组
        {
          role: "system",
          content:
            "你是一个专业的停车场推荐助手，你需要根据用户的位置和需求，推荐合适的停车场，包含位置、价格和可用车位等信息。请使用中文回答。",
        },
      ],
      isLoading: false,
      isDarkMode:
        window.matchMedia &&
        window.matchMedia("(prefers-color-scheme: dark)").matches,
      tempMessageId: null,
    };
  },
  mounted() {
    // 检测系统主题首选项
    if (window.matchMedia) {
      const mediaQuery = window.matchMedia("(prefers-color-scheme: dark)");
      this.isDarkMode = mediaQuery.matches;

      mediaQuery.addEventListener("change", (e) => {
        this.isDarkMode = e.matches;
        this.applyTheme();
      });
    }

    this.applyTheme();

    // 自动调整文本区域高度
    this.$nextTick(() => {
      this.autoResize();
    });
  },
  methods: {
    async handleUserInput() {
      const userMessage = this.userInput.trim();
      if (!userMessage || this.isLoading) return;

      // 清空输入框并重置高度
      this.userInput = "";
      if (this.$refs.inputField) {
        this.$refs.inputField.style.height = "auto";
      }

      // 添加用户消息到显示列表
      this.displayMessages.push({
        id: Date.now(),
        type: "user",
        text: userMessage,
        timestamp: new Date(),
      });

      // 添加用户消息到API消息数组
      this.apiMessages.push({
        role: "user",
        content: userMessage,
      });

      // 滚动到底部
      this.$nextTick(() => {
        this.scrollToBottom();
      });

      // 设置加载状态
      this.isLoading = true;

      // 创建临时消息ID
      this.tempMessageId = Date.now() + 1000;

      // 添加临时AI消息框，用于流式更新
      this.displayMessages.push({
        id: this.tempMessageId,
        type: "ai",
        text: "",
        timestamp: new Date(),
      });

      try {
        // 调用大模型
        const response = await fetch(`${ApiAddress}/v1/chat/completions`, {
          method: "POST",
          headers: {
            Authorization: `Bearer sk-Bp4AtAw19a6lENrPUQeqfiS9KP46Z5A43j4QkNeX4NRnGKMU`,
            "Content-Type": "application/json",
          },
          body: JSON.stringify({
            model: "gpt-4o-mini",
            messages: this.apiMessages,
            stream: true,
          }),
        });

        // 处理流式响应
        if (response.body) {
          const reader = response.body.getReader();
          const decoder = new TextDecoder();
          let streamedText = "";

          // 读取流
          while (true) {
            const { done, value } = await reader.read();
            if (done) break;

            // 解码二进制数据
            const chunk = decoder.decode(value, { stream: true });

            try {
              // 处理数据块，每个数据块可能包含多个事件，以换行符分隔
              const lines = chunk
                .split("\n")
                .filter((line) => line.trim() !== "");

              for (const line of lines) {
                // 对于某些API，可能需要去掉"data: "前缀
                const cleanLine = line.startsWith("data: ")
                  ? line.slice(5)
                  : line;

                if (cleanLine === "[DONE]") continue;

                try {
                  const data = JSON.parse(cleanLine);

                  // 处理标准的OpenAI流式响应格式
                  if (data.choices && data.choices[0]) {
                    const delta = data.choices[0].delta;

                    // 首个消息包含角色信息
                    if (delta.role) {
                      // 仅处理助手角色的消息
                      if (delta.role !== "assistant") continue;
                    }

                    // 处理内容增量
                    if (delta.content) {
                      streamedText += delta.content;

                      // 更新消息
                      const messageIndex = this.displayMessages.findIndex(
                        (m) => m.id === this.tempMessageId
                      );
                      if (messageIndex !== -1) {
                        this.$set(this.displayMessages, messageIndex, {
                          ...this.displayMessages[messageIndex],
                          text: streamedText,
                        });

                        // 滚动到底部
                        this.$nextTick(() => {
                          this.scrollToBottom();
                        });
                      }
                    }

                    // 检查是否完成
                    if (data.choices[0].finish_reason === "stop") {
                      // 流式响应结束，添加AI消息到API消息数组
                      this.apiMessages.push({
                        role: "assistant",
                        content: streamedText,
                      });
                      this.isLoading = false;
                    }
                  }
                } catch (e) {
                  // 可能不是有效的JSON，继续处理下一行
                  console.warn("Failed to parse JSON line:", cleanLine);
                }
              }
            } catch (e) {
              console.error("Error processing chunk:", e);
            }
          }
        } else {
          // 非流式响应处理
          const data = await response.json();

          if (data.choices && data.choices[0] && data.choices[0].message) {
            const assistantMessage = data.choices[0].message.content || "";

            // 更新消息
            const messageIndex = this.displayMessages.findIndex(
              (m) => m.id === this.tempMessageId
            );
            if (messageIndex !== -1) {
              this.$set(this.displayMessages, messageIndex, {
                ...this.displayMessages[messageIndex],
                text: assistantMessage,
              });
            }

            // 添加AI回复到API消息数组
            this.apiMessages.push({
              role: "assistant",
              content: assistantMessage,
            });
          }

          this.isLoading = false;
        }
      } catch (error) {
        console.error("Error communicating with API:", error);

        // 更新临时消息为错误信息
        const messageIndex = this.displayMessages.findIndex(
          (m) => m.id === this.tempMessageId
        );
        if (messageIndex !== -1) {
          this.$set(this.displayMessages, messageIndex, {
            ...this.displayMessages[messageIndex],
            text: "抱歉，出错了，请稍后再试。如果问题持续，可能是网络连接问题或服务暂时不可用。",
          });
        }

        this.isLoading = false;

        // 滚动到底部
        this.$nextTick(() => {
          this.scrollToBottom();
        });
      }
    },

    scrollToBottom() {
      if (this.$refs.messagesContainer) {
        this.$refs.messagesContainer.scrollTop =
          this.$refs.messagesContainer.scrollHeight;
      }
    },

    formatTime(date) {
      if (!date) return "";

      const now = new Date();
      const messageDate = new Date(date);

      // 如果是今天的消息，只显示时间
      if (now.toDateString() === messageDate.toDateString()) {
        return messageDate.toLocaleTimeString([], {
          hour: "2-digit",
          minute: "2-digit",
        });
      }

      // 否则显示日期和时间
      return messageDate.toLocaleString([], {
        month: "numeric",
        day: "numeric",
        hour: "2-digit",
        minute: "2-digit",
      });
    },

    formatMessage(text) {
      // 将纯文本转换为HTML，处理换行符等
      return text.replace(/\n/g, "<br>");
    },

    autoResize() {
      const textarea = this.$refs.inputField;
      if (!textarea) return;

      // 重置高度
      textarea.style.height = "auto";

      // 设置新高度（最大5行）
      const newHeight = Math.min(textarea.scrollHeight, 120);
      textarea.style.height = `${newHeight}px`;
    },

    toggleTheme() {
      this.isDarkMode = !this.isDarkMode;
      this.applyTheme();
    },

    applyTheme() {
      // 向文档添加/移除暗色模式类
      if (this.isDarkMode) {
        document.documentElement.classList.add("dark-theme");
      } else {
        document.documentElement.classList.remove("dark-theme");
      }
    },

    clearMessages() {
      // 清空所有消息
      this.displayMessages = [];
      // 重置API消息数组，只保留系统消息
      this.apiMessages = [
        {
          role: "system",
          content:
            "你是一个专业的停车场推荐助手，你需要根据用户的位置和需求，推荐合适的停车场，包含位置、价格和可用车位等信息。请使用中文回答。",
        },
      ];
    },

    insertSuggestion(text) {
      this.userInput = text;
      // 聚焦输入框
      this.$nextTick(() => {
        this.$refs.inputField.focus();
      });
    },
  },
};
</script>

<style>
/* 全局样式 */
:root {
  --primary-color: #3b82f6;
  --primary-dark: #2563eb;
  --bg-color: #ffffff;
  --bg-secondary: #f9fafb;
  --text-color: #111827;
  --text-secondary: #6b7280;
  --border-color: #e5e7eb;
  --user-msg-bg: #dbeafe;
  --ai-msg-bg: #f3f4f6;
  --input-bg: #ffffff;
  --shadow-color: rgba(0, 0, 0, 0.1);
  --animation-duration: 0.2s;
}

.dark-theme {
  --primary-color: #3b82f6;
  --primary-dark: #2563eb;
  --bg-color: #111827;
  --bg-secondary: #1f2937;
  --text-color: #f9fafb;
  --text-secondary: #d1d5db;
  --border-color: #374151;
  --user-msg-bg: #2563eb;
  --ai-msg-bg: #1f2937;
  --input-bg: #1f2937;
  --shadow-color: rgba(0, 0, 0, 0.3);
}

* {
  margin: 0;
  padding: 0;
  box-sizing: border-box;
  transition: background-color var(--animation-duration) ease,
    color var(--animation-duration) ease,
    border-color var(--animation-duration) ease;
}

body {
  font-family: "Inter", -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto,
    Helvetica, Arial, sans-serif;
  line-height: 1.5;
  color: var(--text-color);
  background-color: var(--bg-color);
  transition: background-color var(--animation-duration) ease;
}

/* 聊天容器 */
.chat-container {
  display: flex;
  flex-direction: column;
  height: 100vh;
  max-width: 100%;
  background-color: var(--bg-color);
}

/* 头部样式 */
.chat-header {
  display: flex;
  justify-content: space-between;
  align-items: center;
  padding: 0.75rem 1rem;
  background-color: var(--bg-secondary);
  border-bottom: 1px solid var(--border-color);
  z-index: 10;
}

.logo {
  display: flex;
  align-items: center;
  font-weight: 600;
  font-size: 1.25rem;
}

.logo-icon {
  width: 1.5rem;
  height: 1.5rem;
  margin-right: 0.5rem;
  color: var(--primary-color);
}

.header-actions {
  display: flex;
  gap: 0.75rem;
}

.theme-toggle,
.clear-button {
  display: flex;
  align-items: center;
  justify-content: center;
  width: 2.25rem;
  height: 2.25rem;
  border-radius: 0.5rem;
  border: none;
  background-color: transparent;
  color: var(--text-secondary);
  cursor: pointer;
  transition: background-color 0.2s ease;
}

.theme-toggle:hover,
.clear-button:hover {
  background-color: var(--border-color);
  color: var(--text-color);
}

.theme-toggle svg,
.clear-button svg {
  width: 1.25rem;
  height: 1.25rem;
}

/* 消息容器样式 */
.messages-container {
  flex: 1;
  overflow-y: auto;
  padding: 1rem;
  scroll-behavior: smooth;
  background-image: radial-gradient(var(--border-color) 1px, transparent 1px);
  background-size: 25px 25px;
}

/* 欢迎消息样式 */
.welcome-message {
  text-align: center;
  margin: 2rem 0;
  padding: 2rem;
  max-width: 48rem;
  margin-left: auto;
  margin-right: auto;
  border-radius: 1rem;
  background-color: var(--bg-secondary);
  box-shadow: 0 4px 6px var(--shadow-color);
  animation: fadeIn 0.5s ease;
}

.welcome-message h1 {
  font-size: 2rem;
  margin-bottom: 1rem;
  background: linear-gradient(
    135deg,
    var(--primary-color),
    var(--primary-dark)
  );
  -webkit-background-clip: text;
  -webkit-text-fill-color: transparent;
  background-clip: text;
}

.welcome-message p {
  color: var(--text-secondary);
  font-size: 1.125rem;
}

/* 消息列表样式 */
.message-list {
  display: flex;
  flex-direction: column;
  gap: 1rem;
  max-width: 48rem;
  margin: 0 auto;
}

.message {
  display: flex;
  gap: 0.75rem;
  animation: slideIn 0.3s ease;
  max-width: 100%;
}

.message-avatar {
  flex-shrink: 0;
  width: 2.5rem;
  height: 2.5rem;
  display: flex;
  align-items: center;
  justify-content: center;
  border-radius: 0.75rem;
  background-color: var(--bg-secondary);
  overflow: hidden;
}

.message-avatar svg {
  width: 1.5rem;
  height: 1.5rem;
  color: var(--primary-color);
}

.user .message-avatar {
  background-color: var(--primary-color);
}

.user .message-avatar svg {
  color: white;
}

.message-content {
  flex: 1;
  min-width: 0;
  padding: 0.75rem 1rem;
  border-radius: 1rem;
  background-color: var(--ai-msg-bg);
  box-shadow: 0 2px 4px var(--shadow-color);
}

.message.user .message-content {
  background-color: var(--user-msg-bg);
}

.message-header {
  display: flex;
  justify-content: space-between;
  align-items: center;
  margin-bottom: 0.25rem;
  font-size: 0.875rem;
}

.message-sender {
  font-weight: 600;
}

.message-time {
  color: var(--text-secondary);
  font-size: 0.75rem;
}

.message-text {
  word-break: break-word;
  white-space: pre-wrap;
}

.user .message-text {
  color: var(--text-color);
}

/* 输入区域样式 */
.input-container {
  padding: 1rem;
  background-color: var(--bg-color);
  border-top: 1px solid var(--border-color);
  max-width: 48rem;
  margin: 0 auto;
  width: 100%;
}

.input-wrapper {
  position: relative;
  display: flex;
  align-items: flex-end;
  background-color: var(--input-bg);
  border-radius: 1rem;
  border: 1px solid var(--border-color);
  box-shadow: 0 2px 6px var(--shadow-color);
  transition: border-color 0.2s ease, box-shadow 0.2s ease;
}

.input-wrapper:focus-within {
  border-color: var(--primary-color);
  box-shadow: 0 0 0 2px rgba(59, 130, 246, 0.3);
}

textarea {
  flex: 1;
  padding: 0.75rem 1rem;
  padding-right: 3rem;
  border: none;
  background: transparent;
  resize: none;
  color: var(--text-color);
  font-family: inherit;
  font-size: 1rem;
  line-height: 1.5;
  max-height: 120px; /* 最大高度，约5行 */
  border-radius: 1rem;
}

textarea:focus {
  outline: none;
}

textarea::placeholder {
  color: var(--text-secondary);
}

.send-button {
  position: absolute;
  right: 0.5rem;
  bottom: 0.5rem;
  width: 2.25rem;
  height: 2.25rem;
  display: flex;
  align-items: center;
  justify-content: center;
  background-color: var(--primary-color);
  color: white;
  border: none;
  border-radius: 0.75rem;
  cursor: pointer;
  transition: background-color 0.2s ease, transform 0.1s ease;
}

.send-button:hover {
  background-color: var(--primary-dark);
}

.send-button:active {
  transform: scale(0.95);
}

.send-button svg {
  width: 1.25rem;
  height: 1.25rem;
}

.send-button:disabled {
  background-color: var(--border-color);
  cursor: not-allowed;
}

/* 建议样式 */
.suggestions {
  display: flex;
  flex-wrap: wrap;
  gap: 0.5rem;
  margin-top: 1rem;
}

.suggestions button {
  padding: 0.5rem 1rem;
  background-color: var(--bg-secondary);
  border: 1px solid var(--border-color);
  border-radius: 1rem;
  color: var(--text-color);
  font-size: 0.875rem;
  cursor: pointer;
  transition: background-color 0.2s ease, transform 0.1s ease;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
  max-width: 100%;
}

.suggestions button:hover {
  background-color: var(--border-color);
}

.suggestions button:active {
  transform: scale(0.98);
}

/* 打字指示器样式 */
.typing-indicator {
  display: flex;
  align-items: center;
  gap: 0.25rem;
  padding: 0.5rem;
  margin-bottom: 0.5rem;
  animation: fadeIn 0.3s ease;
}

.typing-indicator span {
  width: 0.5rem;
  height: 0.5rem;
  border-radius: 50%;
  background-color: var(--primary-color);
  animation: bounce 1.4s infinite ease-in-out;
}

.typing-indicator span:nth-child(1) {
  animation-delay: 0s;
}

.typing-indicator span:nth-child(2) {
  animation-delay: 0.2s;
}

.typing-indicator span:nth-child(3) {
  animation-delay: 0.4s;
}

/* 动画 */
@keyframes fadeIn {
  from {
    opacity: 0;
  }
  to {
    opacity: 1;
  }
}

@keyframes slideIn {
  from {
    opacity: 0;
    transform: translateY(10px);
  }
  to {
    opacity: 1;
    transform: translateY(0);
  }
}

@keyframes bounce {
  0%,
  80%,
  100% {
    transform: translateY(0);
  }
  40% {
    transform: translateY(-6px);
  }
}

/* 响应式设计 */
@media (max-width: 768px) {
  .welcome-message {
    padding: 1.5rem;
    margin: 1rem 0;
  }

  .welcome-message h1 {
    font-size: 1.5rem;
  }

  .welcome-message p {
    font-size: 1rem;
  }

  .message-avatar {
    width: 2rem;
    height: 2rem;
  }

  .message-avatar svg {
    width: 1.25rem;
    height: 1.25rem;
  }

  .input-container {
    padding: 0.75rem;
  }
}

/* 滚动条样式 */
::-webkit-scrollbar {
  width: 0.5rem;
}

::-webkit-scrollbar-track {
  background-color: var(--bg-secondary);
}

::-webkit-scrollbar-thumb {
  background-color: var(--border-color);
  border-radius: 0.25rem;
}

::-webkit-scrollbar-thumb:hover {
  background-color: var(--text-secondary);
}
</style>
