/**
 * Test: Command View Type Guards and Helper Functions
 * Tests for type guards and utility functions in command-view.ts
 */

import { describe, it, expect } from 'vitest'
import {
  isAgent,
  isWorkflow,
  isTrigger,
  isIntegration,
  isExternalResource,
  isHumanCheckpoint,
  getNodeId,
  getNodeType,
  type CommandViewAgent,
  type CommandViewWorkflow,
  type CommandViewNode
} from '../command-view'
import type {
  TriggerDefinition,
  IntegrationDefinition,
  ExternalResourceDefinition,
  HumanCheckpointDefinition
} from '../types'

// ============================================================================
// Mock Data - All resources follow new unified schema
// ============================================================================

const mockAgent: CommandViewAgent = {
  resourceId: 'test-agent-123',
  name: 'Test Agent',
  description: 'A test agent for unit testing',
  version: '1.0.0',
  type: 'agent',
  status: 'dev',
  modelProvider: 'anthropic',
  modelId: 'claude-sonnet-4-20250514',
  toolCount: 5,
  hasKnowledgeMap: true,
  hasMemory: false,
  category: 'production'
}

const mockWorkflow: CommandViewWorkflow = {
  resourceId: 'test-workflow-456',
  name: 'Test Workflow',
  description: 'A test workflow for unit testing',
  version: '2.1.0',
  type: 'workflow',
  status: 'prod',
  stepCount: 3,
  entryPoint: 'start'
}

const mockTrigger: TriggerDefinition = {
  resourceId: 'test-trigger-789',
  name: 'Test Webhook Trigger',
  description: 'A test webhook trigger',
  version: '1.0.0',
  type: 'trigger',
  status: 'prod',
  triggerType: 'webhook',
  webhookPath: '/webhooks/shopify/orders',
  triggers: {
    workflows: ['test-workflow-456']
  }
}

const mockIntegration: IntegrationDefinition = {
  resourceId: 'integration-shopify-prod',
  name: 'Shopify Production',
  description: 'E-commerce platform integration',
  version: '1.0.0',
  type: 'integration',
  status: 'prod',
  provider: 'shopify',
  credentialName: 'shopify-prod'
}

const mockExternalResource: ExternalResourceDefinition = {
  resourceId: 'external-n8n-sync',
  name: 'N8N Order Sync',
  description: 'Legacy n8n workflow for syncing orders',
  version: '1.0.0',
  type: 'external',
  status: 'prod',
  platform: 'n8n',
  platformUrl: 'https://n8n.client.com/workflow/123',
  externalId: 'n8n-workflow-123',
  triggers: {
    workflows: ['test-workflow-456']
  },
  uses: {
    integrations: ['integration-shopify-prod']
  }
}

const mockHumanCheckpoint: HumanCheckpointDefinition = {
  resourceId: 'sales-approval',
  name: 'Sales Approval Queue',
  description: 'High-value order approvals for sales team',
  version: '1.0.0',
  type: 'human',
  status: 'prod',
  requestedBy: {
    agents: ['test-agent-123']
  },
  routesTo: {
    workflows: ['test-workflow-456']
  }
}

// ============================================================================
// Type Guard Tests
// ============================================================================

describe('Command View Type Guards', () => {
  describe('isAgent', () => {
    it('returns true for agent nodes', () => {
      expect(isAgent(mockAgent)).toBe(true)
    })

    it('returns false for workflow nodes', () => {
      expect(isAgent(mockWorkflow)).toBe(false)
    })

    it('returns false for trigger nodes', () => {
      expect(isAgent(mockTrigger)).toBe(false)
    })

    it('returns false for integration nodes', () => {
      expect(isAgent(mockIntegration)).toBe(false)
    })

    it('returns false for external resource nodes', () => {
      expect(isAgent(mockExternalResource)).toBe(false)
    })

    it('returns false for human checkpoint nodes', () => {
      expect(isAgent(mockHumanCheckpoint)).toBe(false)
    })
  })

  describe('isWorkflow', () => {
    it('returns true for workflow nodes', () => {
      expect(isWorkflow(mockWorkflow)).toBe(true)
    })

    it('returns false for agent nodes', () => {
      expect(isWorkflow(mockAgent)).toBe(false)
    })

    it('returns false for trigger nodes', () => {
      expect(isWorkflow(mockTrigger)).toBe(false)
    })

    it('returns false for integration nodes', () => {
      expect(isWorkflow(mockIntegration)).toBe(false)
    })

    it('returns false for external resource nodes', () => {
      expect(isWorkflow(mockExternalResource)).toBe(false)
    })

    it('returns false for human checkpoint nodes', () => {
      expect(isWorkflow(mockHumanCheckpoint)).toBe(false)
    })
  })

  describe('isTrigger', () => {
    it('returns true for webhook trigger nodes', () => {
      expect(isTrigger(mockTrigger)).toBe(true)
    })

    it('verifies trigger detection uses triggerType field', () => {
      // Trigger is identified by presence of triggerType field
      expect('triggerType' in mockTrigger).toBe(true)
      expect(mockTrigger.triggerType).toBe('webhook')
    })

    it('returns false for agent nodes', () => {
      expect(isTrigger(mockAgent)).toBe(false)
    })

    it('returns false for workflow nodes', () => {
      expect(isTrigger(mockWorkflow)).toBe(false)
    })

    it('returns false for integration nodes', () => {
      expect(isTrigger(mockIntegration)).toBe(false)
    })

    it('returns false for external resource nodes', () => {
      expect(isTrigger(mockExternalResource)).toBe(false)
    })

    it('returns false for human checkpoint nodes', () => {
      expect(isTrigger(mockHumanCheckpoint)).toBe(false)
    })
  })

  describe('isIntegration', () => {
    it('returns true for integration nodes (type === integration)', () => {
      expect(isIntegration(mockIntegration)).toBe(true)
      expect(mockIntegration.type).toBe('integration')
    })

    it('returns false for agent nodes', () => {
      expect(isIntegration(mockAgent)).toBe(false)
    })

    it('returns false for workflow nodes', () => {
      expect(isIntegration(mockWorkflow)).toBe(false)
    })

    it('returns false for trigger nodes', () => {
      expect(isIntegration(mockTrigger)).toBe(false)
    })

    it('returns false for external resource nodes', () => {
      expect(isIntegration(mockExternalResource)).toBe(false)
    })

    it('returns false for human checkpoint nodes', () => {
      expect(isIntegration(mockHumanCheckpoint)).toBe(false)
    })
  })

  describe('isExternalResource', () => {
    it('returns true for external resource nodes (has platform)', () => {
      expect(isExternalResource(mockExternalResource)).toBe(true)
      expect('platform' in mockExternalResource).toBe(true)
      expect(mockExternalResource.platform).toBe('n8n')
    })

    it('returns false for agent nodes', () => {
      expect(isExternalResource(mockAgent)).toBe(false)
    })

    it('returns false for workflow nodes', () => {
      expect(isExternalResource(mockWorkflow)).toBe(false)
    })

    it('returns false for trigger nodes', () => {
      expect(isExternalResource(mockTrigger)).toBe(false)
    })

    it('returns false for integration nodes', () => {
      expect(isExternalResource(mockIntegration)).toBe(false)
    })

    it('returns false for human checkpoint nodes', () => {
      expect(isExternalResource(mockHumanCheckpoint)).toBe(false)
    })
  })

  describe('isHumanCheckpoint', () => {
    it('returns true for human checkpoint nodes with requestedBy', () => {
      const checkpoint: HumanCheckpointDefinition = {
        resourceId: 'checkpoint-1',
        name: 'Approval',
        description: 'Approval checkpoint',
        version: '1.0.0',
        type: 'human',
        status: 'prod',
        requestedBy: {
          agents: ['test-agent-123']
        }
      }
      expect(isHumanCheckpoint(checkpoint)).toBe(true)
    })

    it('returns true for human checkpoint nodes with routesTo', () => {
      const checkpoint: HumanCheckpointDefinition = {
        resourceId: 'checkpoint-2',
        name: 'Router',
        description: 'Routing checkpoint',
        version: '1.0.0',
        type: 'human',
        status: 'prod',
        routesTo: {
          workflows: ['test-workflow-456']
        }
      }
      expect(isHumanCheckpoint(checkpoint)).toBe(true)
    })

    it('returns true for human checkpoint nodes with both requestedBy and routesTo', () => {
      expect(isHumanCheckpoint(mockHumanCheckpoint)).toBe(true)
      expect('requestedBy' in mockHumanCheckpoint).toBe(true)
      expect('routesTo' in mockHumanCheckpoint).toBe(true)
    })

    it('returns false for agent nodes', () => {
      expect(isHumanCheckpoint(mockAgent)).toBe(false)
    })

    it('returns false for workflow nodes', () => {
      expect(isHumanCheckpoint(mockWorkflow)).toBe(false)
    })

    it('returns false for trigger nodes', () => {
      expect(isHumanCheckpoint(mockTrigger)).toBe(false)
    })

    it('returns false for integration nodes', () => {
      expect(isHumanCheckpoint(mockIntegration)).toBe(false)
    })

    it('returns false for external resource nodes', () => {
      expect(isHumanCheckpoint(mockExternalResource)).toBe(false)
    })
  })
})

// ============================================================================
// Helper Function Tests
// ============================================================================

describe('Command View Helper Functions', () => {
  describe('getNodeId', () => {
    it('returns resourceId for agent nodes', () => {
      expect(getNodeId(mockAgent)).toBe('test-agent-123')
    })

    it('returns resourceId for workflow nodes', () => {
      expect(getNodeId(mockWorkflow)).toBe('test-workflow-456')
    })

    it('returns resourceId for trigger nodes', () => {
      expect(getNodeId(mockTrigger)).toBe('test-trigger-789')
    })

    it('returns resourceId for integration nodes', () => {
      expect(getNodeId(mockIntegration)).toBe('integration-shopify-prod')
    })

    it('returns resourceId for external resource nodes', () => {
      expect(getNodeId(mockExternalResource)).toBe('external-n8n-sync')
    })

    it('returns resourceId for human checkpoint nodes', () => {
      expect(getNodeId(mockHumanCheckpoint)).toBe('sales-approval')
    })

    it('verifies all nodes use unified resourceId field', () => {
      const nodes: CommandViewNode[] = [
        mockAgent,
        mockWorkflow,
        mockTrigger,
        mockIntegration,
        mockExternalResource,
        mockHumanCheckpoint
      ]

      nodes.forEach((node) => {
        expect(node).toHaveProperty('resourceId')
        expect(typeof node.resourceId).toBe('string')
        expect(node.resourceId.length).toBeGreaterThan(0)
      })
    })
  })

  describe('getNodeType', () => {
    it('returns "agent" for agent nodes', () => {
      expect(getNodeType(mockAgent)).toBe('agent')
    })

    it('returns "workflow" for workflow nodes', () => {
      expect(getNodeType(mockWorkflow)).toBe('workflow')
    })

    it('returns "trigger" for trigger nodes', () => {
      expect(getNodeType(mockTrigger)).toBe('trigger')
    })

    it('returns "integration" for integration nodes', () => {
      expect(getNodeType(mockIntegration)).toBe('integration')
    })

    it('returns "external" for external resource nodes', () => {
      expect(getNodeType(mockExternalResource)).toBe('external')
    })

    it('returns "human" for human checkpoint nodes', () => {
      expect(getNodeType(mockHumanCheckpoint)).toBe('human')
    })

    it('handles all node types in collection', () => {
      const nodes: CommandViewNode[] = [
        mockAgent,
        mockWorkflow,
        mockTrigger,
        mockIntegration,
        mockExternalResource,
        mockHumanCheckpoint
      ]

      const expectedTypes = ['agent', 'workflow', 'trigger', 'integration', 'external', 'human']

      nodes.forEach((node, index) => {
        expect(getNodeType(node)).toBe(expectedTypes[index])
      })
    })
  })
})

