import type { Edge, Node } from '@xyflow/react'
import type {
  AutomationWorkflow,
  WorkflowEdgeDef,
  WorkflowNodeData,
  WorkflowNodeDef,
  WorkflowNodeType,
} from './types'
import { nextNodeId } from './defaults'
import type { ActionsNodeData, ConditionNodeData, LabelCheckNodeData, LLMCheckNodeData, SetVarNodeData, SwitchNodeData } from './types'

export function workflowNodesToFlow(nodes: WorkflowNodeDef[]): Node[] {
  return nodes.map((n) => ({
    id: n.id,
    type: n.type,
    position: n.position,
    data: n.data as Record<string, unknown>,
  }))
}

export function workflowEdgesToFlow(edges: WorkflowEdgeDef[]): Edge[] {
  return edges.map((e) => ({
    id: e.id,
    source: e.source,
    target: e.target,
    sourceHandle: e.sourceHandle ?? null,
    animated: true,
  }))
}

export function flowToWorkflow(
  kind: AutomationWorkflow['kind'],
  triggers: AutomationWorkflow['triggers'],
  variables: AutomationWorkflow['variables'],
  nodes: Node[],
  edges: Edge[]
): AutomationWorkflow {
  return {
    version: 1,
    kind,
    triggers,
    variables,
    nodes: nodes.map((n) => ({
      id: n.id,
      type: n.type as WorkflowNodeType,
      position: n.position,
      data: (n.data ?? {}) as WorkflowNodeData,
    })),
    edges: edges.map((e) => ({
      id: e.id,
      source: e.source,
      target: e.target,
      sourceHandle: e.sourceHandle ?? undefined,
    })),
  }
}

export function defaultDataForNodeType(type: WorkflowNodeType): WorkflowNodeData {
  switch (type) {
    case 'condition':
      return { field: 'subject', operator: 'contains', value: '' } satisfies ConditionNodeData
    case 'label_check':
      return { label: '', operator: 'has' } satisfies LabelCheckNodeData
    case 'switch':
      return {
        field: 'subject',
        cases: [
          { value: 'facture', label: 'Factures' },
          { value: 'newsletter', label: 'Newsletters' },
        ],
      } satisfies SwitchNodeData
    case 'llm_check':
      return {
        prompt: 'Ce message est-il du spam ou une arnaque ?',
        provider: '',
        model: '',
      } satisfies LLMCheckNodeData
    case 'actions':
      return { actions: [{ type: 'label', value: '' }] } satisfies ActionsNodeData
    case 'set_var':
      return { name: 'result', value: '{{subject}}' } satisfies SetVarNodeData
    case 'call_function':
    case 'call_rule':
      return { rule_id: '' }
    default:
      return {}
  }
}

export function createFlowNode(
  type: WorkflowNodeType,
  position: { x: number; y: number }
): Node {
  return {
    id: nextNodeId(type),
    type,
    position,
    data: defaultDataForNodeType(type) as Record<string, unknown>,
  }
}

export function parseWorkflowFromRule(
  workflow: unknown,
  ruleKind: 'rule' | 'function'
): AutomationWorkflow | null {
  if (!workflow || typeof workflow !== 'object') return null
  const w = workflow as AutomationWorkflow
  if (!Array.isArray(w.nodes) || w.nodes.length === 0) return null
  return {
    version: 1,
    kind: w.kind ?? ruleKind,
    triggers: w.triggers ?? {
      operator: 'or',
      groups: [{ operator: 'and', items: [{ type: 'message_received' }] }],
    },
    variables: w.variables ?? [],
    nodes: w.nodes,
    edges: w.edges ?? [],
  }
}
