<script setup lang="ts">
/* eslint-disable vue/no-mutating-props */
import type { AgentOption, AgentToolBinding } from '../types';

import { computed } from 'vue';

import {
  ElButton,
  ElEmpty,
  ElForm,
  ElFormItem,
  ElInput,
  ElOption,
  ElSelect,
  ElSwitch,
} from 'element-plus';

const props = defineProps<{
  binding: AgentToolBinding;
  kind: 'mcp' | 'plugin' | 'workflow';
  options: AgentOption[];
}>();

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

const SAFE_TOOL_NAME_PATTERN = /^[\w-]+$/;

function isSafeToolName(name?: string) {
  return SAFE_TOOL_NAME_PATTERN.test(String(name || ''));
}

function resolveToolName(option?: AgentOption) {
  const raw = option?.raw || {};
  if (isSafeToolName(raw.englishName)) {
    return String(raw.englishName);
  }
  if (isSafeToolName(raw.name)) {
    return String(raw.name);
  }
  const prefix = props.kind === 'workflow' ? 'workflow' : 'plugin';
  return `${prefix}_${option?.value || Date.now()}`;
}

function shouldSyncToolName() {
  const name = String(props.binding.toolName || '');
  if (!name) return true;
  const prefix = props.kind === 'workflow' ? 'workflow_' : 'plugin_';
  return name.startsWith(prefix);
}

const targetValue = computed({
  get() {
    return props.binding.targetId ? String(props.binding.targetId) : '';
  },
  set(value: string) {
    props.binding.targetId = value;
  },
});

const resourceLabel = computed(() => {
  if (props.kind === 'workflow') return '工作流';
  if (props.kind === 'mcp') return 'MCP';
  return '插件工具';
});

const selectedMcpTools = computed(() => {
  if (props.kind !== 'mcp') {
    return [];
  }
  const option = props.options.find(
    (item) => String(item.value) === String(props.binding.targetId),
  );
  const tools = option?.raw?.tools || props.binding.resourceSummary?.tools;
  return Array.isArray(tools) ? tools : [];
});

const selectedMcpToolCount = computed(() => selectedMcpTools.value.length);

const asyncExecutionEnabled = computed({
  get() {
    return String(props.binding.optionsJson?.executionMode || '').toUpperCase() === 'ASYNC';
  },
  set(value: boolean) {
    props.binding.optionsJson = {
      ...(props.binding.optionsJson || {}),
      executionMode: value ? 'ASYNC' : 'SYNC',
    };
    emit('change');
  },
});

function handleTargetChange(value: string) {
  const option = props.options.find(
    (item) => String(item.value) === String(value),
  );
  props.binding.resourceSummary = option?.raw || {};
  if (props.kind === 'mcp') {
    props.binding.targetId = option?.raw?.mcpId
      ? String(option.raw.mcpId)
      : value;
    props.binding.toolName = '';
    emit('change');
    return;
  }
  if (shouldSyncToolName()) {
    props.binding.toolName = resolveToolName(option);
  }
  emit('change');
}
</script>

<template>
  <ElForm label-position="top" class="agent-form">
    <ElFormItem :label="resourceLabel" required>
      <ElSelect
        v-model="targetValue"
        filterable
        placeholder="选择资源"
        @change="handleTargetChange"
      >
        <ElOption
          v-for="item in options"
          :key="item.value"
          :label="item.label"
          :value="item.value"
        />
      </ElSelect>
    </ElFormItem>
    <div v-if="kind === 'mcp'" class="agent-form__mcp-tools">
      <div class="agent-form__mcp-tools-header">
        <span>工具列表</span>
        <span>{{ selectedMcpToolCount }} 个</span>
      </div>
      <div v-if="selectedMcpTools.length > 0" class="agent-form__mcp-tool-list">
        <div
          v-for="tool in selectedMcpTools"
          :key="tool.name || tool.title"
          class="agent-form__mcp-tool"
        >
          <div class="agent-form__mcp-tool-name">
            {{ tool.name || tool.title || '未命名工具' }}
          </div>
          <div v-if="tool.description" class="agent-form__mcp-tool-desc">
            {{ tool.description }}
          </div>
        </div>
      </div>
      <ElEmpty v-else description="暂无工具" :image-size="64" />
    </div>
    <ElFormItem v-if="kind !== 'mcp'" label="工具名称" required>
      <ElInput
        v-model="binding.toolName"
        placeholder="仅支持英文、数字、下划线或中划线"
        @input="emit('change')"
      />
    </ElFormItem>
    <ElFormItem label="执行前确认">
      <ElSwitch v-model="binding.hitlEnabled" @change="emit('change')" />
    </ElFormItem>
    <ElFormItem v-if="kind !== 'mcp'" label="异步执行">
      <ElSwitch v-model="asyncExecutionEnabled" />
    </ElFormItem>
    <ElButton
      class="agent-form__danger"
      type="danger"
      plain
      @click="emit('remove')"
    >
      删除节点
    </ElButton>
  </ElForm>
</template>

<style scoped>
.agent-form {
  padding: 16px;
}

.agent-form :deep(.el-select) {
  width: 100%;
}

.agent-form__mcp-tools {
  margin-bottom: 16px;
}

.agent-form__mcp-tools-header {
  display: flex;
  align-items: center;
  justify-content: space-between;
  margin-bottom: 8px;
  font-size: 13px;
  font-weight: 600;
  color: var(--el-text-color-primary);
}

.agent-form__mcp-tools-header span:last-child {
  font-size: 12px;
  font-weight: 500;
  color: var(--el-text-color-secondary);
}

.agent-form__mcp-tool-list {
  display: flex;
  flex-direction: column;
  gap: 8px;
}

.agent-form__mcp-tool {
  padding: 10px 12px;
  background: var(--el-fill-color-lighter);
  border: 1px solid var(--el-border-color-lighter);
  border-radius: 8px;
}

.agent-form__mcp-tool-name {
  overflow: hidden;
  font-size: 13px;
  font-weight: 600;
  line-height: 20px;
  text-overflow: ellipsis;
  white-space: nowrap;
}

.agent-form__mcp-tool-desc {
  display: -webkit-box;
  margin-top: 4px;
  overflow: hidden;
  font-size: 12px;
  line-height: 18px;
  color: var(--el-text-color-secondary);
  -webkit-box-orient: vertical;
  -webkit-line-clamp: 2;
}

.agent-form__danger {
  width: 100%;
  margin-top: 8px;
}
</style>
