import { describe, expect, it } from "vitest";
import { validate } from "class-validator";
import { plainToClass } from "class-transformer";
import { QueryTasksDto } from "./query-tasks.dto";
import { TaskStatus, TaskPriority } from "@prisma/client";
import { SortOrder } from "../../common/dto";

describe("QueryTasksDto", () => {
  const validWorkspaceId = "123e4567-e89b-42d3-a456-426614174000"; // Valid UUID v4 (4 in third group)

  it("should accept valid workspaceId", async () => {
    const dto = plainToClass(QueryTasksDto, {
      workspaceId: validWorkspaceId,
    });

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

  it("should reject invalid workspaceId", async () => {
    const dto = plainToClass(QueryTasksDto, {
      workspaceId: "not-a-uuid",
    });

    const errors = await validate(dto);
    expect(errors.length).toBeGreaterThan(0);
    expect(errors.some((e) => e.property === "workspaceId")).toBe(true);
  });

  it("should accept valid status filter", async () => {
    const dto = plainToClass(QueryTasksDto, {
      workspaceId: validWorkspaceId,
      status: TaskStatus.IN_PROGRESS,
    });

    const errors = await validate(dto);
    expect(errors.length).toBe(0);
    expect(Array.isArray(dto.status)).toBe(true);
    expect(dto.status).toEqual([TaskStatus.IN_PROGRESS]);
  });

  it("should accept multiple status filters", async () => {
    const dto = plainToClass(QueryTasksDto, {
      workspaceId: validWorkspaceId,
      status: [TaskStatus.IN_PROGRESS, TaskStatus.NOT_STARTED],
    });

    const errors = await validate(dto);
    expect(errors.length).toBe(0);
    expect(Array.isArray(dto.status)).toBe(true);
    expect(dto.status).toHaveLength(2);
  });

  it("should accept valid priority filter", async () => {
    const dto = plainToClass(QueryTasksDto, {
      workspaceId: validWorkspaceId,
      priority: TaskPriority.HIGH,
    });

    const errors = await validate(dto);
    expect(errors.length).toBe(0);
    expect(Array.isArray(dto.priority)).toBe(true);
    expect(dto.priority).toEqual([TaskPriority.HIGH]);
  });

  it("should accept multiple priority filters", async () => {
    const dto = plainToClass(QueryTasksDto, {
      workspaceId: validWorkspaceId,
      priority: [TaskPriority.HIGH, TaskPriority.LOW],
    });

    const errors = await validate(dto);
    expect(errors.length).toBe(0);
    expect(Array.isArray(dto.priority)).toBe(true);
    expect(dto.priority).toHaveLength(2);
  });

  it("should accept search parameter", async () => {
    const dto = plainToClass(QueryTasksDto, {
      workspaceId: validWorkspaceId,
      search: "test task",
    });

    const errors = await validate(dto);
    expect(errors.length).toBe(0);
    expect(dto.search).toBe("test task");
  });

  it("should accept sortBy parameter", async () => {
    const dto = plainToClass(QueryTasksDto, {
      workspaceId: validWorkspaceId,
      sortBy: "priority,dueDate",
    });

    const errors = await validate(dto);
    expect(errors.length).toBe(0);
    expect(dto.sortBy).toBe("priority,dueDate");
  });

  it("should accept sortOrder parameter", async () => {
    const dto = plainToClass(QueryTasksDto, {
      workspaceId: validWorkspaceId,
      sortOrder: SortOrder.ASC,
    });

    const errors = await validate(dto);
    expect(errors.length).toBe(0);
    expect(dto.sortOrder).toBe(SortOrder.ASC);
  });

  it("should accept domainId filter", async () => {
    const domainId = "123e4567-e89b-42d3-a456-426614174001"; // Valid UUID v4
    const dto = plainToClass(QueryTasksDto, {
      workspaceId: validWorkspaceId,
      domainId,
    });

    const errors = await validate(dto);
    expect(errors.length).toBe(0);
    expect(Array.isArray(dto.domainId)).toBe(true);
    expect(dto.domainId).toEqual([domainId]);
  });

  it("should accept multiple domainId filters", async () => {
    const domainIds = [
      "123e4567-e89b-42d3-a456-426614174001", // Valid UUID v4
      "123e4567-e89b-42d3-a456-426614174002", // Valid UUID v4
    ];
    const dto = plainToClass(QueryTasksDto, {
      workspaceId: validWorkspaceId,
      domainId: domainIds,
    });

    const errors = await validate(dto);
    expect(errors.length).toBe(0);
    expect(Array.isArray(dto.domainId)).toBe(true);
    expect(dto.domainId).toHaveLength(2);
  });

  it("should accept date range filters", async () => {
    const dto = plainToClass(QueryTasksDto, {
      workspaceId: validWorkspaceId,
      dueDateFrom: "2024-01-01T00:00:00Z",
      dueDateTo: "2024-12-31T23:59:59Z",
    });

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

  it("should accept all filters combined", async () => {
    const dto = plainToClass(QueryTasksDto, {
      workspaceId: validWorkspaceId,
      status: [TaskStatus.IN_PROGRESS, TaskStatus.NOT_STARTED],
      priority: [TaskPriority.HIGH, TaskPriority.MEDIUM],
      search: "urgent task",
      sortBy: "priority,dueDate",
      sortOrder: SortOrder.ASC,
      page: 2,
      limit: 25,
      dueDateFrom: "2024-01-01T00:00:00Z",
      dueDateTo: "2024-12-31T23:59:59Z",
    });

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