/**
 * Workflow Pinia store
 */

import { defineStore } from 'pinia'
import { ref, computed } from 'vue'
import { workflowApi } from '@/api/workflow'
import type {
  WorkflowDefinition,
  WorkflowSummary,
  WorkflowExecution,
  WorkflowStage,
} from '@/utils/workflowSerializer'
import type { Node, Edge } from '@vue-flow/core'
import { flowToWorkflow, workflowToFlow, getDefaultNodeData, type WorkflowNodeData } from '@/utils/workflowSerializer'

export const useWorkflowStore = defineStore('workflow', () => {
  // --- State ---
  const workflows = ref<WorkflowSummary[]>([])
  const currentWorkflow = ref<WorkflowDefinition | null>(null)
  const currentExecution = ref<WorkflowExecution | null>(null)
  const isExecuting = ref(false)
  const isLoading = ref(false)
  const error = ref<string | null>(null)

  // Vue Flow state
  const flowNodes = ref<Node<WorkflowNodeData>[]>([])
  const flowEdges = ref<Edge[]>([])
  const selectedNodeId = ref<string | null>(null)

  // --- Getters ---
  const selectedNode = computed<Node<WorkflowNodeData> | null>(() => {
    if (!selectedNodeId.value) return null
    return flowNodes.value.find((n) => n.id === selectedNodeId.value) || null
  })

  const selectedNodeData = computed<WorkflowNodeData | null>(() => {
    return selectedNode.value?.data || null
  })

  // --- Actions ---

  /** Load all workflows from server */
  async function loadWorkflows(): Promise<void> {
    isLoading.value = true
    error.value = null
    try {
      const response = await workflowApi.listWorkflows()
      workflows.value = response.workflows
    } catch (err) {
      error.value = err instanceof Error ? err.message : '加载工作流列表失败'
      console.error('Failed to load workflows:', err)
    } finally {
      isLoading.value = false
    }
  }

  /** Create a new workflow */
  async function createWorkflow(name: string): Promise<WorkflowDefinition | null> {
    isLoading.value = true
    error.value = null
    try {
      const workflow = await workflowApi.createWorkflow({
        name,
        stages: [],
      })
      currentWorkflow.value = workflow
      flowNodes.value = []
      flowEdges.value = []
      selectedNodeId.value = null
      await loadWorkflows()
      return workflow
    } catch (err) {
      error.value = err instanceof Error ? err.message : '创建工作流失败'
      console.error('Failed to create workflow:', err)
      return null
    } finally {
      isLoading.value = false
    }
  }

  /** Load a workflow for editing */
  async function loadWorkflow(workflowId: string): Promise<void> {
    isLoading.value = true
    error.value = null
    try {
      const workflow = await workflowApi.getWorkflow(workflowId)
      currentWorkflow.value = workflow
      const { nodes, edges } = workflowToFlow(workflow)
      flowNodes.value = nodes
      flowEdges.value = edges
      selectedNodeId.value = null
    } catch (err) {
      error.value = err instanceof Error ? err.message : '加载工作流失败'
      console.error('Failed to load workflow:', err)
    } finally {
      isLoading.value = false
    }
  }

  /** Save current workflow to server */
  async function saveWorkflow(): Promise<boolean> {
    if (!currentWorkflow.value) return false
    isLoading.value = true
    error.value = null
    try {
      const definition = flowToWorkflow(
        flowNodes.value,
        flowEdges.value,
        currentWorkflow.value.name,
        currentWorkflow.value.workflow_id,
      )
      const saved = await workflowApi.updateWorkflow(
        currentWorkflow.value.workflow_id,
        {
          name: definition.name,
          stages: definition.stages,
          triggers: definition.triggers,
          variables_schema: definition.variables_schema,
          output_schema: definition.output_schema,
        }
      )
      currentWorkflow.value = saved
      await loadWorkflows()
      return true
    } catch (err) {
      error.value = err instanceof Error ? err.message : '保存工作流失败'
      console.error('Failed to save workflow:', err)
      return false
    } finally {
      isLoading.value = false
    }
  }

  /** Delete a workflow */
  async function deleteWorkflow(workflowId: string): Promise<boolean> {
    isLoading.value = true
    error.value = null
    try {
      await workflowApi.deleteWorkflow(workflowId)
      if (currentWorkflow.value?.workflow_id === workflowId) {
        currentWorkflow.value = null
        flowNodes.value = []
        flowEdges.value = []
        selectedNodeId.value = null
      }
      await loadWorkflows()
      return true
    } catch (err) {
      error.value = err instanceof Error ? err.message : '删除工作流失败'
      console.error('Failed to delete workflow:', err)
      return false
    } finally {
      isLoading.value = false
    }
  }

  /** Execute current workflow */
  async function executeWorkflow(variables?: Record<string, unknown>): Promise<void> {
    if (!currentWorkflow.value) return
    isExecuting.value = true
    error.value = null
    try {
      const result = await workflowApi.executeWorkflow(
        currentWorkflow.value.workflow_id,
        variables
      )
      // Poll for execution status
      const pollExecution = async () => {
        const execution = await workflowApi.getExecution(result.execution_id)
        currentExecution.value = execution
        if (execution.status === 'running' || execution.status === 'paused' || execution.status === 'pending') {
          setTimeout(pollExecution, 1000)
        } else {
          isExecuting.value = false
        }
      }
      pollExecution()
    } catch (err) {
      error.value = err instanceof Error ? err.message : '执行工作流失败'
      console.error('Failed to execute workflow:', err)
      isExecuting.value = false
    }
  }

  /** Approve a paused execution */
  async function approveExecution(
    executionId: string,
    approved: boolean,
    comment?: string
  ): Promise<void> {
    try {
      const execution = await workflowApi.approveExecution(executionId, approved, comment)
      currentExecution.value = execution
    } catch (err) {
      error.value = err instanceof Error ? err.message : '审批操作失败'
      console.error('Failed to approve execution:', err)
    }
  }

  /** Cancel an execution */
  async function cancelExecution(executionId: string): Promise<void> {
    try {
      const execution = await workflowApi.cancelExecution(executionId)
      currentExecution.value = execution
      isExecuting.value = false
    } catch (err) {
      error.value = err instanceof Error ? err.message : '取消执行失败'
      console.error('Failed to cancel execution:', err)
    }
  }

  /** Add a node to the flow canvas */
  function addNode(nodeType: string, position: { x: number; y: number }): void {
    const id = `node-${Date.now()}-${Math.random().toString(36).substring(2, 7)}`
    const data = getDefaultNodeData(nodeType)
    const node: Node<WorkflowNodeData> = {
      id,
      type: nodeType === 'condition' ? 'condition' : nodeType === 'approval' ? 'approval' : 'skill',
      position,
      data,
    }
    flowNodes.value = [...flowNodes.value, node]
  }

  /** Update node data */
  function updateNodeData(nodeId: string, data: Partial<WorkflowNodeData>): void {
    const index = flowNodes.value.findIndex((n) => n.id === nodeId)
    if (index !== -1) {
      flowNodes.value[index] = {
        ...flowNodes.value[index],
        data: { ...flowNodes.value[index].data, ...data },
      }
    }
  }

  /** Remove a node */
  function removeNode(nodeId: string): void {
    flowNodes.value = flowNodes.value.filter((n) => n.id !== nodeId)
    flowEdges.value = flowEdges.value.filter(
      (e) => e.source !== nodeId && e.target !== nodeId
    )
    if (selectedNodeId.value === nodeId) {
      selectedNodeId.value = null
    }
  }

  /** Clear the canvas */
  function clearCanvas(): void {
    flowNodes.value = []
    flowEdges.value = []
    selectedNodeId.value = null
  }

  /** Select a node */
  function selectNode(nodeId: string | null): void {
    selectedNodeId.value = nodeId
  }

  return {
    // State
    workflows,
    currentWorkflow,
    currentExecution,
    isExecuting,
    isLoading,
    error,
    flowNodes,
    flowEdges,
    selectedNodeId,
    // Getters
    selectedNode,
    selectedNodeData,
    // Actions
    loadWorkflows,
    createWorkflow,
    loadWorkflow,
    saveWorkflow,
    deleteWorkflow,
    executeWorkflow,
    approveExecution,
    cancelExecution,
    addNode,
    updateNodeData,
    removeNode,
    clearCanvas,
    selectNode,
  }
})
