<template>
  <div class="subtitle-panel">
    <!-- 字幕模式下拉框 -->
    <div class="subtitle-header">
      <div class="dropdown-wrapper" :class="{ open: dropdownOpen }">
        <button class="dropdown-trigger" @click="dropdownOpen = !dropdownOpen">
          <span class="dropdown-label">{{ modeLabel }}</span>
          <svg
            class="dropdown-arrow"
            viewBox="0 0 24 24"
            width="14"
            height="14"
            fill="none"
            stroke="currentColor"
            stroke-width="2.5"
            stroke-linecap="round"
            stroke-linejoin="round"
          >
            <polyline points="6 9 12 15 18 9" />
          </svg>
        </button>
        <Transition name="dropdown">
          <div v-if="dropdownOpen" class="dropdown-menu">
            <button
              v-for="opt in modeOptions"
              :key="opt.value"
              class="dropdown-item"
              :class="{ active: currentMode === opt.value }"
              @click="selectMode(opt.value)"
            >
              <span class="item-icon">{{ opt.icon }}</span>
              <span class="item-label">{{ opt.label }}</span>
              <svg
                v-if="currentMode === opt.value"
                viewBox="0 0 24 24"
                width="14"
                height="14"
                fill="none"
                stroke="currentColor"
                stroke-width="3"
                stroke-linecap="round"
                stroke-linejoin="round"
              >
                <polyline points="20 6 9 17 4 12" />
              </svg>
            </button>
          </div>
        </Transition>
      </div>
    </div>

    <!-- 模式1：仅AI字幕 -->
    <div
      v-if="currentMode === 'ai-only'"
      class="subtitle-content ai-only-mode"
      ref="scrollContainerRef"
    >
      <div v-if="aiSubtitle" class="ai-subtitle-bar" ref="aiSubtitleBarRef">
        <div
          class="ai-subtitle-text"
          ref="aiSubtitleTextRef"
          :style="{ fontSize: aiFontSize + 'px' }"
        >
          {{ aiSubtitle }}
        </div>
        <!-- 滚动指示器 -->
        <div
          v-if="aiTextOverflow"
          class="scroll-hint"
          @click="scrollAIToBottom"
        >
          <svg
            viewBox="0 0 24 24"
            width="14"
            height="14"
            fill="none"
            stroke="currentColor"
            stroke-width="2"
            stroke-linecap="round"
          >
            <polyline points="6 9 12 15 18 9" />
          </svg>
        </div>
      </div>
      <div v-else class="subtitle-placeholder">
        <svg
          viewBox="0 0 24 24"
          width="20"
          height="20"
          fill="none"
          stroke="currentColor"
          stroke-width="1.5"
          stroke-linecap="round"
        >
          <path
            d="M21 15a2 2 0 0 1-2 2H7l-4 4V5a2 2 0 0 1 2-2h14a2 2 0 0 1 2 2z"
          />
        </svg>
        等待AI回复...
      </div>
    </div>

    <!-- 模式2：对话气泡 -->
    <div
      v-if="currentMode === 'bubble'"
      class="subtitle-content bubble-mode"
      ref="scrollContainerRef"
    >
      <div v-if="messages.length === 0" class="subtitle-placeholder">
        <svg
          viewBox="0 0 24 24"
          width="20"
          height="20"
          fill="none"
          stroke="currentColor"
          stroke-width="1.5"
          stroke-linecap="round"
        >
          <path
            d="M21 15a2 2 0 0 1-2 2H7l-4 4V5a2 2 0 0 1 2-2h14a2 2 0 0 1 2 2z"
          />
        </svg>
        等待对话开始...
      </div>
      <div class="chat-list" ref="chatListRef">
        <div
          v-for="msg in messages"
          :key="msg.id"
          :class="[
            'chat-bubble',
            msg.role === 'user' ? 'bubble-user' : 'bubble-ai',
          ]"
        >
          <div class="bubble-body">
            <div
              class="bubble-text"
              :class="{
                collapsed: isCollapsed(msg.id) && isLongText(msg.content),
                'text-user': msg.role === 'user',
                'text-ai': msg.role === 'ai',
              }"
              :ref="(el) => setMsgRef(msg.id, el)"
            >
              {{ msg.content }}
            </div>
            <button
              v-if="isLongText(msg.content)"
              class="expand-btn"
              @click="toggleCollapse(msg.id)"
            >
              {{ isCollapsed(msg.id) ? "展开全部" : "收起" }}
              <svg
                viewBox="0 0 24 24"
                width="12"
                height="12"
                fill="none"
                stroke="currentColor"
                stroke-width="2.5"
                stroke-linecap="round"
                stroke-linejoin="round"
                :style="{
                  transform: isCollapsed(msg.id)
                    ? 'rotate(0deg)'
                    : 'rotate(180deg)',
                  transition: 'transform 0.2s',
                }"
              >
                <polyline points="6 9 12 15 18 9" />
              </svg>
            </button>
          </div>
        </div>
      </div>
    </div>

    <!-- 模式3：合并气泡 -->
    <div
      v-if="currentMode === 'merged'"
      class="subtitle-content merged-mode"
      ref="scrollContainerRef"
    >
      <div v-if="messages.length === 0" class="subtitle-placeholder">
        <svg
          viewBox="0 0 24 24"
          width="20"
          height="20"
          fill="none"
          stroke="currentColor"
          stroke-width="1.5"
          stroke-linecap="round"
        >
          <path
            d="M21 15a2 2 0 0 1-2 2H7l-4 4V5a2 2 0 0 1 2-2h14a2 2 0 0 1 2 2z"
          />
        </svg>
        等待对话开始...
      </div>
      <div class="merged-list" ref="mergedListRef">
        <div
          v-for="(pair, idx) in pairedMessages"
          :key="idx"
          class="merged-bubble"
        >
          <div v-if="pair.user" class="merged-user-section">
            <div
              class="merged-text text-user"
              :class="{
                collapsed:
                  isCollapsed(pair.user.id) && isLongText(pair.user.content),
              }"
            >
              {{ pair.user.content }}
            </div>
            <button
              v-if="isLongText(pair.user.content)"
              class="expand-btn"
              @click="toggleCollapse(pair.user.id)"
            >
              {{ isCollapsed(pair.user.id) ? "展开全部" : "收起" }}
              <svg
                viewBox="0 0 24 24"
                width="12"
                height="12"
                fill="none"
                stroke="currentColor"
                stroke-width="2.5"
                stroke-linecap="round"
                stroke-linejoin="round"
                :style="{
                  transform: isCollapsed(pair.user.id)
                    ? 'rotate(0deg)'
                    : 'rotate(180deg)',
                  transition: 'transform 0.2s',
                }"
              >
                <polyline points="6 9 12 15 18 9" />
              </svg>
            </button>
          </div>
          <div v-if="pair.ai" class="merged-ai-section">
            <div
              class="merged-text text-ai"
              :class="{
                collapsed:
                  isCollapsed(pair.ai.id) && isLongText(pair.ai.content),
              }"
            >
              {{ pair.ai.content }}
            </div>
            <button
              v-if="isLongText(pair.ai.content)"
              class="expand-btn"
              @click="toggleCollapse(pair.ai.id)"
            >
              {{ isCollapsed(pair.ai.id) ? "展开全部" : "收起" }}
              <svg
                viewBox="0 0 24 24"
                width="12"
                height="12"
                fill="none"
                stroke="currentColor"
                stroke-width="2.5"
                stroke-linecap="round"
                stroke-linejoin="round"
                :style="{
                  transform: isCollapsed(pair.ai.id)
                    ? 'rotate(0deg)'
                    : 'rotate(180deg)',
                  transition: 'transform 0.2s',
                }"
              >
                <polyline points="6 9 12 15 18 9" />
              </svg>
            </button>
          </div>
        </div>
      </div>
    </div>
  </div>
</template>

<script setup lang="ts">
import {
  ref,
  computed,
  watch,
  nextTick,
  onMounted,
  onBeforeUnmount,
} from "vue";
import type { ChatMessage, SubtitleMode } from "@/types";

const props = defineProps<{
  mode: SubtitleMode;
  aiSubtitle: string;
  userSubtitle: string;
  messages: ChatMessage[];
}>();

const emit = defineEmits<{
  "update:mode": [value: SubtitleMode];
}>();

const currentMode = computed({
  get: () => props.mode,
  set: (val: SubtitleMode) => emit("update:mode", val),
});

const dropdownOpen = ref(false);
// 滚动容器ref：指向 .subtitle-content（实际可滚动容器）
const scrollContainerRef = ref<HTMLElement | null>(null);
const aiSubtitleBarRef = ref<HTMLElement | null>(null);
const aiSubtitleTextRef = ref<HTMLElement | null>(null);

// ===== AI字幕自适应字号 =====
const aiFontSize = ref(18);
const aiTextOverflow = ref(false);

// 计算AI字幕字号：根据文本长度动态调整
const computeAIFontSize = () => {
  const text = props.aiSubtitle;
  if (!text) {
    aiFontSize.value = 18;
    return;
  }

  const len = text.length;
  if (len <= 50) aiFontSize.value = 18;
  else if (len <= 100) aiFontSize.value = 16;
  else if (len <= 200) aiFontSize.value = 14;
  else if (len <= 400) aiFontSize.value = 13;
  else aiFontSize.value = 12;
};

// 检测AI字幕是否溢出
const checkAIOverflow = () => {
  nextTick(() => {
    const bar = aiSubtitleBarRef.value;
    const textEl = aiSubtitleTextRef.value;
    if (bar && textEl) {
      aiTextOverflow.value = textEl.scrollHeight > bar.clientHeight + 4;
    }
  });
};

const scrollAIToBottom = () => {
  if (aiSubtitleBarRef.value) {
    aiSubtitleBarRef.value.scrollTo({
      top: aiSubtitleBarRef.value.scrollHeight,
      behavior: "smooth",
    });
  }
};

// ===== 长文本折叠/展开 =====
const COLLAPSE_THRESHOLD = 120; // 超过120字符视为长文本
const collapsedIds = ref<Set<string>>(new Set());
const msgRefs = new Map<string, HTMLElement>();

const isLongText = (text: string): boolean => text.length > COLLAPSE_THRESHOLD;

const isCollapsed = (id: string): boolean => collapsedIds.value.has(id);

const toggleCollapse = (id: string) => {
  if (collapsedIds.value.has(id)) {
    collapsedIds.value.delete(id);
  } else {
    collapsedIds.value.add(id);
  }
  // 触发响应式更新
  collapsedIds.value = new Set(collapsedIds.value);
};

const setMsgRef = (id: string, el: any) => {
  if (el) msgRefs.set(id, el as HTMLElement);
};

// ===== 下拉框 =====
const modeOptions = [
  { value: "ai-only" as SubtitleMode, label: "AI字幕", icon: "💬" },
  { value: "bubble" as SubtitleMode, label: "对话气泡", icon: "💭" },
  { value: "merged" as SubtitleMode, label: "合并气泡", icon: "📋" },
];

const modeLabel = computed(() => {
  return (
    modeOptions.find((o) => o.value === currentMode.value)?.label || "AI字幕"
  );
});

const selectMode = (val: SubtitleMode) => {
  currentMode.value = val;
  dropdownOpen.value = false;
};

const handleClickOutside = (e: MouseEvent) => {
  const target = e.target as HTMLElement;
  if (!target.closest(".dropdown-wrapper")) {
    dropdownOpen.value = false;
  }
};

onMounted(() => {
  document.addEventListener("click", handleClickOutside);
});

onBeforeUnmount(() => {
  document.removeEventListener("click", handleClickOutside);
});

// ===== 消息配对 =====
const pairedMessages = computed(() => {
  const pairs: { user: ChatMessage | null; ai: ChatMessage | null }[] = [];
  let currentPair: { user: ChatMessage | null; ai: ChatMessage | null } = {
    user: null,
    ai: null,
  };

  for (const msg of props.messages) {
    if (msg.role === "user") {
      if (currentPair.user) {
        pairs.push(currentPair);
        currentPair = { user: msg, ai: null };
      } else {
        currentPair.user = msg;
      }
    } else {
      currentPair.ai = msg;
      pairs.push(currentPair);
      currentPair = { user: null, ai: null };
    }
  }
  if (currentPair.user || currentPair.ai) {
    pairs.push(currentPair);
  }
  return pairs;
});

// ===== 监听变化 =====

// 模式切换时：立即刷新内容并滚动到底部
watch(
  () => props.mode,
  () => {
    computeAIFontSize();
    nextTick(() => {
      checkAIOverflow();
      scrollToBottom();
      // AI模式切换后确保字幕滚动到底部
      if (props.mode === "ai-only" && aiSubtitleBarRef.value) {
        aiSubtitleBarRef.value.scrollTo({
          top: aiSubtitleBarRef.value.scrollHeight,
          behavior: "instant" as ScrollBehavior,
        });
      }
    });
  },
);

// AI字幕变化时：自适应字号 + 检测溢出 + 自动滚动
watch(
  () => props.aiSubtitle,
  () => {
    computeAIFontSize();
    checkAIOverflow();
    // 自动滚动AI字幕到底部
    nextTick(() => {
      if (aiSubtitleBarRef.value) {
        aiSubtitleBarRef.value.scrollTo({
          top: aiSubtitleBarRef.value.scrollHeight,
          behavior: "smooth",
        });
      }
    });
  },
);

// 消息变化时：自动滚动到底部 + 新消息默认折叠
watch(
  () => props.messages.length,
  (newLen, oldLen) => {
    // 新增的消息默认折叠
    if (newLen > (oldLen ?? 0)) {
      for (let i = oldLen ?? 0; i < newLen; i++) {
        const msg = props.messages[i];
        if (msg && isLongText(msg.content)) {
          collapsedIds.value.add(msg.id);
        }
      }
      collapsedIds.value = new Set(collapsedIds.value);
    }

    nextTick(() => {
      scrollToBottom();
    });
  },
);

// 流式内容更新时：自动滚动到底部（消息数量不变但内容变化）
watch(
  () => {
    const msgs = props.messages;
    if (msgs.length === 0) return "";
    // 监听最后一条消息的内容变化，用于流式更新时自动滚动
    return msgs[msgs.length - 1].content;
  },
  () => {
    nextTick(() => {
      scrollToBottom();
    });
  },
);

/**
 * 将对话列表滚动到底部
 * 兼容不同内容量：内容少时无需滚动，内容超出可见区域时平滑滚动到底部
 */
const scrollToBottom = () => {
  const el = scrollContainerRef.value;
  if (!el) return;
  el.scrollTo({
    top: el.scrollHeight,
    behavior: "smooth",
  });
};
</script>

<style scoped lang="scss">
.subtitle-panel {
  display: flex;
  flex-direction: column;
  height: 100%;
}

/* ===== 下拉框 ===== */
.subtitle-header {
  display: flex;
  align-items: center;
  padding-bottom: 8px;
  border-bottom: 1px solid rgba(255, 255, 255, 0.06);
  margin-bottom: 8px;
  flex-shrink: 0;
}

.dropdown-wrapper {
  position: relative;
}

.dropdown-trigger {
  display: flex;
  align-items: center;
  gap: 8px;
  padding: 8px 14px;
  background: rgba(255, 255, 255, 0.06);
  border: 1px solid rgba(255, 255, 255, 0.1);
  border-radius: 10px;
  color: rgba(255, 255, 255, 0.75);
  cursor: pointer;
  font-size: 13px;
  font-weight: 500;
  transition: all 0.2s;

  &:hover {
    background: rgba(255, 255, 255, 0.1);
    border-color: rgba(255, 255, 255, 0.18);
  }

  .dropdown-wrapper.open & {
    background: rgba(255, 255, 255, 0.1);
    border-color: rgba(108, 140, 255, 0.4);
  }
}

.dropdown-arrow {
  transition: transform 0.2s ease;
  .dropdown-wrapper.open & {
    transform: rotate(180deg);
  }
}

.dropdown-menu {
  position: absolute;
  bottom: calc(100% + 8px);
  left: 0;
  min-width: 180px;
  background: rgba(20, 25, 50, 0.97);
  backdrop-filter: blur(24px);
  border: 1px solid rgba(255, 255, 255, 0.12);
  border-radius: 12px;
  padding: 6px;
  z-index: 100;
  box-shadow: 0 -8px 32px rgba(0, 0, 0, 0.5);
}

.dropdown-item {
  display: flex;
  align-items: center;
  gap: 10px;
  width: 100%;
  padding: 10px 14px;
  border-radius: 8px;
  border: none;
  background: none;
  color: rgba(255, 255, 255, 0.65);
  cursor: pointer;
  font-size: 13px;
  font-weight: 500;
  transition: all 0.15s;

  &:hover {
    background: rgba(255, 255, 255, 0.08);
    color: #fff;
  }
  &.active {
    background: rgba(108, 140, 255, 0.15);
    color: #6c8cff;
  }
  .item-icon {
    font-size: 14px;
  }
  .item-label {
    flex: 1;
    text-align: left;
  }
}

.dropdown-enter-active,
.dropdown-leave-active {
  transition: all 0.2s ease;
}
.dropdown-enter-from,
.dropdown-leave-to {
  opacity: 0;
  transform: translateY(6px) scale(0.96);
}

/* ===== 字幕内容 ===== */
.subtitle-content {
  flex: 1;
  min-height: 0;
  max-height: calc(30vh - 60px);
  overflow-y: auto;
  animation: contentFade 0.3s ease;

  &::-webkit-scrollbar {
    width: 2px;
  }
  &::-webkit-scrollbar-thumb {
    background: rgba(255, 255, 255, 0.12);
    border-radius: 2px;
  }
}

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

.subtitle-placeholder {
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 8px;
  height: 100%;
  color: rgba(255, 255, 255, 0.3);
  font-size: 14px;
}

/* ===== 模式1：AI字幕 ===== */
.ai-only-mode {
  display: flex;
  align-items: flex-end;
  padding-bottom: 4px;
}

.ai-subtitle-bar {
  width: 100%;
  max-height: 100%;
  overflow-y: auto;
  background: linear-gradient(
    135deg,
    rgba(108, 140, 255, 0.06) 0%,
    rgba(79, 110, 247, 0.03) 100%
  );
  border: 1px solid rgba(108, 140, 255, 0.06);
  border-radius: 8px;
  padding: 8px 12px;
  backdrop-filter: blur(4px);
  transition: all 0.3s ease;
  position: relative;

  &::-webkit-scrollbar {
    width: 2px;
  }
  &::-webkit-scrollbar-thumb {
    background: rgba(108, 140, 255, 0.15);
    border-radius: 2px;
  }
}

.ai-subtitle-text {
  line-height: 1.6;
  color: #ffffff;
  word-break: break-word;
  font-weight: 400;
  font-size: 14px;
  letter-spacing: 0.2px;
  transition: font-size 0.3s ease;
  text-shadow: 0 1px 4px rgba(0, 0, 0, 0.6);
}

.scroll-hint {
  position: sticky;
  bottom: 0;
  left: 50%;
  transform: translateX(-50%);
  display: flex;
  align-items: center;
  justify-content: center;
  width: 28px;
  height: 28px;
  border-radius: 50%;
  background: rgba(108, 140, 255, 0.3);
  color: rgba(255, 255, 255, 0.8);
  cursor: pointer;
  margin: 8px auto 0;
  transition: all 0.2s;

  &:hover {
    background: rgba(108, 140, 255, 0.5);
    transform: translateX(-50%) scale(1.1);
  }
}

/* ===== 模式2：对话气泡 ===== */
.bubble-mode {
  .chat-list {
    display: flex;
    flex-direction: column;
    gap: 8px;
    padding: 2px 0;
  }
}

.chat-bubble {
  animation: bubbleSlide 0.35s ease;

  &.bubble-user {
    .bubble-body {
      background: rgba(240, 242, 255, 0.92);
      border-color: rgba(79, 110, 247, 0.12);
      border-radius: 14px 14px 4px 14px;
      margin-left: 24px;
    }
  }

  &.bubble-ai {
    .bubble-body {
      background: rgba(20, 30, 50, 0.85);
      border-color: rgba(52, 211, 153, 0.12);
      border-radius: 14px 14px 14px 4px;
      margin-right: 24px;
    }
  }
}

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

.bubble-body {
  padding: 8px 12px;
  border: 1px solid;
  min-width: 0;
}

.bubble-text {
  font-size: 14px;
  line-height: 1.6;
  word-break: break-word;
  overflow: hidden;
  transition: max-height 0.35s ease;

  &.text-user {
    color: #1a1a1a;
    text-shadow: none;
  }

  &.text-ai {
    color: #ffffff;
    text-shadow: 0 1px 3px rgba(0, 0, 0, 0.5);
  }

  &.collapsed {
    max-height: 4.8em;
    position: relative;

    &::after {
      content: "";
      position: absolute;
      bottom: 0;
      left: 0;
      right: 0;
      height: 2em;
      background: linear-gradient(transparent, rgba(10, 14, 30, 0.5));
      pointer-events: none;
      border-radius: 0 0 8px 8px;
    }
  }
}

/* ===== 展开/收起按钮 ===== */
.expand-btn {
  display: inline-flex;
  align-items: center;
  gap: 4px;
  margin-top: 6px;
  padding: 3px 10px;
  background: rgba(255, 255, 255, 0.06);
  border: 1px solid rgba(255, 255, 255, 0.1);
  border-radius: 6px;
  color: rgba(255, 255, 255, 0.55);
  font-size: 11px;
  cursor: pointer;
  transition: all 0.2s;

  &:hover {
    background: rgba(255, 255, 255, 0.1);
    color: rgba(255, 255, 255, 0.8);
    border-color: rgba(255, 255, 255, 0.2);
  }
}

/* ===== 模式3：合并气泡 ===== */
.merged-mode {
  .merged-list {
    display: flex;
    flex-direction: column;
    gap: 8px;
    padding: 2px 0;
  }
}

.merged-bubble {
  background: rgba(255, 255, 255, 0.02);
  border: 1px solid rgba(255, 255, 255, 0.04);
  border-radius: 12px;
  overflow: hidden;
  animation: bubbleSlide 0.35s ease;
}

.merged-user-section {
  padding: 8px 12px;
  border-bottom: 1px solid rgba(79, 110, 247, 0.08);
}

.merged-ai-section {
  padding: 8px 12px;
}

.merged-text {
  font-size: 14px;
  line-height: 1.6;
  word-break: break-word;
  overflow: hidden;
  transition: max-height 0.35s ease;

  &.text-user {
    color: #303030ab;
    text-shadow: none;
  }

  &.text-ai {
    color: #ffffff;
    text-shadow: 0 1px 3px rgba(0, 0, 0, 0.5);
  }

  &.collapsed {
    max-height: 4.8em;
    position: relative;

    &::after {
      content: "";
      position: absolute;
      bottom: 0;
      left: 0;
      right: 0;
      height: 2em;
      background: linear-gradient(transparent, rgba(10, 14, 30, 0.5));
      pointer-events: none;
    }
  }
}
</style>
