import { describe, it, expect } from 'vitest'
import { WorkflowStepError, WorkflowValidationError } from '../errors'
import { ExecutionError } from '../../base/errors'

describe('Workflow Errors', () => {
  describe('WorkflowStepError', () => {
    it('extends ExecutionError', () => {
      const error = new WorkflowStepError('Step failed')
      expect(error).toBeInstanceOf(ExecutionError)
      expect(error).toBeInstanceOf(Error)
    })

    it('has critical severity', () => {
      const error = new WorkflowStepError('Step failed')
      expect(error.severity).toBe('critical')
    })

    it('has workflow category', () => {
      const error = new WorkflowStepError('Step failed')
      expect(error.category).toBe('workflow')
    })

    it('is not retryable by default', () => {
      const error = new WorkflowStepError('Step failed')
      expect(error.isRetryable()).toBe(false)
    })

    it('sets message correctly', () => {
      const error = new WorkflowStepError('Step "send_email" failed: SMTP unavailable')
      expect(error.message).toBe('Step "send_email" failed: SMTP unavailable')
    })

    it('sets name to WorkflowStepError', () => {
      const error = new WorkflowStepError('Step failed')
      expect(error.name).toBe('WorkflowStepError')
    })

    it('returns correct error type', () => {
      const error = new WorkflowStepError('Step failed')
      expect(error.name).toBe('WorkflowStepError')
    })

    it('stores context with workflow details', () => {
      const context = {
        workflowId: 'wf-123',
        stepIndex: 2,
        stepName: 'send_email',
        attemptCount: 1
      }
      const error = new WorkflowStepError('Step failed', context)
      expect(error.context).toEqual(context)
    })

    it('captures stack trace', () => {
      const error = new WorkflowStepError('Step failed')
      expect(error.stack).toBeDefined()
      expect(error.stack).toContain('WorkflowStepError')
    })
  })

  describe('WorkflowValidationError', () => {
    it('extends ExecutionError', () => {
      const error = new WorkflowValidationError('Validation failed')
      expect(error).toBeInstanceOf(ExecutionError)
      expect(error).toBeInstanceOf(Error)
    })

    it('has info severity', () => {
      const error = new WorkflowValidationError('Validation failed')
      expect(error.severity).toBe('info')
    })

    it('has validation category', () => {
      const error = new WorkflowValidationError('Validation failed')
      expect(error.category).toBe('validation')
    })

    it('is not retryable by default', () => {
      const error = new WorkflowValidationError('Validation failed')
      expect(error.isRetryable()).toBe(false)
    })

    it('sets message correctly', () => {
      const error = new WorkflowValidationError('Invalid workflow: Missing approver')
      expect(error.message).toBe('Invalid workflow: Missing approver')
    })

    it('sets name to WorkflowValidationError', () => {
      const error = new WorkflowValidationError('Validation failed')
      expect(error.name).toBe('WorkflowValidationError')
    })

    it('returns correct error type', () => {
      const error = new WorkflowValidationError('Validation failed')
      expect(error.name).toBe('WorkflowValidationError')
    })

    it('stores context with validation details', () => {
      const context = {
        workflowId: 'wf-123',
        stepIndex: 3,
        field: 'approver',
        expectedType: 'string'
      }
      const error = new WorkflowValidationError('Validation failed', context)
      expect(error.context).toEqual(context)
    })

    it('captures stack trace', () => {
      const error = new WorkflowValidationError('Validation failed')
      expect(error.stack).toBeDefined()
      expect(error.stack).toContain('WorkflowValidationError')
    })
  })

  describe('instanceof checks', () => {
    it('WorkflowStepError maintains inheritance chain', () => {
      const error = new WorkflowStepError('test')
      expect(error instanceof WorkflowStepError).toBe(true)
      expect(error instanceof ExecutionError).toBe(true)
      expect(error instanceof Error).toBe(true)
    })

    it('WorkflowValidationError maintains inheritance chain', () => {
      const error = new WorkflowValidationError('test')
      expect(error instanceof WorkflowValidationError).toBe(true)
      expect(error instanceof ExecutionError).toBe(true)
      expect(error instanceof Error).toBe(true)
    })

    it('workflow errors are distinct types', () => {
      const stepError = new WorkflowStepError('test')
      const validationError = new WorkflowValidationError('test')

      expect(stepError instanceof WorkflowValidationError).toBe(false)
      expect(validationError instanceof WorkflowStepError).toBe(false)
    })
  })
})
