import {
  IsOptional,
  IsInt,
  Min,
  Max,
  IsString,
  IsEnum,
  IsDateString,
  MaxLength,
} from "class-validator";
import { Type, Transform } from "class-transformer";

/**
 * Enum for sort order
 */
export enum SortOrder {
  ASC = "asc",
  DESC = "desc",
}

/**
 * Base DTO for pagination
 */
export class BasePaginationDto {
  @IsOptional()
  @Type(() => Number)
  @IsInt({ message: "page must be an integer" })
  @Min(1, { message: "page must be at least 1" })
  page?: number = 1;

  @IsOptional()
  @Type(() => Number)
  @IsInt({ message: "limit must be an integer" })
  @Min(1, { message: "limit must be at least 1" })
  @Max(100, { message: "limit must not exceed 100" })
  limit?: number = 50;
}

/**
 * Base DTO for filtering and sorting
 * Provides common filtering capabilities across all entities
 */
export class BaseFilterDto extends BasePaginationDto {
  /**
   * Full-text search query
   * Searches across title, description, and other text fields
   */
  @IsOptional()
  @IsString({ message: "search must be a string" })
  @MaxLength(500, { message: "search must not exceed 500 characters" })
  @Transform(({ value }) => (typeof value === "string" ? value.trim() : (value as string)))
  search?: string;

  /**
   * Field(s) to sort by
   * Can be comma-separated for multi-field sorting (e.g., "priority,createdAt")
   */
  @IsOptional()
  @IsString({ message: "sortBy must be a string" })
  sortBy?: string;

  /**
   * Sort order (ascending or descending)
   */
  @IsOptional()
  @IsEnum(SortOrder, { message: "sortOrder must be either 'asc' or 'desc'" })
  sortOrder?: SortOrder = SortOrder.DESC;

  /**
   * Filter by date range - start date
   */
  @IsOptional()
  @IsDateString({}, { message: "dateFrom must be a valid ISO 8601 date string" })
  dateFrom?: Date;

  /**
   * Filter by date range - end date
   */
  @IsOptional()
  @IsDateString({}, { message: "dateTo must be a valid ISO 8601 date string" })
  dateTo?: Date;
}
