// Import Swagger decorator for optional API documentation
import { ApiPropertyOptional } from '@nestjs/swagger';

// Import class-transformer for nested object transformation
import { Type } from 'class-transformer';

// Import class-validator decorators for input validation
import {
  IsArray,
  IsBoolean,
  IsOptional,
  IsString,
  ValidateNested,
} from 'class-validator';

// Import reusable DTO for date range filtering
import { DateRangeDto } from 'src/utils/datetime/dateRangeDto';

// Import base pagination DTO for inheritance
import { PaginationDto } from 'src/config/pagination/paginationDto';

/**
 * SearchMenuDto - Data Transfer Object for searching/filtering menus with pagination
 *
 * This DTO extends PaginationDto to combine search/filter parameters with pagination.
 * It provides comprehensive filtering capabilities for menu search operations.
 *
 * Design Pattern: Composite DTO (Pagination + Filtering)
 *
 * Purpose:
 * - Used in POST /menus/all endpoint for advanced menu searches
 * - Supports complex filtering scenarios with multiple criteria
 * - Enables paginated search results
 * - Provides both simple and nested filtering options
 *
 * Key Features:
 * - Inherits pagination (page, per_page, sort_by, order_by)
 * - Text search on menu title/controller
 * - Multi-select filters (arrays)
 * - Date range filtering with nested DTO
 * - CSV export flag
 */
export class SearchMenuDto extends PaginationDto {
  /**
   * search_title - Text search across menu title and controller fields
   *
   * Validation Rules:
   * - @IsOptional(): Optional parameter
   * - @IsString(): Must be a string if provided
   *
   * Swagger Documentation:
   * - @ApiPropertyOptional(): Marked as optional in Swagger
   *
   * Business Context:
   * - Used for free-text search in menu titles and controllers
   * - Typically performs SQL LIKE '%search_title%' queries
   * - Case-insensitive search in implementation
   *
   * Implementation Note:
   * - In service, this likely searches both 'title' and 'controller' fields
   */
  @ApiPropertyOptional()
  @IsOptional()
  @IsString()
  search_title?: string;

  /**
   * created_by - Filter by user IDs who created the menus
   *
   * Validation Rules:
   * - @IsOptional(): Optional parameter
   * - @IsArray(): Must be an array if provided
   * - @IsString({ each: true }): Each array element must be a string
   *
   * Swagger Documentation:
   * - @ApiPropertyOptional({ type: [String] }): Documents as string array
   *
   * Business Context:
   * - Multi-select filter for creator users
   * - Used in admin interfaces to filter by specific creators
   * - Supports "show menus created by these users" functionality
   *
   * Example Value:
   * - ["123", "456", "789"] - Filter by these user IDs
   */
  @ApiPropertyOptional({ type: [String] })
  @IsOptional()
  @IsArray()
  @IsString({ each: true })
  created_by?: string[];

  /**
   * updated_by - Filter by user IDs who last updated the menus
   *
   * Validation Rules:
   * - @IsOptional(): Optional parameter
   * - @IsArray(): Must be an array if provided
   * - @IsString({ each: true }): Each array element must be a string
   *
   * Business Context:
   * - Multi-select filter for last updater users
   * - Useful for audit trails and change tracking
   * - "Show menus last modified by these users"
   *
   * Implementation Note:
   * - String array for user IDs (TypeORM handles conversion to numbers)
   */
  @ApiPropertyOptional({ type: [String] })
  @IsOptional()
  @IsArray()
  @IsString({ each: true })
  updated_by?: string[];

  /**
   * active - Filter by active status values
   *
   * Validation Rules:
   * - @IsOptional(): Optional parameter
   * - @IsArray(): Must be an array if provided
   * - @IsString({ each: true }): Each array element must be a string
   *
   * Business Context:
   * - Multi-select filter for status values
   * - Allows filtering by multiple statuses simultaneously
   * - Example: Show both active (1) and inactive (0) menus
   *
   * Common Values:
   * - ["1"]: Only active menus
   * - ["0"]: Only inactive menus
   * - ["1", "0"]: All menus regardless of status
   */
  @ApiPropertyOptional({ type: [String] })
  @IsOptional()
  @IsArray()
  @IsString({ each: true })
  active?: string[];

  /**
   * is_csv - Flag to indicate CSV export request
   *
   * Validation Rules:
   * - @IsOptional(): Optional parameter
   * - @IsBoolean(): Must be boolean if provided
   *
   * Default Value:
   * - = false: Defaults to false if not provided
   *
   * Business Context:
   * - When true, service might return CSV format instead of JSON
   * - Used for export functionality in admin interfaces
   * - May change pagination behavior (e.g., return all records)
   *
   * Implementation Note:
   * - Default value ensures consistent behavior when parameter omitted
   */
  @ApiPropertyOptional()
  @IsOptional()
  @IsBoolean()
  is_csv?: boolean = false;

  /**
   * created_on - Date range filter for creation date
   *
   * Validation Rules:
   * - @IsOptional(): Optional parameter
   * - @ValidateNested(): Validates nested DateRangeDto object
   * - @Type(() => DateRangeDto): Enables proper class transformation
   *
   * Swagger Documentation:
   * - @ApiPropertyOptional({ type: DateRangeDto }): Shows nested structure
   *
   * Business Context:
   * - Filter menus created within a date range
   * - Supports "from" and "to" date boundaries
   * - Useful for reporting and audit queries
   *
   * Example Value:
   * - { from: "2024-01-01", to: "2024-12-31" }
   */
  @ApiPropertyOptional({ type: DateRangeDto })
  @IsOptional()
  @ValidateNested()
  @Type(() => DateRangeDto)
  created_on?: DateRangeDto;

  /**
   * updated_on - Date range filter for last modification date
   *
   * Validation Rules:
   * - @IsOptional(): Optional parameter
   * - @ValidateNested(): Validates nested DateRangeDto object
   * - @Type(() => DateRangeDto): Enables proper class transformation
   *
   * Business Context:
   * - Filter menus last modified within a date range
   * - Tracks recent changes and updates
   * - Useful for change management and activity reports
   *
   * Reusability:
   * - Uses same DateRangeDto as created_on for consistency
   */
  @ApiPropertyOptional({ type: DateRangeDto })
  @IsOptional()
  @ValidateNested()
  @Type(() => DateRangeDto)
  updated_on?: DateRangeDto;

  @ApiPropertyOptional({ type: [String] })
  @IsOptional()
  @IsArray()
  @IsString({ each: true })
  menu_groups?: string[];
}
