<template>
  <NCard
    :title="`AI 对话 · ${PHASE_TITLE[phase]}`"
    class="flex flex-col h-full"
    content-class="flex flex-col flex-1 min-h-0"
  >
    <!-- 会话选择条 -->
    <div class="flex items-center gap-2 mb-3">
      <NSelect
        :value="session.currentConversation.value?.id ?? null"
        :options="conversationOptions"
        placeholder="选择历史会话"
        size="small"
        class="flex-1"
        :disabled="creating"
        @update:value="onSelectConversation"
      />
      <NButton size="small" type="primary" secondary @click="openCreateForm"> 新建会话 </NButton>
    </div>

    <!-- 新建会话表单 -->
    <div v-if="showCreateForm" class="space-y-2 mb-3 border rounded p-3">
      <ModelSelector v-model:model-value="newModelId" />
      <NInput
        v-model:value="newSystemPrompt"
        type="textarea"
        placeholder="system prompt（已自动注入需求上下文，可修改）"
        :autosize="{ minRows: 4, maxRows: 10 }"
      />
      <NInput
        v-model:value="newFirstMessage"
        type="textarea"
        placeholder="首条消息（创建后自动发送；留空则只建会话不发送）"
        :autosize="{ minRows: 1, maxRows: 4 }"
      />
      <div class="flex justify-end gap-2">
        <NButton size="small" @click="showCreateForm = false"> 取消 </NButton>
        <NButton
          size="small"
          type="primary"
          :loading="creating"
          :disabled="!newModelId"
          @click="onCreateConversation"
        >
          创建并开始
        </NButton>
      </div>
    </div>

    <!-- 消息区 -->
    <div
      v-if="session.currentConversation.value"
      ref="scrollEl"
      class="flex-1 min-h-0 overflow-y-auto space-y-3 py-2"
    >
      <MessageBubble
        v-for="m in session.messages.value"
        :key="m.id"
        v-memo="[m.id, m.content, m.status]"
        :message="m"
        :savable="!readonly"
        :answer-disabled="readonly || session.isStreaming.value"
        @retry="session.retryMessage"
        @save="onSaveMessage"
        @answer-question="onAnswerQuestion"
      />
    </div>
    <div v-else class="flex-1 flex items-center justify-center text-neutral-400 text-sm">
      选择历史会话，或新建会话开始与 AI 讨论本阶段内容
    </div>

    <!-- 输入区 -->
    <div v-if="session.currentConversation.value" class="border-t pt-3 flex gap-2">
      <NInput
        v-model:value="draft"
        type="textarea"
        :autosize="{ minRows: 1, maxRows: 6 }"
        placeholder="发送消息（Enter 发送，Shift+Enter 换行）"
        :disabled="session.isStreaming.value"
        @keydown.enter.exact.prevent="send"
      />
      <NButton
        v-if="!session.isStreaming.value"
        type="primary"
        :disabled="!draft.trim()"
        @click="send"
      >
        发送
      </NButton>
      <NButton v-else type="warning" @click="session.cancelMessage"> 中断 </NButton>
    </div>

    <SaveArtifactModal
      v-model:show="showSaveModal"
      :slug="slug"
      :number="requirement.number"
      :phase="phase"
      :source-message="saveSource"
      @saved="emit('artifact-saved')"
    />
  </NCard>
</template>

<script setup lang="ts">
import { computed, nextTick, onMounted, onUnmounted, ref, watch } from 'vue'
import { NButton, NCard, NInput, NSelect } from 'naive-ui'

import { chatApi, type ChatMessage, type Conversation } from '@/api/chat'
import type { Artifact, ArtifactPhase, Requirement } from '@/api/projects'
import { formatDateTime } from '@/utils/date'
import { useConversationSession } from '@/composables/useConversationSession'
import {
  formatInteractiveQuestionAnswer,
  type InteractiveQuestionAnswer,
} from '@/utils/interactiveMessage'
import MessageBubble from '@/views/chat/components/MessageBubble.vue'
import ModelSelector from '@/views/chat/components/ModelSelector.vue'
import SaveArtifactModal from './SaveArtifactModal.vue'

const PHASE_TITLE: Record<ArtifactPhase, string> = {
  planning: '规划',
  prototyping: '原型设计',
  auditing: '评审',
}

// 新建会话默认首条消息：system prompt 仅随请求下发不产生消息，必须有一条
// 用户消息才能触发 AI 开始输出，"创建并开始"靠它兑现。
const DEFAULT_FIRST_MESSAGE = '请开始本阶段工作。'

const props = defineProps<{
  slug: string
  requirement: Requirement
  phase: ArtifactPhase
  // 上一阶段产物最新版（planning 无），注入新会话 system prompt。
  prevArtifact?: Artifact | null
  readonly?: boolean
}>()

const emit = defineEmits<{ 'artifact-saved': [] }>()

// 自有会话实例，与全局 /chat 页完全隔离。
const session = useConversationSession()

const conversations = ref<Conversation[]>([])
const showCreateForm = ref(false)
const newModelId = ref<string | undefined>(undefined)
const newSystemPrompt = ref('')
const newFirstMessage = ref(DEFAULT_FIRST_MESSAGE)
const creating = ref(false)
const draft = ref('')
const scrollEl = ref<HTMLElement | null>(null)
const showSaveModal = ref(false)
const saveSource = ref<ChatMessage | null>(null)

const conversationOptions = computed(() =>
  conversations.value.map((c) => ({
    label: `${c.title || '(未命名)'} · ${formatDateTime(c.updated_at)}`,
    value: c.id,
  })),
)

async function loadConversations() {
  conversations.value = await chatApi.listConversations({
    requirement_id: props.requirement.id,
  })
}

function openCreateForm() {
  // system prompt 的角色模板 + 需求/产物上下文已由服务端组装（internal/brief 经
  // composeHistory 注入 FK 上下文）。前端默认留空，仅在操作者想补充额外指令时手填。
  newSystemPrompt.value = ''
  newFirstMessage.value = DEFAULT_FIRST_MESSAGE
  showCreateForm.value = true
}

async function onCreateConversation() {
  if (!newModelId.value) return
  creating.value = true
  try {
    const conv = await chatApi.createConversation({
      model_id: newModelId.value,
      system_prompt: newSystemPrompt.value,
      project_id: props.requirement.project_id,
      requirement_id: props.requirement.id,
    })
    showCreateForm.value = false
    await loadConversations()
    await session.openConversation(conv.id)
    const first = newFirstMessage.value.trim()
    if (first) await session.sendMessage(first)
  } finally {
    creating.value = false
  }
}

async function onSelectConversation(id: string | null) {
  if (!id) return
  await session.openConversation(id)
}

async function send() {
  if (!draft.value.trim() || session.isStreaming.value) return
  const body = draft.value
  draft.value = ''
  await session.sendMessage(body)
}

async function onAnswerQuestion(answer: InteractiveQuestionAnswer) {
  if (props.readonly || session.isStreaming.value) return
  await session.sendMessage(formatInteractiveQuestionAnswer(answer))
}

function onSaveMessage(id: number) {
  const msg = session.messages.value.find((m) => m.id === id)
  if (!msg) return
  saveSource.value = msg
  showSaveModal.value = true
}

// 流式输出时自动滚到底部（同 ChatDetailView 的策略）。
let scrollPending = false
watch(
  () => [session.messages.value.length, session.messages.value.at(-1)?.content?.length ?? 0],
  () => {
    if (scrollPending) return
    scrollPending = true
    requestAnimationFrame(() => {
      scrollPending = false
      nextTick(() => {
        const el = scrollEl.value
        if (el) el.scrollTo(0, el.scrollHeight)
      })
    })
  },
)

// 阶段切换（父组件未卸载本组件时）重置会话面板状态。
watch(
  () => props.phase,
  () => {
    session.closeCurrent()
    draft.value = ''
    showCreateForm.value = false
    newSystemPrompt.value = ''
    newFirstMessage.value = DEFAULT_FIRST_MESSAGE
  },
)

onMounted(loadConversations)
onUnmounted(() => session.closeCurrent())
</script>
