<script lang="ts" setup>
import type { AgentConfig, ModelConfig } from '../components/agent-config'
import type { AiMessage } from '@/store/ai'
import { useAiStore } from '@/store'
import {
  defaultModelAgentConfig,
  defaultModelConfig,
  generateMessageId,
} from '../components/agent-config'
import { fetchRecommendQuestions, streamMessage } from '../components/agent-service'
import AgentHeader from '../components/AgentHeader.vue'
import AgentInput from '../components/AgentInput.vue'
import AgentMessage from '../components/AgentMessage.vue'

definePage({
  style: {
    navigationBarTitleText: 'AI助手',
  },
})

const agentConfig = reactive<AgentConfig>({
  // 当前页面默认走模型直连；如需切回 bot，改成 ...defaultAgentConfig
  ...defaultModelAgentConfig,
})
const modelConfig = reactive<ModelConfig>({ ...defaultModelConfig })

const aiStore = useAiStore()

const paging = ref<any>(null)
const messages = ref<AiMessage[]>([])
const loading = ref(false)
const initQuestionCapsules = computed(() => agentConfig.initQuestions.slice(0, 3))
const shouldShowInitQuestionCapsules = computed(() => aiStore.messages.length === 0 && initQuestionCapsules.value.length > 0)

// 用于停止流：在新一轮发送时把上一轮的 controller 标记为 cancelled
let cancelFlag = false

onLoad(() => {
  // #ifdef MP-WEIXIN
  if (typeof wx !== 'undefined' && wx.cloud) {
    wx.cloud.init({
      env: agentConfig.cloudEnvId,
      traceUser: true,
    })
  }
  // #endif

  aiStore.ensureThreadId()
})

// z-paging 聊天模式：第一页直接把 store 里的历史灌给它
// 聊天模式数据约定：数组下标 0 = 视觉最底部（最新消息），所以要倒序传入
function queryList() {
  const welcomeMsg = agentConfig.welcomeMsg?.trim()

  if (aiStore.messages.length === 0 && welcomeMsg) {
    aiStore.addMessage({
      id: generateMessageId(),
      role: 'assistant',
      content: welcomeMsg,
      createdAt: Date.now(),
    })
  }
  paging.value?.complete(aiStore.messages.slice().reverse())
}

async function handleSend(text: string) {
  if (loading.value) {
    return
  }
  cancelFlag = false
  loading.value = true

  const userMsg: AiMessage = {
    id: generateMessageId(),
    role: 'user',
    content: text,
    createdAt: Date.now(),
  }
  const aiMsg: AiMessage = {
    id: generateMessageId(),
    role: 'assistant',
    content: '',
    pending: true,
    // +1 防止与 userMsg 同毫秒下时间戳相等
    createdAt: Date.now() + 1,
  }

  // store 顺序：旧 → 新；z-paging 聊天模式 addChatRecordData 内部会反转 + 前插，
  // 最终 totalData = [aiMsg, userMsg, ...历史]，下标 0 = 视觉最底，符合"用户问 → AI 答在下方"
  aiStore.addMessage(userMsg)
  aiStore.addMessage(aiMsg)
  paging.value?.addChatRecordData([userMsg, aiMsg])

  try {
    await streamMessage({
      chatMode: agentConfig.chatMode,
      // bot 模式参数
      botId: agentConfig.botId,
      threadId: aiStore.ensureThreadId(),
      // model 模式参数
      modelProvider: modelConfig.modelProvider,
      quickResponseModel: modelConfig.quickResponseModel,
      // 倒数第二条之前是历史；当前 aiMsg 是占位，不传
      history: aiStore.messages.slice(0, -1),
      prompt: text,
      onDelta: (delta) => {
        if (cancelFlag) {
          return
        }
        aiStore.appendDelta(aiMsg.id, delta)
      },
      onError: (msg) => {
        aiStore.updateMessage(aiMsg.id, {
          error: true,
          pending: false,
          content: msg,
        })
      },
    })

    aiStore.updateMessage(aiMsg.id, { pending: false })

    // 当前 V2 agent 后端不支持 getRecommendQuestions（端点 404），先关掉这一调用。
    // 等切换到 bot-xxx 旧版 agent 或后端补上对应路由再开启。
    if (!cancelFlag) {
      void loadRecommendQuestions(aiMsg.id, text)
    }
  }
  catch (err) {
    aiStore.updateMessage(aiMsg.id, {
      pending: false,
      error: true,
      content: aiStore.messages.find(m => m.id === aiMsg.id)?.content
        || (err instanceof Error ? err.message : '生成失败'),
    })
  }
  finally {
    loading.value = false
  }
}

function handleStop() {
  cancelFlag = true
  loading.value = false
  // 把仍在 pending 的消息收尾
  const pending = aiStore.messages.find(m => m.pending)
  if (pending) {
    aiStore.updateMessage(pending.id, { pending: false })
  }
}

function handleRetry(id: string) {
  const failedIdx = aiStore.messages.findIndex(m => m.id === id)
  if (failedIdx <= 0) {
    return
  }
  const userMsg = aiStore.messages[failedIdx - 1]
  if (!userMsg || userMsg.role !== 'user') {
    return
  }
  aiStore.removeMessage(id)
  handleSend(userMsg.content)
}

function handleClickQuestion(question: string) {
  handleSend(question)
}

/** 请求追问建议，结果挂到对应 AI 消息的 recommendQuestions */
async function loadRecommendQuestions(aiMsgId: string, prompt: string) {
  const last = aiStore.messages.slice(-2).map(m => ({
    role: m.role === 'user' ? ('user' as const) : ('assistant' as const),
    content: m.content,
  }))
  try {
    const questions = await fetchRecommendQuestions({
      botId: agentConfig.botId,
      lastPair: last,
      prompt,
      max: 3,
      onProgress: (qs) => {
        aiStore.updateMessage(aiMsgId, { recommendQuestions: qs })
      },
    })
    aiStore.updateMessage(aiMsgId, { recommendQuestions: questions })
  }
  catch (error) {
    console.error('[recommend]', error)
  }
}

function handleClear() {
  aiStore.clear()
  paging.value?.reload()
}
</script>

<template>
  <view class="h-screen w-full flex flex-col bg-[#F4F6FA]">
    <!-- 消息列表（聊天模式） -->
    <view class="min-h-0 flex-1">
      <z-paging
        ref="paging"
        v-model="messages"
        :default-page-size="50"
        :auto-show-system-loading="false"
        :loading-more-enabled="false"
        :show-refresher-when-reload="false"
        :show-loading-more-no-more-view="false"
        use-chat-record-mode
        auto-adjust-position-when-chat
        auto-to-bottom-when-chat
        :paging-style="{ backgroundColor: '#F4F6FA' }"
        @query="queryList"
      >
        <!-- 首屏推荐问题 -->
        <template v-if="shouldShowInitQuestionCapsules" #top>
          <agent-header
            :questions="initQuestionCapsules"
            @pick="handleClickQuestion"
          />
        </template>

        <template #default>
          <agent-message
            v-for="item in messages"
            :key="item.id"
            :message="item"
            :bot-name="agentConfig.botName"
            @retry="handleRetry"
            @pick-recommend="handleClickQuestion"
          />
        </template>

        <template #bottom>
          <view>
            <view class="text-[24rpx] text-[#999] text-center my-[16rpx]">AI建议仅供参考，请以官方政策为准</view>
            <agent-input
              :placeholder="agentConfig.placeholder"
              :loading="loading"
              @send="handleSend"
              @stop="handleStop"
              @clear="handleClear"
            />
          </view>
        </template>
        <template #empty>
          <view />
        </template>
      </z-paging>
    </view>
  </view>
</template>

<style lang="scss" scoped>
//
</style>
