import { describe, it, expect, beforeEach } from "vitest";
import {
  initializeMetrics,
  recordTaskAssignment,
  recordTaskCompletion,
  recordTaskApproval,
  recordReportSubmission,
  getMetrics,
  getAllMetrics,
  getMetricsSummary,
  getTopPerformers,
} from "./aiPerformanceMetrics.ts";
import { AIEmployeeRole } from "./aiEmployeeSystem.ts";
import { getNextReportTime } from "./scheduledReports.ts";

describe("AI Integration System", () => {
  beforeEach(() => {
    initializeMetrics();
  });

  describe("Performance Metrics", () => {
    it("should initialize metrics for all AI employees", () => {
      const allMetrics = getAllMetrics();
      expect(allMetrics.length).toBe(7); // 7 AI employees
      expect(allMetrics.every((m) => m.performanceScore >= 0 && m.performanceScore <= 100)).toBe(true);
    });

    it("should record task assignment", () => {
      recordTaskAssignment(AIEmployeeRole.FRAUD_AI);
      const metrics = getMetrics(AIEmployeeRole.FRAUD_AI);
      expect(metrics?.tasksAssigned).toBe(1);
    });

    it("should record task completion", () => {
      recordTaskAssignment(AIEmployeeRole.GAME_AI);
      recordTaskCompletion(AIEmployeeRole.GAME_AI, 30);
      const metrics = getMetrics(AIEmployeeRole.GAME_AI);
      expect(metrics?.tasksCompleted).toBe(1);
      expect(metrics?.averageCompletionTime).toBe(30);
    });

    it("should record task approval", () => {
      recordTaskAssignment(AIEmployeeRole.LUCKY_AI);
      recordTaskApproval(AIEmployeeRole.LUCKY_AI);
      const metrics = getMetrics(AIEmployeeRole.LUCKY_AI);
      expect(metrics?.tasksApproved).toBe(1);
      expect(metrics?.approvalRate).toBeGreaterThan(0);
    });

    it("should record report submission", () => {
      recordReportSubmission(AIEmployeeRole.SLOTS_AI, 8.5);
      const metrics = getMetrics(AIEmployeeRole.SLOTS_AI);
      expect(metrics?.reportsSubmitted).toBe(1);
      expect(metrics?.averageReportQuality).toBe(8.5);
    });

    it("should calculate average completion time correctly", () => {
      recordTaskAssignment(AIEmployeeRole.BINGO_AI);
      recordTaskCompletion(AIEmployeeRole.BINGO_AI, 10);
      recordTaskCompletion(AIEmployeeRole.BINGO_AI, 20);
      recordTaskCompletion(AIEmployeeRole.BINGO_AI, 30);
      const metrics = getMetrics(AIEmployeeRole.BINGO_AI);
      expect(metrics?.averageCompletionTime).toBe(20); // (10+20+30)/3
    });

    it("should get metrics summary", () => {
      recordTaskAssignment(AIEmployeeRole.FRAUD_AI);
      recordTaskAssignment(AIEmployeeRole.GAME_AI);
      recordTaskCompletion(AIEmployeeRole.FRAUD_AI, 15);
      recordReportSubmission(AIEmployeeRole.FRAUD_AI, 9);

      const summary = getMetricsSummary();
      expect(summary.totalTasksAssigned).toBeGreaterThan(0);
      expect(summary.totalTasksCompleted).toBeGreaterThan(0);
      expect(summary.averagePerformanceScore).toBeGreaterThan(0);
      expect(summary.topPerformer).toBeDefined();
    });

    it("should get top performers", () => {
      const topPerformers = getTopPerformers(3);
      expect(topPerformers.length).toBeLessThanOrEqual(3);
      // Verify they're sorted by performance score descending
      for (let i = 0; i < topPerformers.length - 1; i++) {
        expect(topPerformers[i].performanceScore).toBeGreaterThanOrEqual(topPerformers[i + 1].performanceScore);
      }
    });
  });

  describe("Scheduled Reports", () => {
    it("should calculate next report time", () => {
      const nextTime = getNextReportTime();
      expect(nextTime).toBeInstanceOf(Date);
      expect(nextTime.getHours()).toBe(17); // 5 PM
      expect(nextTime > new Date()).toBe(true);
    });

    it("should schedule for tomorrow if past 5 PM", () => {
      const now = new Date();
      if (now.getHours() >= 17) {
        const nextTime = getNextReportTime();
        expect(nextTime.getDate()).toBeGreaterThan(now.getDate());
      }
    });
  });

  describe("AI Employee Roles", () => {
    it("should have all required AI employee roles", () => {
      const allMetrics = getAllMetrics();
      const roles = allMetrics.map((m) => m.employeeRole);

      expect(roles).toContain(AIEmployeeRole.LUCKY_AI);
      expect(roles).toContain(AIEmployeeRole.FRAUD_AI);
      expect(roles).toContain(AIEmployeeRole.GAME_AI);
      expect(roles).toContain(AIEmployeeRole.SLOTS_AI);
      expect(roles).toContain(AIEmployeeRole.BINGO_AI);
      expect(roles).toContain(AIEmployeeRole.POKER_AI);
      expect(roles).toContain(AIEmployeeRole.SPORTS_AI);
    });
  });

  describe("Performance Score Calculation", () => {
    it("should calculate performance score based on metrics", () => {
      // Simulate good performance
      for (let i = 0; i < 5; i++) {
        recordTaskAssignment(AIEmployeeRole.FRAUD_AI);
        recordTaskCompletion(AIEmployeeRole.FRAUD_AI, 10);
        recordTaskApproval(AIEmployeeRole.FRAUD_AI);
      }
      recordReportSubmission(AIEmployeeRole.FRAUD_AI, 9);

      const metrics = getMetrics(AIEmployeeRole.FRAUD_AI);
      expect(metrics?.performanceScore).toBeGreaterThan(70);
    });

    it("should have performance score between 0 and 100", () => {
      const allMetrics = getAllMetrics();
      allMetrics.forEach((m) => {
        expect(m.performanceScore).toBeGreaterThanOrEqual(0);
        expect(m.performanceScore).toBeLessThanOrEqual(100);
      });
    });
  });
});
