<template>
  <NCard title="产物与会话历史">
    <NSpin :show="loading">
      <NCollapse v-if="hasAnyContent" :default-expanded-names="defaultExpandedNames">
        <!-- 产物：按阶段分组 -->
        <NCollapseItem
          v-for="phase in ARTIFACT_PHASES"
          :key="phase"
          :name="phase"
          :disabled="artifactsByPhase[phase].length === 0"
        >
          <template #header>
            <div class="flex items-center gap-2">
              <span class="font-medium">{{ PHASE_TITLE[phase] }}产物</span>
              <NTag size="tiny" :type="phase === currentPhase ? 'primary' : 'default'">
                {{ artifactsByPhase[phase].length }}
              </NTag>
              <span v-if="phase === currentPhase" class="text-xs text-blue-500">当前</span>
            </div>
          </template>

          <NList v-if="artifactsByPhase[phase].length > 0" :show-divider="false">
            <NListItem v-for="a in artifactsByPhase[phase]" :key="a.id">
              <NThing class="cursor-pointer" @click="toggleArtifact(a)">
                <template #header>
                  <span
                    class="text-sm font-medium"
                    :class="selectedArtifact?.id === a.id ? 'text-blue-600' : ''"
                    >v{{ a.version }}</span
                  >
                  <NTag v-if="a.source_message_id" size="tiny" class="ml-1"> AI </NTag>
                </template>
                <template #header-extra>
                  <span class="text-xs text-gray-400">
                    {{ formatDate(a.created_at) }}
                  </span>
                </template>
                <span v-if="a.note" class="text-xs text-gray-500">{{ a.note }}</span>
              </NThing>
            </NListItem>
          </NList>
          <NEmpty v-else description="暂无产物" size="small" />

          <!-- 选中产物内容预览 -->
          <div v-if="selectedArtifact && selectedArtifact.phase === phase" class="mt-3">
            <NDivider />
            <!-- eslint-disable vue/no-v-html -->
            <div class="prose prose-sm max-w-none" v-html="renderedArtifact" />
            <!-- eslint-enable vue/no-v-html -->
          </div>
        </NCollapseItem>

        <!-- AI 对话 -->
        <NCollapseItem name="conversations" :disabled="conversations.length === 0">
          <template #header>
            <div class="flex items-center gap-2">
              <span class="font-medium">AI 对话</span>
              <NTag size="tiny">
                {{ conversations.length }}
              </NTag>
            </div>
          </template>

          <NList v-if="conversations.length > 0" :show-divider="false">
            <NListItem v-for="c in conversations" :key="c.id">
              <NThing class="cursor-pointer" @click="goConversation(c)">
                <template #header>
                  <span
                    class="text-sm font-medium"
                    :class="selectedConversation?.id === c.id ? 'text-blue-600' : ''"
                  >
                    {{ c.title || '(未命名)' }}
                  </span>
                </template>
                <template #header-extra>
                  <span class="text-xs text-gray-400">
                    {{ formatDateTime(c.updated_at) }}
                  </span>
                </template>
              </NThing>
            </NListItem>
          </NList>
          <NEmpty v-else description="暂无对话" size="small" />
        </NCollapseItem>

        <!-- ACP 会话 -->
        <NCollapseItem name="acp-sessions" :disabled="acpSessions.length === 0">
          <template #header>
            <div class="flex items-center gap-2">
              <span class="font-medium">ACP 会话</span>
              <NTag size="tiny">
                {{ acpSessions.length }}
              </NTag>
            </div>
          </template>

          <NList v-if="acpSessions.length > 0" :show-divider="false">
            <NListItem v-for="s in acpSessions" :key="s.id">
              <NThing
                :class="workspaceSlug ? 'cursor-pointer' : ''"
                @click="workspaceSlug ? goAcpSession(s) : undefined"
              >
                <template #header>
                  <span class="font-mono text-sm">{{ s.branch }}</span>
                </template>
                <template #header-extra>
                  <SessionStatusBadge :status="s.status" />
                </template>
                <span class="text-xs text-gray-400">
                  {{ formatDateTime(s.started_at) }}
                  <template v-if="s.last_error"> · {{ s.last_error }}</template>
                </span>
              </NThing>
            </NListItem>
          </NList>
          <NEmpty v-else description="暂无会话" size="small" />
        </NCollapseItem>
      </NCollapse>

      <NEmpty v-else-if="!loading" description="暂无历史产物与会话" size="small" />
    </NSpin>
  </NCard>
</template>

<script setup lang="ts">
import { computed, onMounted, ref, watch } from 'vue'
import { useRouter } from 'vue-router'
import {
  NCard,
  NCollapse,
  NCollapseItem,
  NDivider,
  NEmpty,
  NList,
  NListItem,
  NSpin,
  NTag,
  NThing,
} from 'naive-ui'

import { chatApi, type Conversation } from '@/api/chat'
import { acpApi, type AcpSession } from '@/api/acp'
import type { Artifact, ArtifactPhase, Phase } from '@/api/projects'
import { md } from '@/utils/markdown'
import { formatDate, formatDateTime } from '@/utils/date'
import { useRequirementsStore } from '@/stores/requirements'
import SessionStatusBadge from '@/components/acp/SessionStatusBadge.vue'

const ARTIFACT_PHASES: ArtifactPhase[] = ['planning', 'prototyping', 'auditing']

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

const props = defineProps<{
  slug: string
  number: number
  requirementId: string
  workspaceSlug: string | null
  currentPhase?: Phase | null
}>()

const router = useRouter()
const store = useRequirementsStore()

const loading = ref(false)
const artifacts = ref<Artifact[]>([])
const conversations = ref<Conversation[]>([])
const acpSessions = ref<AcpSession[]>([])

const selectedArtifact = ref<Artifact | null>(null)
const selectedConversation = ref<Conversation | null>(null)

const artifactsByPhase = computed(() => {
  const map: Record<ArtifactPhase, Artifact[]> = {
    planning: [],
    prototyping: [],
    auditing: [],
  }
  for (const a of artifacts.value) {
    if (map[a.phase]) {
      map[a.phase].push(a)
    }
  }
  // 每个阶段内按版本号排序
  for (const phase of ARTIFACT_PHASES) {
    map[phase].sort((a, b) => a.version - b.version)
  }
  return map
})

const hasAnyContent = computed(
  () =>
    artifacts.value.length > 0 || conversations.value.length > 0 || acpSessions.value.length > 0,
)

// 默认展开有内容的第一项（优先当前阶段）
const defaultExpandedNames = ref<(ArtifactPhase | 'conversations' | 'acp-sessions')[]>([])
watch(
  [
    () => props.currentPhase,
    () => artifacts.value.length,
    () => conversations.value.length,
    () => acpSessions.value.length,
  ],
  () => {
    const names: (ArtifactPhase | 'conversations' | 'acp-sessions')[] = []
    if (props.currentPhase && (ARTIFACT_PHASES as Phase[]).includes(props.currentPhase)) {
      const cp = props.currentPhase as ArtifactPhase
      if (artifactsByPhase.value[cp].length > 0) names.push(cp)
    }
    for (const phase of ARTIFACT_PHASES) {
      if (artifactsByPhase.value[phase].length > 0 && !names.includes(phase)) {
        names.push(phase)
      }
    }
    if (conversations.value.length > 0) names.push('conversations')
    if (acpSessions.value.length > 0) names.push('acp-sessions')
    defaultExpandedNames.value = names.slice(0, 2) // 最多默认展开前两项，避免过长
  },
  { immediate: true },
)

const renderedArtifact = computed(() =>
  selectedArtifact.value ? md.render(selectedArtifact.value.content) : '',
)

function toggleArtifact(a: Artifact) {
  selectedArtifact.value = selectedArtifact.value?.id === a.id ? null : a
}

function goConversation(c: Conversation) {
  selectedConversation.value = c
  router.push({
    name: 'chat-detail',
    params: { conversationId: c.id },
  })
}

function goAcpSession(s: AcpSession) {
  if (!props.workspaceSlug) return
  router.push({
    name: 'acp-sessions-detail',
    params: { slug: props.slug, wsSlug: props.workspaceSlug, sessionId: s.id },
  })
}

async function refresh() {
  loading.value = true
  try {
    const [arts, convs, sessions] = await Promise.all([
      store.listArtifacts(props.slug, props.number),
      chatApi.listConversations({ requirement_id: props.requirementId }),
      acpApi.sessions.list({ requirement_id: props.requirementId }),
    ])
    artifacts.value = arts
    conversations.value = convs
    acpSessions.value = sessions
  } finally {
    loading.value = false
  }
}

onMounted(refresh)

defineExpose({ refresh })
</script>
