import React, { useState, useEffect, useMemo } from 'react'; import ReactMarkdown from 'react-markdown'; import remarkGfm from 'remark-gfm'; import { useTheme } from '../../contexts/ThemeContext'; import { Edit2, Plus, Trash2, Check, X, ChevronDown, ChevronRight, Target, Users, Activity, BookOpen, Zap, AlertTriangle, Settings, FileText, Info, RefreshCw, AlertCircle, Brain, Save, } from 'lucide-react'; interface FieldRequirement { title: string; goal: string; must_cover: string[]; done_criteria: string[]; blockers: string[]; dependencies: string[]; evidence_needs: string[]; preferred_agents: string[]; style_notes: string; min_chars?: number; min_items?: number; } interface AgentData { id: string; name: string; dimension: string; expertise: string; relevant_fields: string[]; analysis_contract: string[]; } interface CoordinatorConfig { system_prompt_prefix?: string; round1_guidance?: string; middle_round_guidance?: string; final_round_guidance?: string; speaker_selection_rules?: string; focus_instruction_rules?: string; dependency_driving_rules?: string[]; consistency_check_rules?: string[]; revise_prompt_prefix?: string; } interface TemplateData { template_id: string; template_name: string; template_brief: string; usage_notes: string[]; report_schema: Record; report_examples: Record; field_requirements: Record; agents: AgentData[]; coordinator_config: CoordinatorConfig; } const FIELD_LABELS: Record = { template_id: '模板ID', template_name: '模板名称', template_brief: '模板简介', usage_notes: '使用说明', report_schema: '报告字段结构', report_examples: '报告字段示例', field_requirements: '字段要求配置', agents: '智能体配置', coordinator_config: '协调者配置', title: '字段标题', goal: '字段目标', must_cover: '必须覆盖内容', done_criteria: '完成标准', blockers: '阻塞条件', dependencies: '依赖字段', evidence_needs: '证据需求', preferred_agents: '推荐智能体', style_notes: '风格说明', min_chars: '最小字符数', min_items: '最小条目数', id: '智能体ID', name: '智能体名称', dimension: '分析维度', expertise: '专业能力', relevant_fields: '关联字段', analysis_contract: '分析契约', system_prompt_prefix: '系统提示词前缀', round1_guidance: '第一轮指导', middle_round_guidance: '中间轮指导', final_round_guidance: '最终轮指导', speaker_selection_rules: '发言者选择规则', focus_instruction_rules: '焦点指令规则', dependency_driving_rules: '依赖驱动规则', consistency_check_rules: '一致性检查规则', revise_prompt_prefix: '修改提示前缀', }; const REPORT_SCHEMA_LABELS: Record = { objective_analysis: '一、目的分析', target_actor_analysis: '二、目标行为体分析', expected_behavior_drivers: '三、预期行为及行为驱动因素分析', narrative_theme_design: '四、叙事主题设计', action_plan_list: '五、认知行动方案列表', }; interface AgentVisual { Icon: React.ElementType; lightCard: string; darkCard: string; iconLight: string; iconDark: string; tagLight: string; tagDark: string; } const AGENT_VISUALS: Record = { objective: { Icon: Target, lightCard: 'from-blue-50 to-sky-50 border-blue-200 hover:border-blue-400 hover:shadow-blue-200/60', darkCard: 'from-slate-900/80 to-blue-950/20 border-slate-700/70 hover:border-blue-500/40 hover:shadow-slate-950/50', iconLight: 'bg-blue-100 text-blue-600', iconDark: 'bg-slate-800/90 text-blue-300 ring-1 ring-blue-500/20', tagLight: 'bg-blue-100 text-blue-700 border-blue-200', tagDark: 'bg-slate-800/70 text-blue-200 border-blue-500/25', }, actor: { Icon: Users, lightCard: 'from-emerald-50 to-teal-50 border-emerald-200 hover:border-emerald-400 hover:shadow-emerald-200/60', darkCard: 'from-slate-900/80 to-emerald-950/20 border-slate-700/70 hover:border-emerald-500/40 hover:shadow-slate-950/50', iconLight: 'bg-emerald-100 text-emerald-600', iconDark: 'bg-slate-800/90 text-emerald-300 ring-1 ring-emerald-500/20', tagLight: 'bg-emerald-100 text-emerald-700 border-emerald-200', tagDark: 'bg-slate-800/70 text-emerald-200 border-emerald-500/25', }, behavior: { Icon: Activity, lightCard: 'from-amber-50 to-orange-50 border-amber-200 hover:border-amber-400 hover:shadow-amber-200/60', darkCard: 'from-slate-900/80 to-amber-950/20 border-slate-700/70 hover:border-amber-500/40 hover:shadow-slate-950/50', iconLight: 'bg-amber-100 text-amber-600', iconDark: 'bg-slate-800/90 text-amber-300 ring-1 ring-amber-500/20', tagLight: 'bg-amber-100 text-amber-700 border-amber-200', tagDark: 'bg-slate-800/70 text-amber-200 border-amber-500/25', }, narrative: { Icon: BookOpen, lightCard: 'from-purple-50 to-violet-50 border-purple-200 hover:border-purple-400 hover:shadow-purple-200/60', darkCard: 'from-slate-900/80 to-purple-950/20 border-slate-700/70 hover:border-purple-500/40 hover:shadow-slate-950/50', iconLight: 'bg-purple-100 text-purple-600', iconDark: 'bg-slate-800/90 text-purple-300 ring-1 ring-purple-500/20', tagLight: 'bg-purple-100 text-purple-700 border-purple-200', tagDark: 'bg-slate-800/70 text-purple-200 border-purple-500/25', }, action: { Icon: Zap, lightCard: 'from-indigo-50 to-slate-50 border-indigo-200 hover:border-indigo-400 hover:shadow-indigo-200/60', darkCard: 'from-slate-900/80 to-indigo-950/20 border-slate-700/70 hover:border-indigo-500/40 hover:shadow-slate-950/50', iconLight: 'bg-indigo-100 text-indigo-600', iconDark: 'bg-slate-800/90 text-indigo-300 ring-1 ring-indigo-500/20', tagLight: 'bg-indigo-100 text-indigo-700 border-indigo-200', tagDark: 'bg-slate-800/70 text-indigo-200 border-indigo-500/25', }, risk: { Icon: AlertTriangle, lightCard: 'from-rose-50 to-pink-50 border-rose-200 hover:border-rose-400 hover:shadow-rose-200/60', darkCard: 'from-slate-900/80 to-rose-950/20 border-slate-700/70 hover:border-rose-500/40 hover:shadow-slate-950/50', iconLight: 'bg-rose-100 text-rose-600', iconDark: 'bg-slate-800/90 text-rose-300 ring-1 ring-rose-500/20', tagLight: 'bg-rose-100 text-rose-700 border-rose-200', tagDark: 'bg-slate-800/70 text-rose-200 border-rose-500/25', }, }; const DEFAULT_VISUAL: AgentVisual = { Icon: Brain, lightCard: 'from-gray-50 to-slate-50 border-gray-200 hover:border-gray-400 hover:shadow-gray-200/60', darkCard: 'from-slate-900/80 to-slate-800/50 border-slate-700/70 hover:border-slate-500/50 hover:shadow-slate-950/50', iconLight: 'bg-gray-100 text-gray-600', iconDark: 'bg-slate-800/90 text-slate-300 ring-1 ring-slate-500/20', tagLight: 'bg-gray-100 text-gray-700 border-gray-200', tagDark: 'bg-slate-800/70 text-slate-200 border-slate-500/25', }; const mapFieldLabel = (v: string) => REPORT_SCHEMA_LABELS[v] || v; function EditableText({ value, onChange, isDark, multiline = false, }: { value: string; onChange: (v: string) => void; isDark: boolean; multiline?: boolean; }) { const [editing, setEditing] = useState(false); const [draft, setDraft] = useState(value); const confirm = () => { onChange(draft); setEditing(false); }; const cancel = () => { setDraft(value); setEditing(false); }; const inputCls = isDark ? 'bg-slate-800 border-blue-500/60 text-slate-100 focus:border-blue-400' : 'bg-white border-blue-300 text-gray-800 focus:border-blue-500'; if (editing) { return (
{multiline ? (