import { describe, it, expect } from "vitest";
import { validate } from "class-validator";
import { plainToInstance } from "class-transformer";
import { QueryActivityLogDto } from "./query-activity-log.dto";
import { ActivityAction, EntityType } from "@prisma/client";

describe("QueryActivityLogDto", () => {
  describe("workspaceId validation", () => {
    it("should pass with valid UUID", async () => {
      const dto = plainToInstance(QueryActivityLogDto, {
        workspaceId: "550e8400-e29b-41d4-a716-446655440000",
      });

      const errors = await validate(dto);
      expect(errors).toHaveLength(0);
    });

    it("should fail with invalid UUID", async () => {
      const dto = plainToInstance(QueryActivityLogDto, {
        workspaceId: "invalid-uuid",
      });

      const errors = await validate(dto);
      expect(errors.length).toBeGreaterThan(0);
      expect(errors[0].property).toBe("workspaceId");
      expect(errors[0].constraints?.isUuid).toBeDefined();
    });

    it("should pass when workspaceId is missing (it's optional)", async () => {
      const dto = plainToInstance(QueryActivityLogDto, {});

      const errors = await validate(dto);
      // workspaceId is optional in DTO since it's set by controller from @Workspace() decorator
      const workspaceIdError = errors.find((e) => e.property === "workspaceId");
      expect(workspaceIdError).toBeUndefined();
    });
  });

  describe("userId validation", () => {
    it("should pass with valid UUID", async () => {
      const dto = plainToInstance(QueryActivityLogDto, {
        workspaceId: "550e8400-e29b-41d4-a716-446655440000",
        userId: "550e8400-e29b-41d4-a716-446655440001",
      });

      const errors = await validate(dto);
      expect(errors).toHaveLength(0);
    });

    it("should fail with invalid UUID", async () => {
      const dto = plainToInstance(QueryActivityLogDto, {
        workspaceId: "550e8400-e29b-41d4-a716-446655440000",
        userId: "not-a-uuid",
      });

      const errors = await validate(dto);
      expect(errors.length).toBeGreaterThan(0);
      expect(errors[0].property).toBe("userId");
    });

    it("should pass when userId is not provided (optional)", async () => {
      const dto = plainToInstance(QueryActivityLogDto, {
        workspaceId: "550e8400-e29b-41d4-a716-446655440000",
      });

      const errors = await validate(dto);
      expect(errors).toHaveLength(0);
    });
  });

  describe("action validation", () => {
    it("should pass with valid ActivityAction", async () => {
      const dto = plainToInstance(QueryActivityLogDto, {
        workspaceId: "550e8400-e29b-41d4-a716-446655440000",
        action: ActivityAction.CREATED,
      });

      const errors = await validate(dto);
      expect(errors).toHaveLength(0);
    });

    it("should fail with invalid action value", async () => {
      const dto = plainToInstance(QueryActivityLogDto, {
        workspaceId: "550e8400-e29b-41d4-a716-446655440000",
        action: "INVALID_ACTION",
      });

      const errors = await validate(dto);
      expect(errors.length).toBeGreaterThan(0);
      expect(errors[0].property).toBe("action");
    });

    it("should pass when action is not provided (optional)", async () => {
      const dto = plainToInstance(QueryActivityLogDto, {
        workspaceId: "550e8400-e29b-41d4-a716-446655440000",
      });

      const errors = await validate(dto);
      expect(errors).toHaveLength(0);
    });
  });

  describe("entityType validation", () => {
    it("should pass with valid EntityType", async () => {
      const dto = plainToInstance(QueryActivityLogDto, {
        workspaceId: "550e8400-e29b-41d4-a716-446655440000",
        entityType: EntityType.TASK,
      });

      const errors = await validate(dto);
      expect(errors).toHaveLength(0);
    });

    it("should fail with invalid entityType value", async () => {
      const dto = plainToInstance(QueryActivityLogDto, {
        workspaceId: "550e8400-e29b-41d4-a716-446655440000",
        entityType: "INVALID_TYPE",
      });

      const errors = await validate(dto);
      expect(errors.length).toBeGreaterThan(0);
      expect(errors[0].property).toBe("entityType");
    });
  });

  describe("entityId validation", () => {
    it("should pass with valid UUID", async () => {
      const dto = plainToInstance(QueryActivityLogDto, {
        workspaceId: "550e8400-e29b-41d4-a716-446655440000",
        entityId: "550e8400-e29b-41d4-a716-446655440002",
      });

      const errors = await validate(dto);
      expect(errors).toHaveLength(0);
    });

    it("should fail with invalid UUID", async () => {
      const dto = plainToInstance(QueryActivityLogDto, {
        workspaceId: "550e8400-e29b-41d4-a716-446655440000",
        entityId: "invalid-entity-id",
      });

      const errors = await validate(dto);
      expect(errors.length).toBeGreaterThan(0);
      expect(errors[0].property).toBe("entityId");
    });
  });

  describe("date validation", () => {
    it("should pass with valid ISO date strings", async () => {
      const dto = plainToInstance(QueryActivityLogDto, {
        workspaceId: "550e8400-e29b-41d4-a716-446655440000",
        startDate: "2024-01-01T00:00:00.000Z",
        endDate: "2024-01-31T23:59:59.999Z",
      });

      const errors = await validate(dto);
      expect(errors).toHaveLength(0);
    });

    it("should fail with invalid date format", async () => {
      const dto = plainToInstance(QueryActivityLogDto, {
        workspaceId: "550e8400-e29b-41d4-a716-446655440000",
        startDate: "not-a-date",
      });

      const errors = await validate(dto);
      expect(errors.length).toBeGreaterThan(0);
      expect(errors[0].property).toBe("startDate");
    });
  });

  describe("pagination validation", () => {
    it("should pass with valid page and limit", async () => {
      const dto = plainToInstance(QueryActivityLogDto, {
        workspaceId: "550e8400-e29b-41d4-a716-446655440000",
        page: "1",
        limit: "50",
      });

      const errors = await validate(dto);
      expect(errors).toHaveLength(0);
      expect(dto.page).toBe(1);
      expect(dto.limit).toBe(50);
    });

    it("should fail when page is less than 1", async () => {
      const dto = plainToInstance(QueryActivityLogDto, {
        workspaceId: "550e8400-e29b-41d4-a716-446655440000",
        page: "0",
      });

      const errors = await validate(dto);
      expect(errors.length).toBeGreaterThan(0);
      const pageError = errors.find((e) => e.property === "page");
      expect(pageError?.constraints?.min).toBeDefined();
    });

    it("should fail when limit exceeds 100", async () => {
      const dto = plainToInstance(QueryActivityLogDto, {
        workspaceId: "550e8400-e29b-41d4-a716-446655440000",
        limit: "101",
      });

      const errors = await validate(dto);
      expect(errors.length).toBeGreaterThan(0);
      const limitError = errors.find((e) => e.property === "limit");
      expect(limitError?.constraints?.max).toBeDefined();
    });

    it("should fail when page is not an integer", async () => {
      const dto = plainToInstance(QueryActivityLogDto, {
        workspaceId: "550e8400-e29b-41d4-a716-446655440000",
        page: "1.5",
      });

      const errors = await validate(dto);
      expect(errors.length).toBeGreaterThan(0);
      const pageError = errors.find((e) => e.property === "page");
      expect(pageError?.constraints?.isInt).toBeDefined();
    });

    it("should fail when limit is not an integer", async () => {
      const dto = plainToInstance(QueryActivityLogDto, {
        workspaceId: "550e8400-e29b-41d4-a716-446655440000",
        limit: "50.5",
      });

      const errors = await validate(dto);
      expect(errors.length).toBeGreaterThan(0);
      const limitError = errors.find((e) => e.property === "limit");
      expect(limitError?.constraints?.isInt).toBeDefined();
    });
  });

  describe("multiple filters", () => {
    it("should pass with all valid filters combined", async () => {
      const dto = plainToInstance(QueryActivityLogDto, {
        workspaceId: "550e8400-e29b-41d4-a716-446655440000",
        userId: "550e8400-e29b-41d4-a716-446655440001",
        action: ActivityAction.UPDATED,
        entityType: EntityType.PROJECT,
        entityId: "550e8400-e29b-41d4-a716-446655440002",
        startDate: "2024-01-01T00:00:00.000Z",
        endDate: "2024-01-31T23:59:59.999Z",
        page: "2",
        limit: "25",
      });

      const errors = await validate(dto);
      expect(errors).toHaveLength(0);
    });
  });
});
