/**
 * Tests for Event Types and Type Guards
 */

import {
  EventType,
  type ProjectEvent,
  isEventType,
  isAgentEvent,
  isIssueEvent,
  isSprintEvent,
  isApprovalEvent,
  isWorkflowEvent,
  isProjectEvent,
} from '@/lib/types/events';

/**
 * Helper to create mock event
 */
function createMockEvent(overrides: Partial<ProjectEvent> = {}): ProjectEvent {
  return {
    id: 'event-123',
    type: EventType.AGENT_MESSAGE,
    timestamp: new Date().toISOString(),
    project_id: 'project-123',
    actor_id: 'agent-456',
    actor_type: 'agent',
    payload: {},
    ...overrides,
  };
}

describe('Event Types', () => {
  describe('EventType enum', () => {
    it('should have correct agent event values', () => {
      expect(EventType.AGENT_SPAWNED).toBe('agent.spawned');
      expect(EventType.AGENT_STATUS_CHANGED).toBe('agent.status_changed');
      expect(EventType.AGENT_MESSAGE).toBe('agent.message');
      expect(EventType.AGENT_TERMINATED).toBe('agent.terminated');
    });

    it('should have correct issue event values', () => {
      expect(EventType.ISSUE_CREATED).toBe('issue.created');
      expect(EventType.ISSUE_UPDATED).toBe('issue.updated');
      expect(EventType.ISSUE_ASSIGNED).toBe('issue.assigned');
      expect(EventType.ISSUE_CLOSED).toBe('issue.closed');
    });

    it('should have correct sprint event values', () => {
      expect(EventType.SPRINT_STARTED).toBe('sprint.started');
      expect(EventType.SPRINT_COMPLETED).toBe('sprint.completed');
    });

    it('should have correct approval event values', () => {
      expect(EventType.APPROVAL_REQUESTED).toBe('approval.requested');
      expect(EventType.APPROVAL_GRANTED).toBe('approval.granted');
      expect(EventType.APPROVAL_DENIED).toBe('approval.denied');
    });

    it('should have correct workflow event values', () => {
      expect(EventType.WORKFLOW_STARTED).toBe('workflow.started');
      expect(EventType.WORKFLOW_STEP_COMPLETED).toBe('workflow.step_completed');
      expect(EventType.WORKFLOW_COMPLETED).toBe('workflow.completed');
      expect(EventType.WORKFLOW_FAILED).toBe('workflow.failed');
    });

    it('should have correct project event values', () => {
      expect(EventType.PROJECT_CREATED).toBe('project.created');
      expect(EventType.PROJECT_UPDATED).toBe('project.updated');
      expect(EventType.PROJECT_ARCHIVED).toBe('project.archived');
    });
  });

  describe('isEventType', () => {
    it('should return true for matching event type', () => {
      const event = createMockEvent({ type: EventType.AGENT_MESSAGE });
      expect(isEventType(event, EventType.AGENT_MESSAGE)).toBe(true);
    });

    it('should return false for non-matching event type', () => {
      const event = createMockEvent({ type: EventType.AGENT_MESSAGE });
      expect(isEventType(event, EventType.ISSUE_CREATED)).toBe(false);
    });
  });

  describe('isAgentEvent', () => {
    it('should return true for agent events', () => {
      expect(isAgentEvent(createMockEvent({ type: EventType.AGENT_SPAWNED }))).toBe(true);
      expect(isAgentEvent(createMockEvent({ type: EventType.AGENT_MESSAGE }))).toBe(true);
      expect(isAgentEvent(createMockEvent({ type: EventType.AGENT_STATUS_CHANGED }))).toBe(true);
      expect(isAgentEvent(createMockEvent({ type: EventType.AGENT_TERMINATED }))).toBe(true);
    });

    it('should return false for non-agent events', () => {
      expect(isAgentEvent(createMockEvent({ type: EventType.ISSUE_CREATED }))).toBe(false);
      expect(isAgentEvent(createMockEvent({ type: EventType.SPRINT_STARTED }))).toBe(false);
    });
  });

  describe('isIssueEvent', () => {
    it('should return true for issue events', () => {
      expect(isIssueEvent(createMockEvent({ type: EventType.ISSUE_CREATED }))).toBe(true);
      expect(isIssueEvent(createMockEvent({ type: EventType.ISSUE_UPDATED }))).toBe(true);
      expect(isIssueEvent(createMockEvent({ type: EventType.ISSUE_ASSIGNED }))).toBe(true);
      expect(isIssueEvent(createMockEvent({ type: EventType.ISSUE_CLOSED }))).toBe(true);
    });

    it('should return false for non-issue events', () => {
      expect(isIssueEvent(createMockEvent({ type: EventType.AGENT_MESSAGE }))).toBe(false);
      expect(isIssueEvent(createMockEvent({ type: EventType.SPRINT_STARTED }))).toBe(false);
    });
  });

  describe('isSprintEvent', () => {
    it('should return true for sprint events', () => {
      expect(isSprintEvent(createMockEvent({ type: EventType.SPRINT_STARTED }))).toBe(true);
      expect(isSprintEvent(createMockEvent({ type: EventType.SPRINT_COMPLETED }))).toBe(true);
    });

    it('should return false for non-sprint events', () => {
      expect(isSprintEvent(createMockEvent({ type: EventType.AGENT_MESSAGE }))).toBe(false);
      expect(isSprintEvent(createMockEvent({ type: EventType.ISSUE_CREATED }))).toBe(false);
    });
  });

  describe('isApprovalEvent', () => {
    it('should return true for approval events', () => {
      expect(isApprovalEvent(createMockEvent({ type: EventType.APPROVAL_REQUESTED }))).toBe(true);
      expect(isApprovalEvent(createMockEvent({ type: EventType.APPROVAL_GRANTED }))).toBe(true);
      expect(isApprovalEvent(createMockEvent({ type: EventType.APPROVAL_DENIED }))).toBe(true);
    });

    it('should return false for non-approval events', () => {
      expect(isApprovalEvent(createMockEvent({ type: EventType.AGENT_MESSAGE }))).toBe(false);
      expect(isApprovalEvent(createMockEvent({ type: EventType.WORKFLOW_STARTED }))).toBe(false);
    });
  });

  describe('isWorkflowEvent', () => {
    it('should return true for workflow events', () => {
      expect(isWorkflowEvent(createMockEvent({ type: EventType.WORKFLOW_STARTED }))).toBe(true);
      expect(isWorkflowEvent(createMockEvent({ type: EventType.WORKFLOW_STEP_COMPLETED }))).toBe(
        true
      );
      expect(isWorkflowEvent(createMockEvent({ type: EventType.WORKFLOW_COMPLETED }))).toBe(true);
      expect(isWorkflowEvent(createMockEvent({ type: EventType.WORKFLOW_FAILED }))).toBe(true);
    });

    it('should return false for non-workflow events', () => {
      expect(isWorkflowEvent(createMockEvent({ type: EventType.AGENT_MESSAGE }))).toBe(false);
      expect(isWorkflowEvent(createMockEvent({ type: EventType.SPRINT_STARTED }))).toBe(false);
    });
  });

  describe('isProjectEvent', () => {
    it('should return true for project events', () => {
      expect(isProjectEvent(createMockEvent({ type: EventType.PROJECT_CREATED }))).toBe(true);
      expect(isProjectEvent(createMockEvent({ type: EventType.PROJECT_UPDATED }))).toBe(true);
      expect(isProjectEvent(createMockEvent({ type: EventType.PROJECT_ARCHIVED }))).toBe(true);
    });

    it('should return false for non-project events', () => {
      expect(isProjectEvent(createMockEvent({ type: EventType.AGENT_MESSAGE }))).toBe(false);
      expect(isProjectEvent(createMockEvent({ type: EventType.ISSUE_CREATED }))).toBe(false);
    });
  });
});
