/**
 * 项目详情和执行页面
 *
 * 标签页结构：
 * 1. 项目设置 - 编辑基本信息 + 创作方式选择 + 上传剧本/编辑灵感
 * 2. 全局设定生成 - 根据项目设置进行分析或生成
 * 3. 剧集创作 - 创作工作台（直接嵌入，包含剧集管理侧边栏）
 * 4. 记忆系统 - 故事记忆管理
 * 5. 审核系统 - 内容质量审核
 */
import { useState, useEffect, useRef, useCallback } from 'react'
import { useParams, useNavigate } from 'react-router-dom'
import { Card, Button, Descriptions, Tag, Space, Modal, message, Spin, Tabs, Form, Input, InputNumber, Upload, Alert, Popover, Select } from 'antd'
import { ArrowLeftOutlined, LoadingOutlined, ClockCircleOutlined, ScanOutlined, SettingOutlined, RobotOutlined, UploadOutlined, EditOutlined, SaveOutlined } from '@ant-design/icons'
import { useProjectStore } from '@/stores/projectStore'
import { useSkillStore } from '@/stores/skillStore'
import { projectService, Episode } from '@/services/projectService'
import { taskService, CreateTaskResponse } from '@/services/taskService'
import { TaskProgress } from '@/components/TaskProgressTracker'
import { SmartCanvas } from '@/components/Workspace/SmartCanvas'
import { DirectorInbox } from '@/components/Workspace/DirectorInbox'
import { LeftSidebar } from '@/components/Workspace/LeftSidebar'
import MemorySystem from './MemorySystem'
import ReviewConfig from './ReviewConfig'
import ReviewResults from './ReviewResults'

const { TabPane } = Tabs
const { TextArea } = Input

// AI辅助选项接口
interface AIAssistOptions {
  skills?: any[]
  customPrompt?: string
  injectAgent?: boolean
}

// Skill 选择器和自定义提示词组件
const SkillSelectorWithPrompt = ({
  title,
  icon,
  skills,
  selectedSkills,
  onSkillsChange,
  customPrompt,
  onPromptChange,
  description
}: {
  title: string
  icon: React.ReactNode
  skills: any[]
  selectedSkills: string[]
  onSkillsChange: (skills: string[]) => void
  customPrompt: string
  onPromptChange: (prompt: string) => void
  description?: string
}) => {
  const content = (
    <div style={{ width: '400px' }}>
      <div style={{ marginBottom: '12px', color: '#666', fontSize: '12px' }}>
        {description || '选择用于此 AI 生成任务的技能'}
      </div>
      <Select
        mode="multiple"
        style={{ width: '100%' }}
        placeholder="选择技能"
        value={selectedSkills}
        onChange={onSkillsChange}
        maxTagCount="responsive"
        options={skills.map(skill => ({
          value: skill.id,
          label: skill.name
        }))}
      />
      <div style={{ marginTop: '12px' }}>
        <Space wrap>
          {selectedSkills.map(skillId => {
            const skill = skills.find(s => s.id === skillId)
            return skill ? (
              <Tag
                key={skillId}
                closable
                onClose={() => onSkillsChange(selectedSkills.filter(id => id !== skillId))}
              >
                {skill.name}
              </Tag>
            ) : null
          })}
        </Space>
      </div>
      <div style={{ marginTop: '16px' }}>
        <div style={{ marginBottom: '8px', fontSize: '12px', color: '#666' }}>
          自定义提示词（可选）
        </div>
        <TextArea
          placeholder="添加额外的要求或上下文..."
          value={customPrompt}
          onChange={(e) => onPromptChange(e.target.value)}
          rows={3}
          style={{ fontSize: '12px' }}
        />
      </div>
    </div>
  )

  return (
    <Popover
      content={content}
      title={title}
      trigger="click"
      placement="bottomRight"
    >
      <Button
        icon={icon}
        size="small"
        type={(selectedSkills.length > 0 || customPrompt) ? 'primary' : 'default'}
      >
        {selectedSkills.length > 0 || customPrompt ? `已配置` : '配置'}
      </Button>
    </Popover>
  )
}

export const ProjectDetail = () => {
  const { id } = useParams<{ id: string }>()
  const navigate = useNavigate()

  // 调试：确认组件已加载
  console.log('=== ProjectDetail component loaded ===')
  console.log('id:', id)
  const { currentProject, projects, episodes, loading, error, fetchProject, fetchEpisodes, updateProject, updateEpisodeInList } = useProjectStore()
  const { skills, fetchSkills } = useSkillStore()
  const [selectedEpisode, setSelectedEpisode] = useState<Episode | null>(null)
  
  // Use location state to set initial tab if provided
  const [activeTab, setActiveTab] = useState('settings')

  useEffect(() => {
    // Check for activeTab in history state (passed from navigate)
    const state = (window.history.state?.usr as any);
    if (state?.activeTab) {
      setActiveTab(state.activeTab);
    }
    if (state?.reviewSubTab) {
      setReviewSubTab(state.reviewSubTab);
    }
  }, []);

  // 项目设置相关状态
  const [settingsForm] = Form.useForm()
  const [updatingSettings, setUpdatingSettings] = useState(false)
  const [creationMode, setCreationMode] = useState<'script' | 'inspiration' | null>(null)
  const [scriptContent, setScriptContent] = useState('')
  const [inspirationContent, setInspirationContent] = useState('')
  const [scriptEditing, setScriptEditing] = useState(false)
  const [inspirationEditing, setInspirationEditing] = useState(false)

  // 全局设定生成相关状态
  const [globalForm] = Form.useForm()
  const [generatingWorld, setGeneratingWorld] = useState(false)
  const [generatingCharacters, setGeneratingCharacters] = useState(false)
  const [generatingOutline, setGeneratingOutline] = useState(false)
  const [generatingAll, setGeneratingAll] = useState(false)

  // 顺序生成状态：跟踪当前完成到哪一步
  // 步骤：0=未开始, 1=世界观完成, 2=人物完成, 3=大纲完成
  const [generationStep, setGenerationStep] = useState(0)

  // 异步任务状态
  // const [activeTasks, setActiveTasks] = useState<Record<string, { type: string; status: string; progress: number }>>({})

  // Skills 配置
  const [worldSkills, setWorldSkills] = useState<string[]>([])
  const [characterSkills, setCharacterSkills] = useState<string[]>([])
  const [outlineSkills, setOutlineSkills] = useState<string[]>([])

  // 自定义提示词
  const [worldPrompt, setWorldPrompt] = useState('')
  const [characterPrompt, setCharacterPrompt] = useState('')
  const [outlinePrompt, setOutlinePrompt] = useState('')

  // 自定义 genre
  const [customGenre, setCustomGenre] = useState('')

  // 工作台相关状态
  const [wsConnected, setWsConnected] = useState(false)
  const [streaming, setStreaming] = useState(false)
  const [canvasContent, setCanvasContent] = useState<string>('')
  const [outlineContent, setOutlineContent] = useState<string>('')
  const [outlineStreaming, setOutlineStreaming] = useState(false)
  const [agentStatus, setAgentStatus] = useState<'idle' | 'planning' | 'writing' | 'reviewing'>('idle')
  const [agentPlan, setAgentPlan] = useState<string[]>([])
  const [inboxItems, setInboxItems] = useState<any[]>([])
  const [chatHistory, setChatHistory] = useState<{role: 'user' | 'agent', content: string}[]>([])
  const [annotations, setAnnotations] = useState<any[]>([])
  const [activeStates, setActiveStates] = useState<any[]>([
    { type: 'time', value: '初始状态' },
    { type: 'location', value: '未知地点' }
  ])
  const [workspaceMemoryItems, setWorkspaceMemoryItems] = useState<any[]>([])
  const [currentEpisodeInWorkspace, setCurrentEpisodeInWorkspace] = useState<Episode | null>(null)
  const [reviewSubTab, setReviewSubTab] = useState('config')

  // 执行和保存状态
  // const [executing, setExecuting] = useState(false)
  // const [savingContent, setSavingContent] = useState(false)

  // 工作台侧边栏宽度状态
  const [leftPanelWidth, setLeftPanelWidth] = useState(360)
  const [rightPanelWidth, setRightPanelWidth] = useState(280)
  const [isResizing, setIsResizing] = useState<'left' | 'right' | null>(null)
  const resizeStartRef = useRef<{ x: number; leftWidth: number; rightWidth: number } | null>(null)

  // 检查全局设定是否完成
  const globalSettingsCompleted = currentProject?.globalContext?.worldSetting?.trim() &&
    currentProject?.globalContext?.overallOutline?.trim()

  // WebSocket refs
  const wsRef = useRef<WebSocket | null>(null)
  const reconnectTimeoutRef = useRef<number | null>(null)

  // 拖拽调整侧边栏宽度
  useEffect(() => {
    const handleMouseMove = (e: MouseEvent) => {
      if (!isResizing || !resizeStartRef.current) return

      const deltaX = e.clientX - resizeStartRef.current.x

      if (isResizing === 'left') {
        const newWidth = Math.max(280, Math.min(600, resizeStartRef.current.leftWidth + deltaX))
        setLeftPanelWidth(newWidth)
      } else if (isResizing === 'right') {
        const newWidth = Math.max(220, Math.min(450, resizeStartRef.current.rightWidth - deltaX))
        setRightPanelWidth(newWidth)
      }
    }

    const handleMouseUp = () => {
      setIsResizing(null)
      resizeStartRef.current = null
    }

    if (isResizing) {
      document.addEventListener('mousemove', handleMouseMove)
      document.addEventListener('mouseup', handleMouseUp)
      document.body.style.userSelect = 'none'
      document.body.style.cursor = 'col-resize'
    }

    return () => {
      document.removeEventListener('mousemove', handleMouseMove)
      document.removeEventListener('mouseup', handleMouseUp)
      document.body.style.userSelect = ''
      document.body.style.cursor = ''
    }
  }, [isResizing])

  // 加载 Skills
  useEffect(() => {
    const loadSkills = async () => {
      try {
        await fetchSkills()
      } catch (error) {
        console.error('加载 Skills 失败:', error)
      }
    }
    loadSkills()
  }, [])

  // 加载项目数据后初始化
  useEffect(() => {
    if (currentProject) {
      // 初始化项目设置表单
      const genre = currentProject.genre || '古风'
      const isCustomGenre = !['古风', '现代', '科幻', '奇幻', '悬疑', '都市', '历史'].includes(genre)

      settingsForm.setFieldsValue({
        name: currentProject.name,
        totalEpisodes: currentProject.totalEpisodes,
        genre: isCustomGenre ? '其他' : genre
      })

      if (isCustomGenre) {
        setCustomGenre(genre)
      }

      // 确定创作方式
      const hasScript = currentProject.globalContext?.uploadedScript && currentProject.globalContext.uploadedScript.length > 0
      const hasInspiration = currentProject.globalContext?.inspiration && currentProject.globalContext.inspiration.length > 0

      if (hasScript) {
        setCreationMode('script')
        setScriptContent(currentProject.globalContext.uploadedScript || '')
        setScriptEditing(true)  // Show content editor when script exists
      } else if (hasInspiration) {
        setCreationMode('inspiration')
        setInspirationContent(currentProject.globalContext.inspiration || '')
        setInspirationEditing(true)  // Show content editor when inspiration exists
      }

      // 初始化全局设定表单
      const worldSetting = currentProject.globalContext?.worldSetting || ''
      const characters = currentProject.globalContext?.styleGuide || ''
      const overallOutline = currentProject.globalContext?.overallOutline || ''

      globalForm.setFieldsValue({
        worldSetting,
        characters,
        overallOutline
      })

      // 根据已有内容设置初始步骤
      let initialStep = 0
      if (worldSetting.trim()) initialStep = 1
      if (characters.trim()) initialStep = 2
      if (overallOutline.trim()) initialStep = 3
      setGenerationStep(initialStep)
    }
  }, [currentProject])

  useEffect(() => {
    if (id) {
      fetchProject(id)
      fetchEpisodes(id)
    }
  }, [id])

  // 上传剧本文件
  const handleScriptUpload = (file: any) => {
    const reader = new FileReader()
    reader.onload = (e) => {
      const content = e.target?.result as string || ''
      setScriptContent(content)
      setCreationMode('script')
      setScriptEditing(true)
      message.success('剧本上传成功！您可以编辑内容后点击保存')
    }
    reader.readAsText(file)
    return false
  }

  // 上传灵感文件
  const handleInspirationUpload = (file: any) => {
    const reader = new FileReader()
    reader.onload = (e) => {
      const content = e.target?.result as string || ''
      setInspirationContent(content)
      setCreationMode('inspiration')
      setInspirationEditing(true)
      message.success('灵感文件上传成功！您可以编辑内容后点击保存')
    }
    reader.readAsText(file)
    return false
  }

  // 保存项目设置
  const handleSaveSettings = async () => {
    try {
      await settingsForm.validateFields()

      // 验证必须选择了创作方式并填写了内容
      if (!creationMode) {
        message.error('请选择创作方式并填写相应内容')
        return
      }

      if (creationMode === 'script' && !scriptContent.trim()) {
        message.error('请上传或填写剧本内容')
        return
      }

      if (creationMode === 'inspiration' && !inspirationContent.trim()) {
        message.error('请上传或填写灵感内容')
        return
      }

      setUpdatingSettings(true)
      const values = settingsForm.getFieldsValue()

      // 处理 genre：如果是"其他"且有自定义输入，使用自定义值
      const genreValue = values.genre === '其他' ? (customGenre || '其他') : (values.genre || '古风')

      await updateProject(id!, {
        name: values.name,
        totalEpisodes: values.totalEpisodes,
        genre: genreValue,
        globalContext: {
          ...currentProject?.globalContext,
          uploadedScript: scriptContent,
          inspiration: inspirationContent
        }
      })

      message.success('项目设置已保存')
      await fetchProject(id!)

      // 自动跳转到全局设定生成标签页
      setActiveTab('global-generation')
    } catch (error: any) {
      if (error.errorFields) {
        return
      }
      message.error(`保存失败: ${error.message || '未知错误'}`)
    } finally {
      setUpdatingSettings(false)
    }
  }

  // 轮询任务状态的辅助函数（非阻塞）
  const monitorTask = async (taskId: string, _type: string) => {
    try {
      // 添加到活动任务
      /*
      setActiveTasks(prev => ({
        ...prev,
        [taskId]: { type, status: 'running', progress: 0 }
      }))
      */

      // 使用轮询但不会阻塞UI
      const checkInterval = setInterval(async () => {
        try {
          const task = (await taskService.getTask(taskId)) as unknown as TaskProgress

          // 兼容不同的进度格式
          /*
          const progressValue = typeof task.progress === 'number' ? task.progress :
                               (task.progress?.current || 0)

          setActiveTasks(prev => ({
            ...prev,
            [taskId]: { type, status: task.status || 'running', progress: progressValue }
          }))
          */

          if (task.status === 'completed') {
            clearInterval(checkInterval)
            /*
            setActiveTasks(prev => {
              const newTasks = { ...prev }
              delete newTasks[taskId]
              return newTasks
            })
            */
            return task.result
          }

          if (task.status === 'failed') {
            clearInterval(checkInterval)
            /*
            setActiveTasks(prev => {
              const newTasks = { ...prev }
              delete newTasks[taskId]
              return newTasks
            })
            */
            throw new Error(task.error || '任务执行失败')
          }
        } catch (err) {
          clearInterval(checkInterval)
          console.error('Task monitoring error:', err)
        }
      }, 1000)

      // 返回taskId供调用者跟踪
      return taskId
    } catch (error) {
      console.error('Failed to start task monitoring:', error)
      throw error
    }
  }

  // AI生成/分析世界观（完全异步）
  const handleGenerateWorld = async () => {
    if (!id) return
    if (generatingWorld) return // 防止重复点击

    const projectName = currentProject?.name || '未命名项目'
    const projectGenre = currentProject?.genre || '古风'
    const selectedSkillsInfo = skills.filter(s => worldSkills.includes(s.id))

    // 根据创作方式决定是分析还是生成（从项目数据中实时获取最新内容）
    const projectScript = currentProject?.globalContext?.uploadedScript || ''
    const projectInspiration = currentProject?.globalContext?.inspiration || ''

    // 如果有编辑中的内容，优先使用；否则使用项目中保存的内容
    const finalScript = scriptContent || projectScript
    const finalInspiration = inspirationContent || projectInspiration

    const isAnalysis = creationMode === 'script'
    const baseContent = isAnalysis ? finalScript : finalInspiration
    const idea = isAnalysis
      ? `分析以下剧本，提取世界观设定：\n${baseContent?.substring(0, 2000)}`
      : `项目名称：${projectName}\n创意灵感：\n${baseContent}`

    const hideMessage = message.loading(isAnalysis ? '正在分析剧本...' : '正在生成世界观设定...', 0)

    try {
      setGeneratingWorld(true)

      // 使用异步API创建任务
      const response = (await taskService.generateWorld({
        idea,
        projectName,
        genre: projectGenre,
        skills: selectedSkillsInfo.map(s => ({
          id: s.id,
          name: s.name,
          behavior: s.behavior_guide
        })),
        customPrompt: worldPrompt || undefined,
        projectId: id
      })) as unknown as CreateTaskResponse

      hideMessage()
      message.success('世界观生成任务已启动，可在后台进行')

      // 启动非阻塞监控
      monitorTask(response.taskId, 'world')

      // 立即返回，不等待完成
      setGenerationStep(1)
    } catch (error: any) {
      hideMessage()
      message.error(`生成失败: ${error.message || '未知错误'}`)
    } finally {
      setGeneratingWorld(false)
    }
  }

  // AI生成/分析人物设定（完全异步）
  const handleGenerateCharacters = async () => {
    if (!id) return
    if (generatingCharacters) return // 防止重复点击

    const projectName = currentProject?.name || '未命名项目'
    const projectGenre = currentProject?.genre || '古风'
    const totalEpisodes = currentProject?.totalEpisodes || 30
    const selectedSkillsInfo = skills.filter(s => characterSkills.includes(s.id))

    // 获取已生成的世界观设定，保证一致性
    const worldSetting = globalForm.getFieldValue('worldSetting') || ''

    // 从项目数据中实时获取最新内容
    const projectScript = currentProject?.globalContext?.uploadedScript || ''
    const projectInspiration = currentProject?.globalContext?.inspiration || ''

    // 如果有编辑中的内容，优先使用；否则使用项目中保存的内容
    const finalScript = scriptContent || projectScript
    const finalInspiration = inspirationContent || projectInspiration

    const isAnalysis = creationMode === 'script'
    const baseContent = isAnalysis ? finalScript : finalInspiration
    let idea = isAnalysis
      ? `分析以下剧本，提取人物设定：\n${baseContent?.substring(0, 2000)}`
      : `项目名称：${projectName}，总集数：${totalEpisodes}集\n创意灵感：\n${baseContent}`

    // 无论分析模式还是创作模式，如果已有世界观设定，都将其作为上下文注入
    // 这样可以确保生成的世界观能够影响人物设定的生成，保证连贯性
    if (worldSetting) {
      idea += `\n\n【世界观设定】\n${worldSetting}`
    }

    const hideMessage = message.loading(isAnalysis ? '正在分析人物设定...' : '正在生成人物设定...', 0)

    try {
      setGeneratingCharacters(true)

      // 使用异步API创建任务
      const response = (await taskService.generateCharacters({
        idea,
        projectName,
        genre: projectGenre,
        totalEpisodes,
        skills: selectedSkillsInfo.map(s => ({
          id: s.id,
          name: s.name,
          behavior: s.behavior_guide
        })),
        customPrompt: characterPrompt || undefined,
        projectId: id
      })) as unknown as CreateTaskResponse

      hideMessage()
      message.success('人物生成任务已启动，可在后台进行')

      // 启动非阻塞监控，并在完成后自动填充结果
      const taskId = response.taskId
      monitorTask(taskId, 'characters')

      // 设置完成后回调
      const checkInterval = setInterval(async () => {
        try {
          const task = (await taskService.getTask(taskId)) as unknown as TaskProgress
          if (task.status === 'completed') {
            clearInterval(checkInterval)
            const result = task.result
            const characters = result?.characters || result
            let characterText = ''
            if (typeof characters === 'string') {
              characterText = characters
            } else if (Array.isArray(characters)) {
              characterText = characters.map((c: any) => {
                if (typeof c === 'string') return c
                if (c.name) {
                  return c.lines ? `【${c.name}】出场 ${c.lines} 次` : `【${c.name}】`
                }
                return JSON.stringify(c)
              }).join('\n')
            } else {
              characterText = JSON.stringify(characters, null, 2)
            }
            globalForm.setFieldsValue({ characters: characterText })
            setGenerationStep(2)
            message.success(isAnalysis ? '人物设定分析完成！' : '人物设定生成完成！')
          }
          if (task.status === 'failed') {
            clearInterval(checkInterval)
            message.error(`人物生成失败: ${task.error || '未知错误'}`)
          }
        } catch (err) {
          clearInterval(checkInterval)
        }
      }, 2000)
    } catch (error: any) {
      hideMessage()
      message.error(`生成失败: ${error.message || '未知错误'}`)
    } finally {
      setGeneratingCharacters(false)
    }
  }

  // AI生成/分析大纲（完全异步）
  const handleGenerateOutline = async () => {
    if (!id) return
    if (generatingOutline) return // 防止重复点击

    const projectName = currentProject?.name || '未命名项目'
    const projectGenre = currentProject?.genre || '古风'
    const totalEpisodes = currentProject?.totalEpisodes || 30
    const selectedSkillsInfo = skills.filter(s => outlineSkills.includes(s.id))

    // 获取已生成的世界观设定和人物设定，保证一致性
    const worldSetting = globalForm.getFieldValue('worldSetting') || ''
    const characters = globalForm.getFieldValue('characters') || ''

    // 从项目数据中实时获取最新内容
    const projectScript = currentProject?.globalContext?.uploadedScript || ''
    const projectInspiration = currentProject?.globalContext?.inspiration || ''

    // 如果有编辑中的内容，优先使用；否则使用项目中保存的内容
    const finalScript = scriptContent || projectScript
    const finalInspiration = inspirationContent || projectInspiration

    const isAnalysis = creationMode === 'script'
    const baseContent = isAnalysis ? finalScript : finalInspiration
    let idea = isAnalysis
      ? `分析以下剧本，提取整体大纲：\n${baseContent?.substring(0, 2000)}`
      : `项目名称：${projectName}，总集数：${totalEpisodes}集\n创意灵感：\n${baseContent}`

    // 无论分析模式还是创作模式，如果已有世界观设定和人物设定，都将其作为上下文注入
    // 这样可以确保已生成的内容能够影响大纲的生成，保证连贯性
    if (worldSetting) {
      idea += `\n\n【世界观设定】\n${worldSetting}`
    }
    if (characters) {
      idea += `\n\n【人物设定】\n${characters}`
    }

    const hideMessage = message.loading(isAnalysis ? '正在分析整体大纲...' : '正在生成整体大纲...', 0)

    try {
      setGeneratingOutline(true)

      // 使用异步API创建任务
      const response = (await taskService.generateOutline({
        idea,
        totalEpisodes,
        genre: projectGenre,
        projectName,
        skills: selectedSkillsInfo.map(s => ({
          id: s.id,
          name: s.name,
          behavior: s.behavior_guide
        })),
        customPrompt: outlinePrompt || undefined,
        projectId: id
      })) as unknown as CreateTaskResponse

      hideMessage()
      message.success('大纲生成任务已启动，可在后台进行')

      // 启动非阻塞监控，并在完成后自动填充结果
      const taskId = response.taskId
      monitorTask(taskId, 'outline')

      // 设置完成后回调
      const checkInterval = setInterval(async () => {
        try {
          const task = (await taskService.getTask(taskId)) as unknown as TaskProgress
          if (task.status === 'completed') {
            clearInterval(checkInterval)
            const result = task.result
            const outline = result?.outline || result
            const outlineText = typeof outline === 'string' ? outline : JSON.stringify(outline, null, 2)
            globalForm.setFieldsValue({ overallOutline: outlineText })
            setGenerationStep(3)
            message.success(isAnalysis ? '整体大纲分析完成！' : '整体大纲生成完成！')
          }
          if (task.status === 'failed') {
            clearInterval(checkInterval)
            message.error(`大纲生成失败: ${task.error || '未知错误'}`)
          }
        } catch (err) {
          clearInterval(checkInterval)
        }
      }, 2000)
    } catch (error: any) {
      hideMessage()
      message.error(`生成失败: ${error.message || '未知错误'}`)
    } finally {
      setGeneratingOutline(false)
    }
  }

  // 一键生成全部（世界观 → 人物设定 → 大纲）
  /*
  const handleGenerateAll = async () => {
    if (!id) return
    if (generatingAll || generatingWorld || generatingCharacters || generatingOutline) return

    setGeneratingAll(true)

    try {
      // Step 1: 生成世界观
      message.info('开始生成世界观设定...')
      await handleGenerateWorld()

      // 等待一下再继续
      await new Promise(resolve => setTimeout(resolve, 1000))

      // Step 2: 生成人物设定（会使用已生成的世界观）
      message.info('开始生成人物设定...')
      await handleGenerateCharacters()

      // 等待一下再继续
      await new Promise(resolve => setTimeout(resolve, 1000))

      // Step 3: 生成大纲（会使用已生成的世界观和人物设定）
      message.info('开始生成整体大纲...')
      await handleGenerateOutline()

      // Step 4: 自动保存全局设定
      await handleSaveGlobalSettings()

      message.success('全局设定全部生成完成！')
    } catch (error: any) {
      message.error(`生成失败: ${error.message || '未知错误'}`)
    } finally {
      setGeneratingAll(false)
    }
  }
  */

  // 保存全局设定
  const handleSaveGlobalSettings = async () => {
    try {
      const worldSetting = globalForm.getFieldValue('worldSetting')
      const characters = globalForm.getFieldValue('characters')
      const overallOutline = globalForm.getFieldValue('overallOutline')

      await updateProject(id!, {
        globalContext: {
          ...currentProject?.globalContext,
          worldSetting: worldSetting || '',
          overallOutline: overallOutline || '',
          // 同时保存到两个字段以保持兼容性
          styleGuide: characters || '',
          characterProfiles: currentProject?.globalContext?.characterProfiles || {},
          sceneSettings: currentProject?.globalContext?.sceneSettings || {}
        }
      })

      message.success('全局设定已保存')
      await fetchProject(id!)
    } catch (error: any) {
      message.error(`保存失败: ${error.message || '未知错误'}`)
    }
  }

  // 执行剧集创作
  /*
  const handleExecuteEpisode = async (epNum: number) => {
    // setExecuting(true)
    try {
      await executeEpisode(id!, epNum)
      message.success(`EP${epNum} 创作完成！`)
      await fetchEpisodes(id!)
    } catch (error) {
      message.error(`创作失败: ${(error as Error).message}`)
    } finally {
      // setExecuting(false)
    }
  }
  */

  // ==================== 工作台 WebSocket 相关函数 ====================

  // WebSocket 连接逻辑
  const connectWorkspaceWebSocket = useCallback(() => {
    if (!id) return

    // 关闭现有连接
    if (wsRef.current && wsRef.current.readyState === WebSocket.OPEN) {
      wsRef.current.close()
    }

    const protocol = window.location.protocol === 'https:' ? 'wss:' : 'ws:'
    const host = window.location.host
    const wsUrl = `${protocol}//${host}/ws/projects/${id}/execute`

    const ws = new WebSocket(wsUrl)

    ws.onopen = () => {
      console.log('Workspace WebSocket Connected')
      setWsConnected(true)
      // 只在剧集创作标签页时显示连接成功消息
      if (activeTab === 'episodes') {
        message.success('已连接到 Agent Runtime')
      }
    }

    ws.onmessage = (event) => {
      try {
        const msg = JSON.parse(event.data)
        handleWorkspaceWebSocketMessage(msg)
      } catch (e) {
        console.error('Failed to parse WS message:', e)
      }
    }

    ws.onclose = () => {
      console.log('Workspace WebSocket Disconnected')
      setWsConnected(false)
      if (wsRef.current === ws) {
        wsRef.current = null
      }
    }

    ws.onerror = (error) => {
      console.error('Workspace WebSocket Error:', error)
    }

    wsRef.current = ws
  }, [id, activeTab])

  // WebSocket 消息处理
  const handleWorkspaceWebSocketMessage = (msg: any) => {
    switch (msg.type) {
      case 'connected':
        break
      case 'history':
        if (msg.messages) {
          setChatHistory(msg.messages)
        }
        break
      case 'thinking':
        break
      case 'text':
        setChatHistory(prev => {
          const lastMsg = prev[prev.length - 1]
          if (lastMsg && lastMsg.role === 'agent') {
            const newHistory = [...prev]
            newHistory[newHistory.length - 1] = {
              ...lastMsg,
              content: lastMsg.content + msg.content
            }
            return newHistory
          }
          return [...prev, { role: 'agent', content: msg.content }]
        })
        break
      case 'plan_update':
        if (msg.plan) {
          setAgentPlan(msg.plan)
        }
        if (msg.status) {
          setAgentStatus(msg.status)
        }
        break
      case 'review_request':
        setInboxItems(prev => [...prev, {
          id: msg.id || Date.now().toString(),
          type: 'review',
          title: msg.title || '需要审核',
          description: msg.description,
          status: 'pending',
          timestamp: Date.now()
        }])
        break
      case 'review_completed':
        // 处理审核完成消息
        if (msg.data) {
          const { score, passed, issue_count, issues } = msg.data
          // 显示审核结果通知
          if (passed) {
            message.success(`✅ 审核通过！得分: ${score?.toFixed(1) || 'N/A'}`)
          } else {
            message.warning(`⚠️ 审核发现问题！得分: ${score?.toFixed(1) || 'N/A'}，问题数: ${issue_count || 0}`)
          }
          // 如果有问题，添加到收件箱供用户查看
          if (issues && issues.length > 0) {
            setInboxItems(prev => [...prev, {
              id: `review_${Date.now()}`,
              type: 'review_card',
              title: `审核结果 - ${passed ? '通过' : '发现问题'}`,
              description: `发现 ${issues.length} 个问题。得分: ${score?.toFixed(1) || 'N/A'}`,
              status: passed ? 'approved' : 'pending',
              timestamp: Date.now(),
              reviewData: {
                score,
                passed,
                issues,
                episode_number: currentEpisodeInWorkspace?.number || 1
              }
            }])
          }
          // 更新 annotation 列表显示问题
          if (issues && issues.length > 0) {
            const newAnnotations = issues.map((issue: any) => ({
              content: `${issue.dimension}: ${issue.description}`,
              type: issue.severity || 'review',
              suggestion: issue.suggestion || '',
              timestamp: Date.now()
            }))
            setAnnotations(prev => [...prev, ...newAnnotations])
          }
        }
        break
      case 'annotation_add':
        setAnnotations(prev => [...prev, msg.annotation])
        break
      case 'context_update':
        if (msg.states) {
          setActiveStates(msg.states)
        }
        break
      case 'tool_call':
        const toolData = msg.data || {}
        const toolName = toolData.name || msg.name
        if (toolName === 'update_canvas' || toolName === 'write_file') {
          setStreaming(true)
          setAgentStatus('writing')
        } else {
          setAgentStatus('planning')
        }
        break
      case 'tool_result':
        setStreaming(false)
        break
      case 'canvas_update':
        if (msg.content) {
          setCanvasContent(msg.content)
        }
        break
      case 'outline_update':
        if (msg.content) {
          setOutlineContent(msg.content)
        }
        break
      case 'outline_streaming_start':
        setOutlineStreaming(true)
        break
      case 'outline_streaming_end':
        setOutlineStreaming(false)
        break
      case 'done':
        setAgentStatus('idle')
        setStreaming(false)
        break
      case 'error':
        message.error(msg.data?.message || 'Unknown error')
        setAgentStatus('idle')
        break
      case 'memory_update':
        // 处理记忆库更新
        if (msg.data) {
          setWorkspaceMemoryItems(prev => [...prev, {
            type: msg.data.type || msg.data.memory_type || 'timeline',
            title: msg.data.title || '记忆更新',
            description: msg.data.description || '',
            timestamp: msg.data.timestamp || Date.now(),
            character: msg.data.character,
            state: msg.data.state
          }])
        }
        break
      case 'memory_hit':
        // 添加到记忆库
        if (msg.data) {
          setWorkspaceMemoryItems(prev => [...prev, {
            type: msg.data.memory_type || 'timeline',
            title: msg.data.title || '记忆更新',
            description: msg.data.description || JSON.stringify(msg.data.data),
            timestamp: Date.now()
          }])
        }
        break
      case 'episode_updated':
        // 剧集信息更新（如标题）
        if (msg.data) {
          const episodeData = msg.data as Partial<Episode>;
          // 找到现有的完整剧集对象
          const existingEpisode = episodes.find(ep => ep.number === episodeData.number || ep.id === episodeData.id);
          if (existingEpisode) {
            // 合并数据创建完整的 Episode 对象
            const updatedEpisode: Episode = {
              ...existingEpisode,
              ...episodeData
            };
            // 1. 本地更新 Store 中的剧集列表
            updateEpisodeInList(updatedEpisode);

            // 2. 如果更新的是当前剧集，同步更新当前剧集状态
            if (currentEpisodeInWorkspace && updatedEpisode.number === currentEpisodeInWorkspace.number) {
              setCurrentEpisodeInWorkspace(updatedEpisode);
            }
          }
        }
        break
      case 'episode_saved':
        // Agent 保存剧集后的确认
        message.success(`剧集 ${msg.episode_number || ''} 已自动保存`)
        // 刷新剧集列表
        if (id) {
          fetchEpisodes(id)
        }
        break
    }
  }

  // Inbox 操作处理
  const handleWorkspaceInboxAction = (itemId: string, action: 'approve' | 'reject') => {
    setInboxItems(prev => prev.filter(item => item.id !== itemId))
    if (wsRef.current && wsRef.current.readyState === WebSocket.OPEN) {
      wsRef.current.send(JSON.stringify({
        type: 'inbox_action',
        itemId,
        action
      }))
    }
    message.success(action === 'approve' ? '已批准' : '已拒绝')
  }

  // Director 消息发送
  const handleDirectorMessage = (msg: string) => {
    setChatHistory(prev => [...prev, { role: 'user', content: msg }])

    if (wsRef.current && wsRef.current.readyState === WebSocket.OPEN) {
      const messagePayload = JSON.stringify({
        type: 'chat_message',
        content: msg,
        episodeNumber: currentEpisodeInWorkspace?.number,
        episodeTitle: currentEpisodeInWorkspace?.title
      })
      wsRef.current.send(messagePayload)

      if (msg.includes("开始")) {
        setAgentStatus('planning')
      }
    } else {
      message.error('Agent 连接未就绪')
    }
  }

  // 剧集内容变更处理
  const handleContentChange = (content: string) => {
    setCanvasContent(content)
  }

  // 剧集内容保存处理
  const handleContentSave = async (content: string) => {
    if (!currentEpisodeInWorkspace) {
      message.warning('请先选择一个剧集')
      return
    }

    // setSavingContent(true)
    try {
      const updatedEpisode = (await projectService.updateEpisode(id!, currentEpisodeInWorkspace.number, {
        content: content
      })) as unknown as Episode

      setCurrentEpisodeInWorkspace(updatedEpisode);
      message.success('剧集内容已保存');
    } catch (error) {
      console.error('Failed to save episode content:', error)
      message.error('保存失败')
    } finally {
      // setSavingContent(false)
    }
  }

  // 剧集标题变更处理
  const handleTitleChange = async (newTitle: string) => {
    if (!currentEpisodeInWorkspace) return;

    try {
      // 1. 先尝试通过 WebSocket 同步（如果 Agent 正在修改）
      if (wsRef.current && wsRef.current.readyState === WebSocket.OPEN) {
        wsRef.current.send(JSON.stringify({
          type: 'update_episode_title',
          episode_number: currentEpisodeInWorkspace.number,
          title: newTitle
        }));
      }

      // 2. 同时调用 API 持久化
      const updatedEpisode = (await projectService.updateEpisode(id!, currentEpisodeInWorkspace.number, {
        title: newTitle
      })) as unknown as Episode
      
      setCurrentEpisodeInWorkspace(updatedEpisode);
      
      // 3. 触发侧边栏同步更新
      updateEpisodeInList(updatedEpisode);
    } catch (error) {
      console.error('Failed to update title:', error);
      message.error('标题更新失败');
    }
  };

  // AI 辅助处理
  const handleAIAssist = (assistPrompt: string, options?: AIAssistOptions) => {
    if (!currentEpisodeInWorkspace) {
      message.warning('请先选择一个剧集')
      return
    }

    // 检查是否是"开始创作"场景（assistPrompt为空且customPrompt包含"创作"）
    const isStartCreation = !assistPrompt && options?.customPrompt && options.customPrompt.includes('创作');

    let fullPrompt = '';

    if (isStartCreation) {
      // 开始创作场景：直接发送customPrompt，让后端注入大纲
      fullPrompt = options.customPrompt + '\n\n';
      fullPrompt += `项目：《${currentProject?.name}》\n`;
      fullPrompt += `剧集：第${currentEpisodeInWorkspace.number}集 - ${currentEpisodeInWorkspace.title || '未命名'}\n`;
      fullPrompt += `重要：请直接调用 write_to_canvas(content="创作的完整内容", append=false) 工具来写入内容，不要只输出文本。`;
    } else {
      // AI辅助修改场景：注入当前内容和上下文
      fullPrompt = `我正在修改《${currentProject?.name}》第${currentEpisodeInWorkspace.number}集的内容。\n\n`;
      fullPrompt += `当前剧集标题：${currentEpisodeInWorkspace.title || '未命名'}\n`;
      if (canvasContent) {
        fullPrompt += `当前内容：\n${canvasContent}\n\n`;
      }
      fullPrompt += `修改要求：${assistPrompt}\n\n`;

      // 如果有自定义提示词，添加进去
      if (options?.customPrompt) {
        fullPrompt += `自定义要求：${options.customPrompt}\n\n`;
      }

      fullPrompt += `重要：请直接调用 write_to_canvas(content="优化后的完整内容", append=false) 工具来更新画布，不要只输出文本。`;
    }

    // 通过 WebSocket 发送 AI 辅助请求给 Agent（隐藏发送，不显示在聊天记录中）
    if (wsRef.current && wsRef.current.readyState === WebSocket.OPEN) {
      wsRef.current.send(JSON.stringify({
        type: 'chat_message',
        content: fullPrompt,
        episodeNumber: currentEpisodeInWorkspace?.number,
        episodeTitle: currentEpisodeInWorkspace?.title
      }));
      message.info('已发送 AI 辅助请求');
      setAgentStatus('planning');
    } else {
      message.error('Agent 连接未就绪');
    }
  }

  // 大纲内容变更处理
  const handleOutlineChange = (newOutline: string) => {
    setOutlineContent(newOutline)
  }

  // 大纲保存处理
  const handleOutlineSave = async (newOutline: string) => {
    if (!currentEpisodeInWorkspace) {
      message.warning('请先选择一个剧集')
      return
    }

    try {
      const updatedEpisode = (await projectService.updateEpisode(id!, currentEpisodeInWorkspace.number, {
        outline: newOutline
      })) as unknown as Episode

      // 更新本地状态
      setCurrentEpisodeInWorkspace(updatedEpisode)
      updateEpisodeInList(updatedEpisode)
      setOutlineContent(newOutline)

      message.success('大纲已保存')
    } catch (error) {
      console.error('Failed to save outline:', error)
      message.error('保存大纲失败')
    }
  }

  // 大纲AI辅助处理
  const handleOutlineAIAssist = (assistPrompt: string, options?: AIAssistOptions) => {
    if (!currentEpisodeInWorkspace) {
      message.warning('请先选择一个剧集')
      return
    }

    // 注入当前大纲内容和上下文
    let fullPrompt = `我正在修改《${currentProject?.name}》第${currentEpisodeInWorkspace.number}集的大纲。\n\n`
    fullPrompt += `当前剧集标题：${currentEpisodeInWorkspace.title || '未命名'}\n`
    if (outlineContent) {
      fullPrompt += `当前大纲：\n${outlineContent}\n\n`
    } else {
      fullPrompt += `当前大纲：空\n\n`
    }
    fullPrompt += `修改要求：${assistPrompt}\n\n`

    // 如果有自定义提示词，添加进去
    if (options?.customPrompt) {
      fullPrompt += `自定义要求：${options.customPrompt}\n\n`
    }

    fullPrompt += `重要：请直接调用 write_to_canvas(content="优化后的完整大纲", append=false) 工具来更新大纲编辑区，不要只输出文本。`
    fullPrompt += `\n注意：这是大纲内容，不是剧本内容。请专注于大纲的结构和逻辑。`

    // 通过 WebSocket 发送 AI 辅助请求给 Agent
    if (wsRef.current && wsRef.current.readyState === WebSocket.OPEN) {
      wsRef.current.send(JSON.stringify({
        type: 'chat_message',
        content: fullPrompt,
        episodeNumber: currentEpisodeInWorkspace?.number,
        episodeTitle: currentEpisodeInWorkspace?.title,
        contentType: 'outline'  // 标记这是大纲修改
      }))
      message.info('已发送大纲 AI 辅助请求')
      setAgentStatus('planning')
      setOutlineStreaming(true)
    } else {
      message.error('Agent 连接未就绪')
    }
  }

  // 当切换到剧集创作标签页时连接 WebSocket
  useEffect(() => {
    if (activeTab === 'episodes' && globalSettingsCompleted) {
      connectWorkspaceWebSocket()
    }

    return () => {
      if (reconnectTimeoutRef.current) {
        clearTimeout(reconnectTimeoutRef.current)
      }
      if (activeTab !== 'episodes' && wsRef.current) {
        wsRef.current.close()
        wsRef.current = null
      }
    }
  }, [activeTab, globalSettingsCompleted, connectWorkspaceWebSocket])

  // ==================== 工作台函数结束 ====================

  /*
  const getStatusColor = (status: string) => {
    const colors: Record<string, string> = {
      'pending': 'default',
      'writing': 'processing',
      'completed': 'success',
      'needs-review': 'warning'
    }
    return colors[status] || 'default'
  }

  const getStatusText = (status: string) => {
    const texts: Record<string, string> = {
      'pending': '待开始',
      'writing': '创作中',
      'completed': '已完成',
      'needs-review': '需审核'
    }
    return texts[status] || status
  }
  */

  // 检查是否可以进入全局设定生成
  const canProceedToGlobalGeneration = creationMode &&
    ((creationMode === 'script' && scriptContent.trim()) ||
     (creationMode === 'inspiration' && inspirationContent.trim()))

  // 错误处理
  if (error) {
    return (
      <div style={{ padding: '50px', textAlign: 'center' }}>
        <Alert
          message="加载失败"
          description={error}
          type="error"
          showIcon
          action={
            <Button type="primary" onClick={() => window.location.reload()}>
              刷新页面
            </Button>
          }
        />
      </div>
    )
  }

  // 加载中
  if (loading || !currentProject) {
    return (
      <div style={{ padding: '50px', textAlign: 'center' }}>
        <Spin size="large" />
      </div>
    )
  }

  const isAnalysisMode = creationMode === 'script'

  return (
    <div style={{ padding: '24px' }}>
      {/* 头部 */}
      <Card style={{ marginBottom: '16px' }}>
        <Space direction="vertical" style={{ width: '100%' }} size="middle">
          <div style={{ display: 'flex', justifyContent: 'space-between', alignItems: 'center' }}>
            <div>
              <Button
                icon={<ArrowLeftOutlined />}
                onClick={() => navigate('/projects')}
                style={{
                  marginRight: '16px',
                  borderRadius: '8px',
                  height: '40px',
                  fontWeight: 600,
                  transition: 'all 0.3s cubic-bezier(0.4, 0, 0.2, 1)',
                }}
                onMouseEnter={(e) => {
                  e.currentTarget.style.transform = 'translateX(-4px)'
                  e.currentTarget.style.boxShadow = '0 4px 12px rgba(22, 119, 255, 0.15)'
                }}
                onMouseLeave={(e) => {
                  e.currentTarget.style.transform = 'translateX(0)'
                  e.currentTarget.style.boxShadow = 'none'
                }}
              >
                返回项目列表
              </Button>
              <span style={{ fontSize: '14px', color: '#999', marginLeft: '8px' }}>
                共 {projects.length} 个项目
              </span>
            </div>
            <h1 style={{ margin: 0 }}>{currentProject.name}</h1>
          </div>
          <Descriptions column={2} size="small">
            <Descriptions.Item label="总集数">{currentProject.totalEpisodes}</Descriptions.Item>
            <Descriptions.Item label="模式">{currentProject.mode}</Descriptions.Item>
            <Descriptions.Item label="创建时间">
              {new Date(currentProject.createdAt).toLocaleString()}
            </Descriptions.Item>
            <Descriptions.Item label="Agent">{currentProject.agentId}</Descriptions.Item>
          </Descriptions>
        </Space>
      </Card>

      {/* 标签页 */}
      <Card>
        <Tabs activeKey={activeTab} onChange={setActiveTab}>
          {/* 项目设置标签页 */}
          <TabPane
            tab={
              <span>
                <SettingOutlined />
                项目设置
              </span>
            }
            key="settings"
          >
            <Alert
              message="项目基本设置"
              description="编辑项目信息，选择创作方式并上传/填写相关内容"
              type="info"
              showIcon
              style={{ marginBottom: '16px' }}
            />
            <Form form={settingsForm} layout="vertical" style={{ maxWidth: '800px' }}>
              <Form.Item label="项目名称" name="name" rules={[{ required: true, message: '请填写项目名称' }]}>
                <Input placeholder="例如：宫廷风云" />
              </Form.Item>

              <Form.Item label="总集数" name="totalEpisodes" rules={[{ required: true, message: '请填写总集数' }]}>
                <InputNumber min={1} max={500} style={{ width: '100%' }} />
              </Form.Item>

              <Form.Item label="类型/风格" name="genre" rules={[{ required: true, message: '请选择类型' }]}>
                <Select
                  placeholder="请选择类型"
                  onChange={(value) => {
                    if (value !== '其他') {
                      setCustomGenre('')
                    }
                  }}
                >
                  <Select.Option value="古风">古风</Select.Option>
                  <Select.Option value="现代">现代</Select.Option>
                  <Select.Option value="科幻">科幻</Select.Option>
                  <Select.Option value="奇幻">奇幻</Select.Option>
                  <Select.Option value="悬疑">悬疑</Select.Option>
                  <Select.Option value="都市">都市</Select.Option>
                  <Select.Option value="历史">历史</Select.Option>
                  <Select.Option value="其他">其他</Select.Option>
                </Select>
              </Form.Item>

              {/* 自定义 genre 输入框 */}
              <Form.Item noStyle shouldUpdate={(prevValues, currentValues) => prevValues.genre !== currentValues.genre}>
                {({ getFieldValue }) => {
                  const genre = getFieldValue('genre')
                  return genre === '其他' ? (
                    <Form.Item
                      label="自定义类型"
                      name="customGenre"
                      rules={[{ required: true, message: '请输入自定义类型' }]}
                    >
                      <Input
                        placeholder="例如：武侠、仙侠、校园等"
                        value={customGenre}
                        onChange={(e) => setCustomGenre(e.target.value)}
                      />
                    </Form.Item>
                  ) : null
                }}
              </Form.Item>

              {/* 创作方式选择 */}
              <Form.Item label="选择创作方式" required>
                <Space direction="vertical" style={{ width: '100%' }} size="middle">
                  <Card
                    size="small"
                    title="剧本改编"
                    style={{
                      cursor: 'pointer',
                      border: creationMode === 'script' ? '2px solid #1677ff' : undefined,
                      backgroundColor: creationMode === 'script' ? '#f0f5ff' : undefined
                    }}
                    onClick={() => {
                      setCreationMode('script')
                      setScriptEditing(true)
                    }}
                  >
                    <div onClick={(e) => e.stopPropagation()}>
                      <p style={{ margin: 0, marginBottom: '12px', color: '#666' }}>
                        上传现有剧本，AI将分析并提取世界观、人物设定和大纲
                      </p>
                      {!scriptEditing ? (
                        <Upload.Dragger
                          name="script"
                          multiple={false}
                          accept=".txt,.md,.docx"
                          showUploadList={false}
                          beforeUpload={handleScriptUpload}
                          style={{ padding: '16px' }}
                        >
                          <p className="ant-upload-drag-icon">
                            <UploadOutlined style={{ fontSize: '24px', color: '#1677ff' }} />
                          </p>
                          <p className="ant-upload-text">点击或拖拽文件到此区域上传剧本</p>
                          <p className="ant-upload-hint">支持 .txt, .md, .docx 格式</p>
                        </Upload.Dragger>
                      ) : (
                        <div>
                          <div style={{ display: 'flex', justifyContent: 'space-between', alignItems: 'center', marginBottom: '8px' }}>
                            <Space>
                              <Tag color="success">剧本内容 ({scriptContent.length} 字符)</Tag>
                              <Button size="small" icon={<EditOutlined />} onClick={() => setScriptEditing(true)}>
                                编辑
                              </Button>
                            </Space>
                          </div>
                          {scriptEditing && (
                            <>
                              <TextArea
                                value={scriptContent}
                                onChange={(e) => setScriptContent(e.target.value)}
                                rows={10}
                                placeholder="剧本内容..."
                                style={{ marginBottom: '8px' }}
                              />
                              <Space>
                                <Button size="small" onClick={() => setScriptEditing(false)}>
                                  完成编辑
                                </Button>
                                <Button size="small" danger onClick={() => setScriptContent('')}>
                                  清除内容
                                </Button>
                              </Space>
                            </>
                          )}
                        </div>
                      )}
                    </div>
                  </Card>

                  <Card
                    size="small"
                    title="从头创作"
                    style={{
                      cursor: 'pointer',
                      border: creationMode === 'inspiration' ? '2px solid #1677ff' : undefined,
                      backgroundColor: creationMode === 'inspiration' ? '#f0f5ff' : undefined
                    }}
                    onClick={() => {
                      setCreationMode('inspiration')
                      setInspirationEditing(true)
                    }}
                  >
                    <div onClick={(e) => e.stopPropagation()}>
                      <p style={{ margin: 0, marginBottom: '12px', color: '#666' }}>
                        描述您的创意灵感，AI将根据灵感生成完整的世界观、人物设定和大纲
                      </p>
                      {!inspirationEditing ? (
                        <>
                          <TextArea
                            placeholder="描述您的创意灵感、故事构思..."
                            rows={4}
                            value={inspirationContent}
                            onChange={(e) => setInspirationContent(e.target.value)}
                            style={{ marginBottom: '8px' }}
                          />
                          <div style={{ display: 'flex', justifyContent: 'space-between', alignItems: 'center' }}>
                            <span style={{ fontSize: '12px', color: '#999' }}>或上传灵感文件</span>
                            <Upload.Dragger
                              name="inspiration"
                              multiple={false}
                              accept=".txt,.md,.docx"
                              showUploadList={false}
                              beforeUpload={handleInspirationUpload}
                              style={{ padding: '12px', width: '300px' }}
                            >
                              <p className="ant-upload-drag-icon">
                                <UploadOutlined style={{ fontSize: '20px', color: '#1677ff' }} />
                              </p>
                              <p className="ant-upload-text">上传灵感文件</p>
                            </Upload.Dragger>
                          </div>
                        </>
                      ) : (
                          <div>
                            <div style={{ display: 'flex', justifyContent: 'space-between', alignItems: 'center', marginBottom: '8px' }}>
                              <Space>
                                <Tag color="processing">灵感内容 ({inspirationContent.length} 字符)</Tag>
                                <Button size="small" icon={<EditOutlined />} onClick={() => setInspirationEditing(true)}>
                                  编辑
                                </Button>
                              </Space>
                            </div>
                            <TextArea
                              value={inspirationContent}
                              onChange={(e) => setInspirationContent(e.target.value)}
                              rows={10}
                              placeholder="创意灵感内容..."
                              style={{ marginBottom: '8px' }}
                            />
                            <Space>
                              <Button size="small" onClick={() => setInspirationEditing(false)}>
                                完成编辑
                              </Button>
                              <Button size="small" danger onClick={() => setInspirationContent('')}>
                                清除内容
                              </Button>
                            </Space>
                          </div>
                        )}
                    </div>
                  </Card>
                </Space>
              </Form.Item>

              <Form.Item>
                <Space>
                  <Button type="primary" loading={updatingSettings} onClick={handleSaveSettings} icon={<SaveOutlined />}>
                    保存设置
                  </Button>
                  {canProceedToGlobalGeneration && (
                    <Button onClick={() => setActiveTab('global-generation')}>
                      下一步：全局设定生成
                    </Button>
                  )}
                </Space>
              </Form.Item>
            </Form>
          </TabPane>

          {/* 全局设定生成标签页 */}
          <TabPane
            tab={
              <span>
                <RobotOutlined />
                全局设定生成
              </span>
            }
            key="global-generation"
          >
            {!canProceedToGlobalGeneration ? (
              <Alert
                message="请先完成项目设置"
                description="请在项目设置中选择创作方式并填写剧本或灵感内容"
                type="warning"
                showIcon
                action={
                  <Button type="primary" onClick={() => setActiveTab('settings')}>
                    前往设置
                  </Button>
                }
              />
            ) : (
              <Space direction="vertical" size="large" style={{ width: '100%' }}>
                {/* 步骤进度显示 */}
                <Card size="small">
                  <Space direction="vertical" style={{ width: '100%' }} size="middle">
                    <div style={{ display: 'flex', alignItems: 'center', justifyContent: 'space-between' }}>
                      <span style={{ fontWeight: 600, fontSize: '14px' }}>生成步骤</span>
                      <span style={{ color: '#666', fontSize: '12px' }}>
                        {generationStep === 0 && '请按顺序依次生成'}
                        {generationStep === 1 && '世界观已完成，继续生成人物设定'}
                        {generationStep === 2 && '人物设定已完成，继续生成整体大纲'}
                        {generationStep === 3 && '全部完成！'}
                      </span>
                    </div>
                    <div style={{ display: 'flex', gap: '8px', alignItems: 'center' }}>
                      <div style={{
                        flex: 1,
                        height: '8px',
                        borderRadius: '4px',
                        background: generationStep >= 1 ? '#52c41a' : '#d9d9d9',
                        transition: 'all 0.3s'
                      }} />
                      <div style={{
                        flex: 1,
                        height: '8px',
                        borderRadius: '4px',
                        background: generationStep >= 2 ? '#52c41a' : '#d9d9d9',
                        transition: 'all 0.3s'
                      }} />
                      <div style={{
                        flex: 1,
                        height: '8px',
                        borderRadius: '4px',
                        background: generationStep >= 3 ? '#52c41a' : '#d9d9d9',
                        transition: 'all 0.3s'
                      }} />
                    </div>
                    <div style={{ display: 'flex', justifyContent: 'space-between', fontSize: '12px', color: '#666' }}>
                      <span>世界观</span>
                      <span>人物</span>
                      <span>大纲</span>
                    </div>
                  </Space>
                </Card>

                <Alert
                  message={isAnalysisMode ? "全局设定分析" : "全局设定生成"}
                  description={
                    isAnalysisMode
                      ? "AI将按顺序分析您上传的剧本：世界观 → 人物设定 → 整体大纲"
                      : "AI将按顺序根据您的创意生成：世界观设定 → 人物设定 → 整体大纲"
                  }
                  type="info"
                  showIcon
                />

                {/* 生成进度提示 */}
                {(generatingAll || generatingWorld || generatingCharacters || generatingOutline) && (
                  <Space direction="vertical" style={{ width: '100%' }}>
                    <div style={{ display: 'flex', alignItems: 'center', gap: '12px' }}>
                      <Spin size="small" />
                      <span style={{ color: '#666' }}>
                        {generatingAll ? '正在依次生成全部内容...' :
                         generatingWorld ? '正在生成世界观设定...' :
                         generatingCharacters ? '正在生成人物设定...' :
                         generatingOutline ? '正在生成整体大纲...' : ''}
                      </span>
                    </div>
                  </Space>
                )}

                <Form form={globalForm} layout="vertical">
                  {/* 世界观设定 */}
                  <Card
                    title={
                      <Space>
                        <span>世界观设定</span>
                        {generationStep >= 1 && <Tag color="success">已完成</Tag>}
                      </Space>
                    }
                    size="small"
                    extra={
                      <Space>
                        <SkillSelectorWithPrompt
                          title="配置世界观生成"
                          icon={<SettingOutlined />}
                          skills={skills}
                          selectedSkills={worldSkills}
                          onSkillsChange={setWorldSkills}
                          customPrompt={worldPrompt}
                          onPromptChange={setWorldPrompt}
                        />
                        <Button
                          type="primary"
                          size="small"
                          icon={generatingWorld ? <LoadingOutlined /> : <RobotOutlined />}
                          onClick={handleGenerateWorld}
                          disabled={generatingWorld || generatingCharacters || generatingOutline || generatingAll}
                        >
                          {isAnalysisMode ? 'AI 分析' : 'AI 生成'}
                        </Button>
                      </Space>
                    }
                    style={{ marginBottom: '16px', border: generationStep >= 1 ? '1px solid #52c41a' : undefined }}
                  >
                    <Form.Item name="worldSetting">
                      <TextArea
                        rows={6}
                        placeholder={
                          isAnalysisMode
                            ? "点击AI分析，从剧本中提取世界观设定..."
                            : "点击AI生成，根据灵感创建世界观设定..."
                        }
                      />
                    </Form.Item>
                  </Card>

                  {/* 人物设定 */}
                  <Card
                    title={
                      <Space>
                        <span>人物设定</span>
                        {generationStep >= 2 && <Tag color="success">已完成</Tag>}
                        {generationStep < 1 && <Tag color="default">需先完成世界观</Tag>}
                      </Space>
                    }
                    size="small"
                    extra={
                      <Space>
                        <SkillSelectorWithPrompt
                          title="配置人物生成"
                          icon={<SettingOutlined />}
                          skills={skills}
                          selectedSkills={characterSkills}
                          onSkillsChange={setCharacterSkills}
                          customPrompt={characterPrompt}
                          onPromptChange={setCharacterPrompt}
                        />
                        <Button
                          type="primary"
                          size="small"
                          icon={generatingCharacters ? <LoadingOutlined /> : <RobotOutlined />}
                          onClick={handleGenerateCharacters}
                          disabled={generationStep < 1 || generatingWorld || generatingCharacters || generatingOutline || generatingAll}
                        >
                          {isAnalysisMode ? 'AI 分析' : 'AI 生成'}
                        </Button>
                      </Space>
                    }
                    style={{ marginBottom: '16px', border: generationStep >= 2 ? '1px solid #52c41a' : undefined, opacity: generationStep < 1 ? 0.6 : 1 }}
                  >
                    <Form.Item name="characters">
                      <TextArea
                        rows={6}
                        placeholder={
                          isAnalysisMode
                            ? "点击AI分析，从剧本中提取人物设定..."
                            : "点击AI生成，根据灵感创建人物设定..."
                        }
                      />
                    </Form.Item>
                  </Card>

                  {/* 整体大纲 */}
                  <Card
                    title={
                      <Space>
                        <span>整体大纲</span>
                        {generationStep >= 3 && <Tag color="success">已完成</Tag>}
                        {generationStep < 2 && <Tag color="default">需先完成人物设定</Tag>}
                      </Space>
                    }
                    size="small"
                    extra={
                      <Space>
                        <SkillSelectorWithPrompt
                          title="配置大纲生成"
                          icon={<SettingOutlined />}
                          skills={skills}
                          selectedSkills={outlineSkills}
                          onSkillsChange={setOutlineSkills}
                          customPrompt={outlinePrompt}
                          onPromptChange={setOutlinePrompt}
                        />
                        <Button
                          type="primary"
                          size="small"
                          icon={generatingOutline ? <LoadingOutlined /> : <RobotOutlined />}
                          onClick={handleGenerateOutline}
                          disabled={generationStep < 2 || generatingWorld || generatingCharacters || generatingOutline || generatingAll}
                        >
                          {isAnalysisMode ? 'AI 分析' : 'AI 生成'}
                        </Button>
                      </Space>
                    }
                    style={{ marginBottom: '16px', border: generationStep >= 3 ? '1px solid #52c41a' : undefined, opacity: generationStep < 2 ? 0.6 : 1 }}
                  >
                    <Form.Item name="overallOutline">
                      <TextArea
                        rows={8}
                        placeholder={
                          isAnalysisMode
                            ? "点击AI分析，从剧本中提取整体大纲..."
                            : "点击AI生成，根据灵感创建整体大纲..."
                        }
                      />
                    </Form.Item>
                  </Card>

                  <Form.Item>
                    <Button type="primary" onClick={handleSaveGlobalSettings} icon={<SaveOutlined />}>
                      保存全局设定
                    </Button>
                  </Form.Item>
                </Form>
              </Space>
            )}
          </TabPane>

          {/* 剧集创作标签页 - 直接嵌入创作工作台 */}
          <TabPane tab="剧集创作" key="episodes">
            {!globalSettingsCompleted ? (
              <Alert
                message="请先完成全局设定"
                description="开始剧集创作前，请先在「全局设定生成」中完成世界观设定和整体大纲的AI生成或手动填写"
                type="warning"
                showIcon
                action={
                  <Button type="primary" onClick={() => setActiveTab('global-generation')}>
                    前往全局设定生成
                  </Button>
                }
              />
            ) : (
              <div style={{
                height: 'calc(100vh - 220px)',
                display: 'flex',
                flexDirection: 'column',
                background: '#fff',
                borderRadius: '8px',
                border: '1px solid #f0f0f0',
                overflow: 'hidden'
              }}>
                {/* 工作台头部 */}
                <div style={{
                  background: '#fafafa',
                  borderBottom: '1px solid #f0f0f0',
                  padding: '10px 16px',
                  display: 'flex',
                  alignItems: 'center',
                  justifyContent: 'space-between',
                  flexShrink: 0
                }}>
                  <Space size="small">
                    <span style={{ fontWeight: 600, fontSize: '13px' }}>创作工作台</span>
                    <span style={{ color: '#999', fontSize: '11px' }}>{currentProject?.name}</span>
                    <Tag color={wsConnected ? 'success' : 'error'} style={{ fontSize: '11px' }}>
                      {wsConnected ? '在线' : '离线'}
                    </Tag>
                  </Space>
                  <Space size="small">
                    <Button size="small">导出</Button>
                    <Button size="small" type="primary">发布</Button>
                  </Space>
                </div>

                {/* 工作台主体 */}
                <div style={{
                  flex: 1,
                  display: 'flex',
                  overflow: 'hidden',
                  gap: 0,
                  background: '#f3f4f6'
                }}>
                  {/* 左侧：剧集管理 + 故事上下文 */}
                  <div style={{ flex: '0 0 ' + leftPanelWidth + 'px', minWidth: '280px', maxWidth: '600px' }}>
                    <LeftSidebar
                      projectId={id!}
                      project={currentProject}
                      loading={loading}
                      activeStates={activeStates}
                      memoryItems={workspaceMemoryItems}
                      width={leftPanelWidth}
                      currentEpisodeId={currentEpisodeInWorkspace?.id}
                      onEpisodeSelect={(episode) => {
                        setCurrentEpisodeInWorkspace(episode)
                        setCanvasContent(episode.content || '')
                      }}
                      onSendMessage={handleDirectorMessage}
                      onNavigateToSettings={() => setActiveTab('global-generation')}
                    />
                  </div>

                  {/* 左侧拖拽手柄 */}
                  <div
                    style={{
                      width: '4px',
                      cursor: 'col-resize',
                      background: isResizing === 'left' ? '#1890ff' : '#f0f0f0',
                      flexShrink: 0,
                      userSelect: 'none',
                      transition: 'all 0.2s',
                      position: 'relative',
                      zIndex: 10,
                      borderLeft: '1px solid #e8e8e8',
                      borderRight: '1px solid #e8e8e8'
                    }}
                    onMouseDown={(e) => {
                      e.preventDefault()
                      setIsResizing('left')
                      resizeStartRef.current = {
                        x: e.clientX,
                        leftWidth: leftPanelWidth,
                        rightWidth: rightPanelWidth
                      }
                    }}
                    onMouseEnter={(e) => {
                      if (isResizing !== 'left') {
                        e.currentTarget.style.background = '#1890ff'
                      }
                    }}
                    onMouseLeave={(e) => {
                      if (isResizing !== 'left') {
                        e.currentTarget.style.background = '#f0f0f0'
                      }
                    }}
                  />

                  {/* 中间：Smart Canvas */}
                  <div style={{
                    flex: 1,
                    minWidth: 0,
                    display: 'flex',
                    flexDirection: 'column',
                    background: '#ffffff',
                    position: 'relative',
                    zIndex: 1
                  }}>
                    <SmartCanvas
                      content={canvasContent}
                      streaming={streaming}
                      annotations={annotations}
                      episodeTitle={currentEpisodeInWorkspace?.title}
                      episodeNumber={currentEpisodeInWorkspace?.number}
                      onContentChange={handleContentChange}
                      onContentSave={handleContentSave}
                      onAIAssist={handleAIAssist}
                      onTitleChange={handleTitleChange}
                      availableSkills={skills}
                      projectId={id}
                      // 大纲相关props
                      outlineContent={outlineContent}
                      onOutlineChange={handleOutlineChange}
                      onOutlineSave={handleOutlineSave}
                      onOutlineAIAssist={handleOutlineAIAssist}
                      outlineStreaming={outlineStreaming}
                    />
                  </div>

                  {/* 右侧拖拽手柄 */}
                  <div
                    style={{
                      width: '4px',
                      cursor: 'col-resize',
                      background: isResizing === 'right' ? '#1890ff' : '#f0f0f0',
                      flexShrink: 0,
                      userSelect: 'none',
                      transition: 'all 0.2s',
                      position: 'relative',
                      zIndex: 10,
                      borderLeft: '1px solid #e8e8e8',
                      borderRight: '1px solid #e8e8e8'
                    }}
                    onMouseDown={(e) => {
                      e.preventDefault()
                      setIsResizing('right')
                      resizeStartRef.current = {
                        x: e.clientX,
                        leftWidth: leftPanelWidth,
                        rightWidth: rightPanelWidth
                      }
                    }}
                    onMouseEnter={(e) => {
                      if (isResizing !== 'right') {
                        e.currentTarget.style.background = '#1890ff'
                      }
                    }}
                    onMouseLeave={(e) => {
                      if (isResizing !== 'right') {
                        e.currentTarget.style.background = '#f0f0f0'
                      }
                    }}
                  />

                  {/* 右侧：Director Inbox */}
                  <div style={{ flex: '0 0 ' + rightPanelWidth + 'px', minWidth: '220px', maxWidth: '450px' }}>
                    <DirectorInbox
                      onSendMessage={handleDirectorMessage}
                      onInboxAction={handleWorkspaceInboxAction}
                      agentStatus={agentStatus}
                      agentPlan={agentPlan}
                      inboxItems={inboxItems}
                      chatHistory={chatHistory}
                      wsRef={wsRef}
                    />
                  </div>
                </div>
              </div>
            )}
          </TabPane>

          {/* 记忆系统标签页 - 直接嵌入 MemorySystem 组件 */}
          <TabPane
            tab={
              <span>
                <ClockCircleOutlined />
                记忆系统
              </span>
            }
            key="memory"
          >
            <div style={{ height: 'calc(100dvh - 200px)', overflow: 'hidden' }}>
              <MemorySystem projectId={id} />
            </div>
          </TabPane>

          {/* 审核系统标签页 - 直接嵌入审核配置和结果组件 */}
          <TabPane
            tab={
              <span>
                <ScanOutlined />
                审核系统
              </span>
            }
            key="review"
          >
            <div>
              <Tabs
                activeKey={reviewSubTab}
                onChange={setReviewSubTab}
                type="card"
              >
                <TabPane tab="审核平台" key="results">
                  <ReviewResults projectId={id} />
                </TabPane>
                <TabPane tab="审核配置" key="config">
                  <ReviewConfig projectId={id} />
                </TabPane>
              </Tabs>
            </div>
          </TabPane>
        </Tabs>
      </Card>

      {/* 剧集内容弹窗 */}
      <Modal
        title={`EP${selectedEpisode?.number} - ${selectedEpisode?.title}`}
        open={!!selectedEpisode}
        onCancel={() => setSelectedEpisode(null)}
        footer={null}
        width={800}
      >
        {selectedEpisode && (
          <Space direction="vertical" style={{ width: '100%' }} size="large">
            {selectedEpisode.outline && (
              <div>
                <h4>大纲</h4>
                <p>{selectedEpisode.outline}</p>
              </div>
            )}
            {selectedEpisode.content && (
              <div>
                <h4>剧本内容</h4>
                <pre style={{ whiteSpace: 'pre-wrap', background: '#f5f5f5', padding: '16px', borderRadius: '4px' }}>
                  {selectedEpisode.content}
                </pre>
              </div>
            )}
            {selectedEpisode.qualityScore && (
              <div>
                <h4>质量分数: {selectedEpisode.qualityScore}</h4>
              </div>
            )}
          </Space>
        )}
      </Modal>
    </div>
  )
}
