import type {
  CredentialRequirement,
  ListBuilderStep,
  ProspectingBuildTemplate,
  RecordColumnConfig
} from '../../organization-model/domains/prospecting'
import type { BuildPlanSnapshot, BuildPlanSnapshotStep } from './types'

export interface ProspectingBuildTemplateOption {
  id: string
  label: string
  description?: string | undefined
}

export function getProspectingBuildTemplateOptions(
  templates: readonly ProspectingBuildTemplate[]
): ProspectingBuildTemplateOption[] {
  return templates.map(({ id, label, description }) => ({
    id,
    label,
    description
  }))
}

export function isProspectingBuildTemplateId(
  value: string,
  templates: readonly ProspectingBuildTemplate[] = []
): boolean {
  return templates.some((template) => template.id === value)
}

export function createBuildPlanSnapshotFromTemplate(template: ProspectingBuildTemplate): BuildPlanSnapshot {
  const stepIdByStageKey = new Map(template.steps.map((step) => [step.stageKey, step.id]))
  const stepIds = new Set(template.steps.map((step) => step.id))

  return {
    templateId: template.id,
    templateLabel: template.label,
    steps: template.steps.map((step: ListBuilderStep): BuildPlanSnapshotStep => {
      const snapshotStep: BuildPlanSnapshotStep = {
        id: step.id,
        label: step.label,
        primaryEntity: step.primaryEntity,
        outputs: [...step.outputs],
        stageKey: step.stageKey,
        recordsStageKey: step.recordsStageKey ?? step.stageKey,
        recordSourceStageKey: step.recordSourceStageKey ?? step.recordsStageKey ?? step.stageKey,
        dependencyMode: step.dependencyMode,
        actionKey: step.actionKey,
        defaultBatchSize: step.defaultBatchSize,
        maxBatchSize: step.maxBatchSize
      }

      if (step.description) snapshotStep.description = step.description
      if (step.recordEntity) snapshotStep.recordEntity = step.recordEntity
      if (step.dependsOn?.length) {
        snapshotStep.dependsOn = step.dependsOn.map((dependency) =>
          stepIds.has(dependency) ? dependency : (stepIdByStageKey.get(dependency) ?? dependency)
        )
      }
      if (step.credentialRequirements?.length) {
        snapshotStep.credentialRequirements = step.credentialRequirements.map((requirement: CredentialRequirement) => ({
          ...requirement
        }))
      }
      if (step.recordColumns) {
        snapshotStep.recordColumns = {
          ...(step.recordColumns.company
            ? {
                company: step.recordColumns.company.map((column: RecordColumnConfig) => ({ ...column }))
              }
            : {}),
          ...(step.recordColumns.contact
            ? {
                contact: step.recordColumns.contact.map((column: RecordColumnConfig) => ({ ...column }))
              }
            : {})
        }
      }

      return snapshotStep
    })
  }
}

export function createBuildPlanSnapshotFromTemplateId(
  templateId: string,
  templates: readonly ProspectingBuildTemplate[] = []
): BuildPlanSnapshot | null {
  const template = templates.find((item) => item.id === templateId)
  if (!template) return null

  return createBuildPlanSnapshotFromTemplate(template)
}
