import { PARALLEL } from '@/executor/constants'
import type { NodeMetadata } from '@/executor/dag/types'
import type { ExecutionContext, LoopPauseScope, ParallelPauseScope } from '@/executor/types'

interface NodeMetadataLike
  extends Pick<NodeMetadata, 'loopId' | 'parallelId' | 'branchIndex' | 'branchTotal'> {
  nodeId: string
}

export function generatePauseContextId(
  baseBlockId: string,
  nodeMetadata: NodeMetadataLike,
  loopScope?: LoopPauseScope
): string {
  let contextId = baseBlockId

  if (typeof nodeMetadata.branchIndex === 'number') {
    contextId = `${contextId}${PARALLEL.BRANCH.PREFIX}${nodeMetadata.branchIndex}${PARALLEL.BRANCH.SUFFIX}`
  }

  if (loopScope) {
    contextId = `${contextId}_loop${loopScope.iteration}`
  }

  return contextId
}

export function buildTriggerBlockId(nodeId: string): string {
  if (nodeId.includes('__response')) {
    return nodeId.replace('__response', '__trigger')
  }

  if (nodeId.endsWith('_response')) {
    return nodeId.replace(/_response$/, '_trigger')
  }

  return `${nodeId}__trigger`
}

export function mapNodeMetadataToPauseScopes(
  ctx: ExecutionContext,
  nodeMetadata: NodeMetadataLike
): {
  parallelScope?: ParallelPauseScope
  loopScope?: LoopPauseScope
} {
  let parallelScope: ParallelPauseScope | undefined
  let loopScope: LoopPauseScope | undefined

  if (nodeMetadata.parallelId && typeof nodeMetadata.branchIndex === 'number') {
    parallelScope = {
      parallelId: nodeMetadata.parallelId,
      branchIndex: nodeMetadata.branchIndex,
      branchTotal: nodeMetadata.branchTotal,
    }
  }

  if (nodeMetadata.loopId) {
    const loopExecution = ctx.loopExecutions?.get(nodeMetadata.loopId)
    const iteration = loopExecution?.iteration ?? 0
    loopScope = {
      loopId: nodeMetadata.loopId,
      iteration,
    }
  }

  return {
    parallelScope,
    loopScope,
  }
}
