import { describe, it, expect, beforeEach, vi } from "vitest";
import { Test, TestingModule } from "@nestjs/testing";
import { DashboardController } from "./dashboard.controller";
import { DashboardService } from "./dashboard.service";
import { AuthGuard } from "../auth/guards/auth.guard";
import { WorkspaceGuard } from "../common/guards/workspace.guard";
import { PermissionGuard } from "../common/guards/permission.guard";
import type { DashboardSummaryDto } from "./dto";

describe("DashboardController", () => {
  let controller: DashboardController;
  let service: DashboardService;

  const mockWorkspaceId = "550e8400-e29b-41d4-a716-446655440001";

  const mockSummary: DashboardSummaryDto = {
    metrics: {
      activeAgents: 3,
      tasksCompleted: 12,
      totalTasks: 25,
      tasksInProgress: 5,
      activeProjects: 4,
      errorRate: 2.5,
    },
    recentActivity: [
      {
        id: "550e8400-e29b-41d4-a716-446655440010",
        action: "CREATED",
        entityType: "TASK",
        entityId: "550e8400-e29b-41d4-a716-446655440011",
        details: { title: "New task" },
        userId: "550e8400-e29b-41d4-a716-446655440002",
        createdAt: "2026-02-22T12:00:00.000Z",
      },
    ],
    activeJobs: [
      {
        id: "550e8400-e29b-41d4-a716-446655440020",
        type: "code-task",
        status: "RUNNING",
        progressPercent: 45,
        createdAt: "2026-02-22T11:00:00.000Z",
        updatedAt: "2026-02-22T11:30:00.000Z",
        steps: [
          {
            id: "550e8400-e29b-41d4-a716-446655440030",
            name: "Setup",
            status: "COMPLETED",
            phase: "SETUP",
          },
        ],
      },
    ],
    tokenBudget: [
      {
        model: "agent-1",
        used: 5000,
        limit: 10000,
      },
    ],
  };

  const mockDashboardService = {
    getSummary: vi.fn(),
  };

  const mockAuthGuard = {
    canActivate: vi.fn(() => true),
  };

  const mockWorkspaceGuard = {
    canActivate: vi.fn(() => true),
  };

  const mockPermissionGuard = {
    canActivate: vi.fn(() => true),
  };

  beforeEach(async () => {
    const module: TestingModule = await Test.createTestingModule({
      controllers: [DashboardController],
      providers: [
        {
          provide: DashboardService,
          useValue: mockDashboardService,
        },
      ],
    })
      .overrideGuard(AuthGuard)
      .useValue(mockAuthGuard)
      .overrideGuard(WorkspaceGuard)
      .useValue(mockWorkspaceGuard)
      .overrideGuard(PermissionGuard)
      .useValue(mockPermissionGuard)
      .compile();

    controller = module.get<DashboardController>(DashboardController);
    service = module.get<DashboardService>(DashboardService);

    vi.clearAllMocks();
  });

  it("should be defined", () => {
    expect(controller).toBeDefined();
  });

  describe("getSummary", () => {
    it("should return dashboard summary for workspace", async () => {
      mockDashboardService.getSummary.mockResolvedValue(mockSummary);

      const result = await controller.getSummary(mockWorkspaceId);

      expect(result).toEqual(mockSummary);
      expect(service.getSummary).toHaveBeenCalledWith(mockWorkspaceId);
    });

    it("should return empty arrays when no data exists", async () => {
      const emptySummary: DashboardSummaryDto = {
        metrics: {
          activeAgents: 0,
          tasksCompleted: 0,
          totalTasks: 0,
          tasksInProgress: 0,
          activeProjects: 0,
          errorRate: 0,
        },
        recentActivity: [],
        activeJobs: [],
        tokenBudget: [],
      };

      mockDashboardService.getSummary.mockResolvedValue(emptySummary);

      const result = await controller.getSummary(mockWorkspaceId);

      expect(result).toEqual(emptySummary);
      expect(result.metrics.errorRate).toBe(0);
      expect(result.recentActivity).toHaveLength(0);
      expect(result.activeJobs).toHaveLength(0);
      expect(result.tokenBudget).toHaveLength(0);
    });
  });
});
