<template>
  <div
    class="chat-input-container"
    :class="{ 'is-focused': isFocused, 'is-expanded': isExpanded }"
  >
    <!-- 附件预览区 -->
    <AttachmentPreview
      v-if="attachments.length > 0"
      :attachments="attachments"
      @remove="removeAttachment"
    />

    <!-- 输入区域 -->
    <div class="input-area">
      <!-- 左侧功能按钮 -->
      <div class="input-actions left">
        <!-- 附件按钮 -->
        <button class="action-btn" title="添加附件" @click="triggerFileInput">
          <Paperclip :size="20" />
        </button>

        <!-- 图片按钮 -->
        <button class="action-btn" title="添加图片" @click="triggerImageInput">
          <Image :size="20" />
        </button>

        <!-- 隐藏的文件输入框 -->
        <input
          ref="fileInputRef"
          type="file"
          multiple
          hidden
          @change="handleFileSelect"
        />
        <input
          ref="imageInputRef"
          type="file"
          accept="image/*"
          multiple
          hidden
          @change="handleImageSelect"
        />
      </div>

      <!-- 文本输入框 -->
      <div class="textarea-wrapper">
        <textarea
          ref="textareaRef"
          v-model="inputText"
          :placeholder="placeholder"
          :rows="1"
          @input="autoResize"
          @focus="isFocused = true"
          @blur="isFocused = false"
          @keydown="handleKeydown"
          @paste="handlePaste"
        />
      </div>

      <!-- 右侧功能按钮 -->
      <div class="input-actions right">
        <!-- 发送/停止按钮 -->
        <button
          v-if="isStreaming"
          class="action-btn stop"
          title="停止生成"
          @click="$emit('stop')"
        >
          <StopCircle :size="20" />
        </button>
        <button
          v-else
          class="action-btn send"
          :class="{ active: canSend, loading: isUploading }"
          :disabled="!canSend"
          :title="isUploading ? '上传中...' : '发送消息 (Ctrl+Enter)'"
          @click="handleSend"
        >
          <Loader2 v-if="isUploading" :size="20" class="animate-spin" />
          <Send v-else :size="20" />
        </button>
      </div>
    </div>

    <!-- 底部工具栏 -->
    <div class="input-toolbar">
      <div class="toolbar-left">
        <!-- 深度思考开关 -->
        <button
          class="toolbar-btn"
          :class="{ active: isDeepThinking }"
          title="深度思考"
          @click="toggleDeepThink"
        >
          <Brain :size="16" />
          <span>深度思考</span>
        </button>

        <!-- 深度搜索开关 -->
        <button
          class="toolbar-btn"
          :class="{ active: isDeepSearch }"
          title="深度搜索"
          @click="toggleDeepSearch"
        >
          <Sparkles :size="16" />
          <span>深度搜索</span>
        </button>

        <!-- 联网搜索开关 -->
        <button
          class="toolbar-btn"
          :class="{ active: isWebSearch }"
          title="联网搜索"
          @click="toggleWebSearch"
        >
          <Globe :size="16" />
          <span>联网搜索</span>
        </button>

        <!-- 展开/收起 -->
        <button class="toolbar-btn" title="展开输入框" @click="toggleExpand">
          <Maximize2 v-if="!isExpanded" :size="16" />
          <Minimize2 v-else :size="16" />
        </button>
      </div>

      <div class="toolbar-right">
        <span
          class="char-count"
          :class="{ warning: charCount > maxChars * 0.9 }"
        >
          {{ charCount }} / {{ maxChars }}
        </span>
        <span class="send-hint">
          {{ sendOnEnter ? "Enter 发送, Shift+Enter 换行" : "Ctrl+Enter 发送" }}
        </span>
      </div>
    </div>
  </div>
</template>

<script setup lang="ts">
import { ref, computed, watch, nextTick, onMounted } from "vue";
import {
  Paperclip,
  Image,
  Send,
  StopCircle,
  Sparkles,
  Globe,
  Maximize2,
  Minimize2,
  Brain,
  Loader2,
} from "@/components/icons";
import AttachmentPreview from "./AttachmentPreview.vue";
import { generateId } from "@/utils/helpers";
import type { Attachment } from "@/types/chat";
import { chatApi } from "@/services/api";

interface AttachmentWithProgress extends Attachment {
  uploading?: boolean;
  progress?: number;
}

const props = withDefaults(
  defineProps<{
    placeholder?: string;
    isStreaming?: boolean;
    sendOnEnter?: boolean;
    maxChars?: number;
    disabled?: boolean;
  }>(),
  {
    placeholder: "输入你的问题...",
    isStreaming: false,
    sendOnEnter: false,
    maxChars: 4000,
    disabled: false,
  },
);

const emit = defineEmits<{
  send: [
    text: string,
    attachments: Attachment[],
    options: { deepSearch: boolean; webSearch: boolean; deepThinking: boolean },
  ];
  stop: [];
}>();

// 响应式状态
const inputText = ref("");
const attachments = ref<AttachmentWithProgress[]>([]);
const isFocused = ref(false);
const isExpanded = ref(false);
const isDeepSearch = ref(
  JSON.parse(localStorage.getItem("isDeepSearch") || "false"),
);
const isDeepThinking = ref(
  JSON.parse(localStorage.getItem("isDeepThinking") || "false"),
);
const isWebSearch = ref(
  JSON.parse(localStorage.getItem("isWebSearch") || "false"),
);
// DOM引用
const textareaRef = ref<HTMLTextAreaElement | null>(null);
const fileInputRef = ref<HTMLInputElement | null>(null);
const imageInputRef = ref<HTMLInputElement | null>(null);

// 计算属性
const charCount = computed(() => inputText.value.length);
const isUploading = computed(() =>
  attachments.value.some((a) => a.uploading),
);
const canSend = computed(() => {
  return (
    (inputText.value.trim().length > 0 || attachments.value.length > 0) &&
    !props.disabled &&
    charCount.value <= props.maxChars &&
    !isUploading.value
  );
});

// 自动调整高度
function autoResize() {
  const textarea = textareaRef.value;
  if (!textarea) return;

  textarea.style.height = "auto";
  const maxHeight = isExpanded.value ? 400 : 160;
  textarea.style.height = `${Math.min(textarea.scrollHeight, maxHeight)}px`;
}

// 处理键盘事件
function handleKeydown(event: KeyboardEvent) {
  // Ctrl+Enter 或 Cmd+Enter 发送
  if ((event.ctrlKey || event.metaKey) && event.key === "Enter") {
    event.preventDefault();
    handleSend();
    return;
  }

  // Enter 发送（如果开启了这个选项且没有按 Shift）
  if (props.sendOnEnter && event.key === "Enter" && !event.shiftKey) {
    event.preventDefault();
    handleSend();
    return;
  }
}

// 发送消息
function handleSend() {
  if (!canSend.value) return;

  emit("send", inputText.value.trim(), [...attachments.value], {
    deepSearch: isDeepSearch.value,
    webSearch: isWebSearch.value,
    deepThinking: isDeepThinking.value,
  });

  // 重置状态
  inputText.value = "";
  attachments.value = [];
  // isDeepSearch.value = false;
  // isWebSearch.value = false;
  // isDeepThinking.value = false;

  nextTick(() => {
    autoResize();
  });
}

// 处理粘贴事件
async function handlePaste(event: ClipboardEvent) {
  const items = event.clipboardData?.items;
  if (!items) return;

  for (const item of items) {
    if (item.type.startsWith("image/")) {
      event.preventDefault();
      const file = item.getAsFile();
      if (file) {
        await addFileAsAttachment(file, "image");
      }
    }
  }
}

// 触发文件选择
function triggerFileInput() {
  fileInputRef.value?.click();
}

function triggerImageInput() {
  imageInputRef.value?.click();
}

// 处理文件选择
async function handleFileSelect(event: Event) {
  const input = event.target as HTMLInputElement;
  const files = input.files;
  if (!files) return;

  for (const file of files) {
    await addFileAsAttachment(file, "file");
  }

  input.value = "";
}

async function handleImageSelect(event: Event) {
  const input = event.target as HTMLInputElement;
  const files = input.files;
  if (!files) return;

  for (const file of files) {
    await addFileAsAttachment(file, "image");
  }

  input.value = "";
}

// 添加文件作为附件
async function addFileAsAttachment(
  file: File,
  type: "image" | "file" | "video",
) {
  const id = generateId();

  // 创建本地预览URL
  const url = URL.createObjectURL(file);

  const attachment: AttachmentWithProgress = {
    id,
    name: file.name,
    type,
    url,
    size: file.size,
    mimeType: file.type,
    uploading: true,
    progress: 0,
  };

  attachments.value.push(attachment);

  // 实际上传文件到服务器
  await uploadFileToServer(id, file);
}

// 上传文件到服务器
async function uploadFileToServer(id: string, file: File) {
  try {
    const uploadResult = await chatApi.uploadFile(file);

    const attachment = attachments.value.find((a) => a.id === id);
    if (attachment) {
      // 替换本地预览URL为服务器返回的真实URL
      attachment.url = uploadResult.url;
      attachment.uploading = false;
      attachment.progress = 100;
    }

    // 显示上传成功提示
    window.$toast && window.$toast('文件上传成功', 'success');
  } catch (error) {
    console.error('文件上传失败:', error);

    const attachment = attachments.value.find((a) => a.id === id);
    if (attachment) {
      attachment.uploading = false;
      // 设置错误状态或者移除附件
      removeAttachment(id);
    }

    // 显示错误提示
    window.$toast && window.$toast('文件上传失败，请重试', 'error');
  }
}

// 移除附件
function removeAttachment(id: string) {
  const index = attachments.value.findIndex((a) => a.id === id);
  if (index !== -1) {
    // 释放 blob URL
    URL.revokeObjectURL(attachments.value[index].url);
    attachments.value.splice(index, 1);
  }
}

// 切换功能（深度搜索与联网搜索互斥）
function toggleDeepSearch() {
  isDeepSearch.value = !isDeepSearch.value;
  if (isDeepSearch.value) {
    isWebSearch.value = false;
    localStorage.setItem("isWebSearch", "false");
  }
  localStorage.setItem("isDeepSearch", String(isDeepSearch.value));
}

function toggleDeepThink() {
  isDeepThinking.value = !isDeepThinking.value;
  localStorage.setItem("isDeepThinking", String(isDeepThinking.value));
}

function toggleWebSearch() {
  isWebSearch.value = !isWebSearch.value;
  if (isWebSearch.value) {
    isDeepSearch.value = false;
    localStorage.setItem("isDeepSearch", "false");
  }
  localStorage.setItem("isWebSearch", String(isWebSearch.value));
}

function toggleExpand() {
  isExpanded.value = !isExpanded.value;
  nextTick(() => {
    autoResize();
  });
}

// 暴露方法给父组件
function focus() {
  textareaRef.value?.focus();
}

function clear() {
  inputText.value = "";
  attachments.value = [];
  nextTick(() => {
    autoResize();
  });
}

defineExpose({
  focus,
  clear,
});

// 监听文本变化，自动调整高度
watch(inputText, () => {
  nextTick(() => {
    autoResize();
  });
});

onMounted(() => {
  autoResize();
});
</script>

<style lang="scss" scoped>
.chat-input-container {
  background: white;
  border: 2px solid #e2e8f0;
  border-radius: 20px;
  overflow: hidden;
  transition: all 0.2s ease;

  .dark & {
    background: #1e1e2e;
    border-color: #374151;
  }

  &.is-focused {
    border-color: #3b82f6;
    box-shadow: 0 0 0 4px rgba(59, 130, 246, 0.1);
  }

  &.is-expanded {
    .textarea-wrapper textarea {
      min-height: 200px;
    }
  }
}

.input-area {
  display: flex;
  align-items: flex-end;
  gap: 8px;
  padding: 12px 16px;
}

.input-actions {
  display: flex;
  align-items: center;
  gap: 4px;
  padding-bottom: 4px;

  &.left {
    flex-shrink: 0;
  }

  &.right {
    flex-shrink: 0;
  }
}

.action-btn {
  display: flex;
  align-items: center;
  justify-content: center;
  width: 38px;
  height: 38px;
  border: none;
  border-radius: 12px;
  background: transparent;
  color: #6b7280;
  cursor: pointer;
  transition: all 0.2s ease;

  &:hover {
    background: #f3f4f6;
    color: #374151;

    .dark & {
      background: #374151;
      color: #e5e7eb;
    }
  }

  &.send {
    background: #e5e7eb;
    color: #9ca3af;

    .dark & {
      background: #374151;
    }

    &.active {
      background: linear-gradient(135deg, #3b82f6 0%, #2563eb 100%);
      color: white;

      &:hover {
        transform: scale(1.05);
        box-shadow: 0 4px 12px rgba(59, 130, 246, 0.4);
      }
    }

    &.loading {
      background: linear-gradient(135deg, #3b82f6 0%, #2563eb 100%);
      color: white;
      cursor: wait;
    }

    &:disabled {
      cursor: not-allowed;
      opacity: 0.6;
    }
  }

  &.stop {
    background: linear-gradient(135deg, #ef4444 0%, #dc2626 100%);
    color: white;
    animation: pulse 2s infinite;

    &:hover {
      transform: scale(1.05);
    }
  }
}

.textarea-wrapper {
  flex: 1;
  min-width: 0;

  textarea {
    width: 100%;
    min-height: 24px;
    max-height: 160px;
    padding: 8px 0;
    border: none;
    outline: none;
    background: transparent;
    font-family: inherit;
    font-size: 15px;
    line-height: 1.5;
    color: #1f2937;
    resize: none;

    .dark & {
      color: #f3f4f6;
    }

    &::placeholder {
      color: #9ca3af;
    }
  }
}

.input-toolbar {
  display: flex;
  align-items: center;
  justify-content: space-between;
  padding: 8px 16px;
  border-top: 1px solid #f3f4f6;
  background: #fafbfc;

  .dark & {
    border-top-color: #2d2d3d;
    background: #181825;
  }
}

.toolbar-left {
  display: flex;
  align-items: center;
  gap: 6px;
}

.toolbar-btn {
  display: flex;
  align-items: center;
  gap: 6px;
  padding: 6px 12px;
  border: 1px solid transparent;
  border-radius: 8px;
  background: transparent;
  color: #6b7280;
  font-size: 13px;
  cursor: pointer;
  transition: all 0.2s ease;

  &:hover {
    background: #f3f4f6;
    color: #374151;

    .dark & {
      background: #2d2d3d;
      color: #e5e7eb;
    }
  }

  &.active {
    background: rgba(59, 130, 246, 0.1);
    border-color: rgba(59, 130, 246, 0.3);
    color: #3b82f6;

    svg {
      color: #3b82f6;
    }
  }
}

.toolbar-right {
  display: flex;
  align-items: center;
  gap: 16px;
}

.char-count {
  font-size: 12px;
  color: #9ca3af;

  &.warning {
    color: #f59e0b;
  }
}

.send-hint {
  font-size: 12px;
  color: #9ca3af;
}

@keyframes pulse {
  0%,
  100% {
    box-shadow: 0 0 0 0 rgba(239, 68, 68, 0.4);
  }
  50% {
    box-shadow: 0 0 0 8px rgba(239, 68, 68, 0);
  }
}
</style>
