<script setup lang="ts">
import type {ChatTimelineMessageItem, ChatTimelineToolApprovalPayload,} from '@easyflow/common-ui';
import {ChatTimeline} from '@easyflow/common-ui';

import type {AgentInfo, AgentKnowledgeBinding, AgentToolBinding,} from '../types';

import {onMounted, ref, watch} from 'vue';
import {BrushCleaning} from '@easyflow/icons';

import {ElButton, ElMessage} from 'element-plus';

import AiChatPanel from '#/components/ai-chat/AiChatPanel.vue';

import {approveAgentRun, rejectAgentRun} from '../api';
import {useAgentTryoutStream} from '../composables/useAgentTryoutStream';

const props = defineProps<{
  agent: AgentInfo;
  knowledgeBindings: AgentKnowledgeBinding[];
  toolBindings: AgentToolBinding[];
}>();

const emit = defineEmits<{ close: [] }>();

const {
  loading,
  clearDraftSession,
  markToolApproving,
  markToolRejected,
  copyMessageText,
  selectVariant,
  syncDraftContext,
  timelineItems,
  sendDraft,
  stop,
} = useAgentTryoutStream();
const approvalLoading = ref(false);

function getDraftContext() {
  return {
    agent: props.agent,
    toolBindings: props.toolBindings,
    knowledgeBindings: props.knowledgeBindings,
  };
}

function syncCurrentDraftContext(restore = false) {
  syncDraftContext(getDraftContext(), restore);
}

onMounted(() => {
  syncCurrentDraftContext(true);
});

watch(
  () => [props.agent.id, props.agent.localId],
  () => {
    syncCurrentDraftContext(true);
  },
);

watch(
  () => [props.agent, props.knowledgeBindings, props.toolBindings],
  () => {
    syncCurrentDraftContext();
  },
  { deep: true },
);

async function handleSend(prompt: string) {
  await sendDraft({
    ...getDraftContext(),
    prompt,
  });
}

function canCopyMessage(item: ChatTimelineMessageItem) {
  if (item.role === 'user') {
    return Boolean(copyMessageText(item).trim());
  }
  return Boolean(
    item.roundId && item.roundCompleted && copyMessageText(item).trim(),
  );
}

function canRegenerateMessage(item: ChatTimelineMessageItem) {
  return (
    item.role === 'assistant' &&
    Boolean(item.roundId) &&
    Boolean(item.roundCompleted)
  );
}

async function handleCopyMessage(item: ChatTimelineMessageItem) {
  const text = copyMessageText(item).trim();
  if (!text) {
    return;
  }
  try {
    await navigator.clipboard.writeText(text);
    ElMessage.success('已复制');
  } catch {
    ElMessage.error('复制失败');
  }
}

async function handleRegenerateMessage(item: ChatTimelineMessageItem) {
  void item;
}

function handleSelectPreviousVariant(item: ChatTimelineMessageItem) {
  selectVariant(item, 'previous');
}

function handleSelectNextVariant(item: ChatTimelineMessageItem) {
  selectVariant(item, 'next');
}

async function handleClearSession() {
  try {
    await clearDraftSession();
    ElMessage.success('已清理会话');
  } catch (error) {
    ElMessage.error(error instanceof Error ? error.message : '清理会话失败');
  }
}

function handleStop() {
  if (!loading.value) {
    return;
  }
  stop();
}

async function handleApprove(payload: ChatTimelineToolApprovalPayload) {
  approvalLoading.value = true;
  markToolApproving(payload);
  try {
    const res = await approveAgentRun(payload.requestId, payload.resumeToken);
    if (res.errorCode === 0) {
      ElMessage.success('已批准');
    }
  } catch (error) {
    markToolRejected({
      ...payload,
      reason: error instanceof Error ? error.message : '批准失败',
    });
    throw error;
  } finally {
    approvalLoading.value = false;
  }
}

async function handleReject(payload: ChatTimelineToolApprovalPayload) {
  approvalLoading.value = true;
  markToolRejected({
    ...payload,
    reason: '用户拒绝执行',
  });
  try {
    await rejectAgentRun(
      payload.requestId,
      payload.resumeToken,
      '用户拒绝执行',
    );
  } finally {
    approvalLoading.value = false;
  }
}
</script>

<template>
  <AiChatPanel
    :title="agent.name || '草稿试运行'"
    empty-text="输入问题试运行当前智能体"
    closable
    :messages="[]"
    :loading="loading"
    :approval-loading="approvalLoading"
    @send="handleSend"
    @stop="handleStop"
    @approve="handleApprove"
    @reject="handleReject"
    @close="emit('close')"
  >
    <template #headerActions>
      <ElButton
        :icon="BrushCleaning"
        circle
        text
        :disabled="approvalLoading"
        aria-label="清理会话"
        title="清理会话"
        @click="handleClearSession"
      />
    </template>
    <ChatTimeline
      :items="timelineItems"
      empty-text="输入问题试运行当前智能体"
      :approval-loading="approvalLoading"
      :copyable="canCopyMessage"
      :regenerable="canRegenerateMessage"
      :regenerate-disabled="true"
      @approve="handleApprove"
      @copy-message="handleCopyMessage"
      @regenerate-message="handleRegenerateMessage"
      @reject="handleReject"
      @select-next-variant="handleSelectNextVariant"
      @select-previous-variant="handleSelectPreviousVariant"
    />
  </AiChatPanel>
</template>
