import type { StateCreator } from 'zustand'
import type {
  Edge,
  Node,
  TriggerNodeType,
  WorkflowRunningData,
} from '@/app/components/workflow/types'
import type { FileUploadConfigResponse } from '@/models/common'
import { getLocalStorageItem, setLocalStorageItem } from '@/utils/local-storage'

type PreviewRunningData = WorkflowRunningData & {
  resultTabActive?: boolean
  resultText?: string
  // human input form schema or data cached when node is in 'Paused' status
  extraContentAndFormData?: Record<string, any>
}

type MousePosition = {
  pageX: number
  pageY: number
  elementX: number
  elementY: number
}

const getStoredControlMode = () => {
  const storedControlMode = getLocalStorageItem('workflow-operation-mode')
  if (storedControlMode === 'pointer' || storedControlMode === 'hand' || storedControlMode === 'comment')
    return storedControlMode

  return 'pointer'
}

export type WorkflowSliceShape = {
  workflowRunningData?: PreviewRunningData
  setWorkflowRunningData: (workflowData: PreviewRunningData) => void
  isListening: boolean
  setIsListening: (listening: boolean) => void
  listeningTriggerType: TriggerNodeType | null
  setListeningTriggerType: (triggerType: TriggerNodeType | null) => void
  listeningTriggerNodeId: string | null
  setListeningTriggerNodeId: (nodeId: string | null) => void
  listeningTriggerNodeIds: string[]
  setListeningTriggerNodeIds: (nodeIds: string[]) => void
  listeningTriggerIsAll: boolean
  setListeningTriggerIsAll: (isAll: boolean) => void
  clipboardElements: Node[]
  clipboardEdges: Edge[]
  setClipboardElements: (clipboardElements: Node[]) => void
  setClipboardEdges: (clipboardEdges: Edge[]) => void
  setClipboardData: (clipboardData: { nodes: Node[], edges: Edge[] }) => void
  selection: null | { x1: number, y1: number, x2: number, y2: number }
  setSelection: (selection: WorkflowSliceShape['selection']) => void
  bundleNodeSize: { width: number, height: number } | null
  setBundleNodeSize: (bundleNodeSize: WorkflowSliceShape['bundleNodeSize']) => void
  controlMode: 'pointer' | 'hand' | 'comment'
  setControlMode: (controlMode: WorkflowSliceShape['controlMode']) => void
  pendingComment: MousePosition | null
  setPendingComment: (pendingComment: WorkflowSliceShape['pendingComment']) => void
  isCommentPlacing: boolean
  setCommentPlacing: (isCommentPlacing: boolean) => void
  isCommentQuickAdd: boolean
  setCommentQuickAdd: (isCommentQuickAdd: boolean) => void
  isCommentPreviewHovering: boolean
  setCommentPreviewHovering: (hovering: boolean) => void
  mousePosition: { pageX: number, pageY: number, elementX: number, elementY: number }
  setMousePosition: (mousePosition: WorkflowSliceShape['mousePosition']) => void
  showConfirm?: { title: string, desc?: string, onConfirm: () => void }
  setShowConfirm: (showConfirm: WorkflowSliceShape['showConfirm']) => void
  controlPromptEditorRerenderKey: number
  setControlPromptEditorRerenderKey: (controlPromptEditorRerenderKey: number) => void
  showImportDSLModal: boolean
  setShowImportDSLModal: (showImportDSLModal: boolean) => void
  fileUploadConfig?: FileUploadConfigResponse
  setFileUploadConfig: (fileUploadConfig: FileUploadConfigResponse) => void
}

export const createWorkflowSlice: StateCreator<WorkflowSliceShape> = set => ({
  workflowRunningData: undefined,
  setWorkflowRunningData: workflowRunningData => set(() => ({ workflowRunningData })),
  isListening: false,
  setIsListening: listening => set(() => ({ isListening: listening })),
  listeningTriggerType: null,
  setListeningTriggerType: triggerType => set(() => ({ listeningTriggerType: triggerType })),
  listeningTriggerNodeId: null,
  setListeningTriggerNodeId: nodeId => set(() => ({ listeningTriggerNodeId: nodeId })),
  listeningTriggerNodeIds: [],
  setListeningTriggerNodeIds: nodeIds => set(() => ({ listeningTriggerNodeIds: nodeIds })),
  listeningTriggerIsAll: false,
  setListeningTriggerIsAll: isAll => set(() => ({ listeningTriggerIsAll: isAll })),
  clipboardElements: [],
  clipboardEdges: [],
  setClipboardElements: clipboardElements => set(() => ({ clipboardElements })),
  setClipboardEdges: clipboardEdges => set(() => ({ clipboardEdges })),
  setClipboardData: ({ nodes, edges }) => {
    set(() => ({
      clipboardElements: nodes,
      clipboardEdges: edges,
    }))
  },
  selection: null,
  setSelection: selection => set(() => ({ selection })),
  bundleNodeSize: null,
  setBundleNodeSize: bundleNodeSize => set(() => ({ bundleNodeSize })),
  controlMode: getStoredControlMode(),
  setControlMode: (controlMode) => {
    set(() => ({ controlMode }))
    setLocalStorageItem('workflow-operation-mode', controlMode)
  },
  pendingComment: null,
  setPendingComment: pendingComment => set(() => ({ pendingComment })),
  isCommentPlacing: false,
  setCommentPlacing: isCommentPlacing => set(() => ({ isCommentPlacing })),
  isCommentQuickAdd: false,
  setCommentQuickAdd: isCommentQuickAdd => set(() => ({ isCommentQuickAdd })),
  mousePosition: { pageX: 0, pageY: 0, elementX: 0, elementY: 0 },
  setMousePosition: mousePosition => set(() => ({ mousePosition })),
  isCommentPreviewHovering: false,
  setCommentPreviewHovering: hovering => set(() => ({ isCommentPreviewHovering: hovering })),
  showConfirm: undefined,
  setShowConfirm: showConfirm => set(() => ({ showConfirm })),
  controlPromptEditorRerenderKey: 0,
  setControlPromptEditorRerenderKey: controlPromptEditorRerenderKey => set(() => ({ controlPromptEditorRerenderKey })),
  showImportDSLModal: false,
  setShowImportDSLModal: showImportDSLModal => set(() => ({ showImportDSLModal })),
  fileUploadConfig: undefined,
  setFileUploadConfig: fileUploadConfig => set(() => ({ fileUploadConfig })),
})
