import { describe, expect, it } from 'vitest'
import type { ProspectingBuildTemplate } from '../../organization-model/domains/prospecting'
import {
  createBuildPlanSnapshotFromTemplate,
  createBuildPlanSnapshotFromTemplateId,
  getProspectingBuildTemplateOptions,
  isProspectingBuildTemplateId
} from './build-templates'

const templates: ProspectingBuildTemplate[] = [
  {
    id: 'source-and-qualify',
    label: 'Source and Qualify',
    description: 'Source companies, analyze websites, and qualify fit.',
    steps: [
      {
        id: 'source-companies',
        label: 'Companies found',
        primaryEntity: 'company',
        outputs: ['company'],
        stageKey: 'populated',
        dependencyMode: 'per-record-eligibility',
        actionKey: 'lead-gen.company.source',
        defaultBatchSize: 100,
        maxBatchSize: 250,
        recordColumns: {
          company: [{ key: 'name', label: 'Company', path: 'company.name' }]
        }
      },
      {
        id: 'qualify-companies',
        label: 'Companies qualified',
        description: 'Score companies against the active ICP.',
        primaryEntity: 'company',
        outputs: ['company'],
        stageKey: 'qualified',
        dependsOn: ['source-companies'],
        dependencyMode: 'per-record-eligibility',
        actionKey: 'lead-gen.company.qualify',
        defaultBatchSize: 50,
        maxBatchSize: 100
      }
    ]
  },
  {
    id: 'export-ready',
    label: 'Export Ready',
    steps: [
      {
        id: 'review-and-export',
        label: 'Reviewed and exported',
        primaryEntity: 'company',
        outputs: ['export'],
        stageKey: 'uploaded',
        recordsStageKey: 'uploaded',
        recordSourceStageKey: 'qualified',
        dependencyMode: 'per-record-eligibility',
        actionKey: 'lead-gen.export.list',
        defaultBatchSize: 25,
        maxBatchSize: 100,
        credentialRequirements: [
          {
            key: 'export',
            provider: 'export-provider',
            credentialType: 'api-key-secret',
            label: 'Export API token',
            required: true,
            selectionMode: 'single',
            inputPath: 'credential',
            verifyOnRun: true
          }
        ]
      }
    ]
  }
]

describe('getProspectingBuildTemplateOptions', () => {
  it('projects option metadata from caller-supplied templates', () => {
    expect(getProspectingBuildTemplateOptions(templates)).toEqual([
      {
        id: 'source-and-qualify',
        label: 'Source and Qualify',
        description: 'Source companies, analyze websites, and qualify fit.'
      },
      {
        id: 'export-ready',
        label: 'Export Ready',
        description: undefined
      }
    ])
  })
})

describe('isProspectingBuildTemplateId', () => {
  it('checks membership against caller-supplied templates', () => {
    expect(isProspectingBuildTemplateId('source-and-qualify', templates)).toBe(true)
    expect(isProspectingBuildTemplateId('not-a-template', templates)).toBe(false)
  })

  it('has no published default template catalog', () => {
    expect(isProspectingBuildTemplateId('source-and-qualify')).toBe(false)
  })
})

describe('createBuildPlanSnapshotFromTemplate', () => {
  it('creates an immutable build-plan snapshot shape from a supplied template', () => {
    const snapshot = createBuildPlanSnapshotFromTemplate(templates[0]!)

    expect(snapshot).toMatchObject({
      templateId: 'source-and-qualify',
      templateLabel: 'Source and Qualify',
      steps: [
        {
          id: 'source-companies',
          label: 'Companies found',
          primaryEntity: 'company',
          outputs: ['company'],
          stageKey: 'populated',
          recordsStageKey: 'populated',
          recordSourceStageKey: 'populated',
          dependencyMode: 'per-record-eligibility',
          actionKey: 'lead-gen.company.source',
          defaultBatchSize: 100,
          maxBatchSize: 250,
          recordColumns: {
            company: [{ key: 'name', label: 'Company', path: 'company.name' }]
          }
        },
        {
          id: 'qualify-companies',
          dependsOn: ['source-companies'],
          description: 'Score companies against the active ICP.'
        }
      ]
    })
  })

  it('copies array/object fields so subsequent snapshots are isolated', () => {
    const snapshotA = createBuildPlanSnapshotFromTemplate(templates[0]!)
    const snapshotB = createBuildPlanSnapshotFromTemplate(templates[0]!)

    snapshotA.steps[0]?.outputs.push('export')
    snapshotA.steps[0]?.recordColumns?.company?.push({ key: 'domain', label: 'Domain', path: 'company.domain' })

    expect(snapshotB.steps[0]?.outputs).toEqual(['company'])
    expect(snapshotB.steps[0]?.recordColumns?.company).toEqual([
      { key: 'name', label: 'Company', path: 'company.name' }
    ])
  })

  it('preserves credential requirements and explicit record stage fields', () => {
    const snapshot = createBuildPlanSnapshotFromTemplate(templates[1]!)

    expect(snapshot.steps[0]).toMatchObject({
      id: 'review-and-export',
      recordsStageKey: 'uploaded',
      recordSourceStageKey: 'qualified',
      credentialRequirements: [
        {
          key: 'export',
          provider: 'export-provider',
          credentialType: 'api-key-secret',
          label: 'Export API token',
          required: true,
          selectionMode: 'single',
          inputPath: 'credential',
          verifyOnRun: true
        }
      ]
    })
  })

  it('normalizes stage-key dependencies to step ids for snapshots', () => {
    const snapshot = createBuildPlanSnapshotFromTemplate({
      id: 'stage-key-dependency',
      label: 'Stage Key Dependency',
      steps: [
        {
          id: 'source-companies',
          label: 'Companies found',
          primaryEntity: 'company',
          outputs: ['company'],
          stageKey: 'populated',
          dependencyMode: 'per-record-eligibility',
          actionKey: 'lead-gen.company.source',
          defaultBatchSize: 100,
          maxBatchSize: 250
        },
        {
          id: 'qualify-companies',
          label: 'Companies qualified',
          primaryEntity: 'company',
          outputs: ['company'],
          stageKey: 'qualified',
          dependsOn: ['populated'],
          dependencyMode: 'per-record-eligibility',
          actionKey: 'lead-gen.company.qualify',
          defaultBatchSize: 50,
          maxBatchSize: 100
        }
      ]
    })

    expect(snapshot.steps[1]?.dependsOn).toEqual(['source-companies'])
  })
})

describe('createBuildPlanSnapshotFromTemplateId', () => {
  it('creates snapshots from caller-supplied template catalogs', () => {
    const snapshot = createBuildPlanSnapshotFromTemplateId('export-ready', templates)

    expect(snapshot?.templateId).toBe('export-ready')
    expect(snapshot?.steps).toHaveLength(1)
  })

  it('returns null for unknown ids or when no template catalog is supplied', () => {
    expect(createBuildPlanSnapshotFromTemplateId('not-a-template', templates)).toBeNull()
    expect(createBuildPlanSnapshotFromTemplateId('source-and-qualify')).toBeNull()
  })
})
