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

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

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

// Import nested DTO for menu actions
import { MenuActionDto } from './menu-action.dto';

// Import custom validator for flexible number/string validation
import { IsNumberOrStringDto } from 'src/utils/common/numberOrStringDto';

/**
 * CreateMenuDto - Data Transfer Object for creating new menus
 *
 * This DTO defines the structure and validation rules for creating menu entries.
 * It serves multiple purposes:
 * 1. Request validation using class-validator decorators
 * 2. Type safety for TypeScript
 * 3. Swagger API documentation generation
 * 4. Transformation from request body to proper types
 *
 * Key Features:
 * - Validates all required fields
 * - Supports nested actions array
 * - Flexible type handling (number or string for numeric fields)
 * - Provides default values for optional fields
 */
export class CreateMenuDto {
  /**
   * menu_group_id - References the menu group this menu belongs to
   *
   * Validation Rules:
   * - @IsNotEmpty(): Cannot be empty or null
   * - @IsNumberString(): Must be a string representation of a number
   *
   * Business Context:
   * - Links menu to a specific menu group (category/container)
   * - Ensures hierarchical organization of menus
   *
   * @ApiProperty(): Includes this field in Swagger documentation
   */
  @IsNotEmpty()
  @IsNumberString({}, { message: 'Menu Group must be a number or string' })
  @ApiProperty()
  menu_group_id: string;

  /**
   * title - Display name of the menu item
   *
   * Validation Rules:
   * - @IsNotEmpty(): Required field
   * - @IsString(): Must be a string type
   *
   * Business Context:
   * - User-facing name shown in navigation/menu systems
   * - Should be descriptive and user-friendly
   */
  @IsNotEmpty()
  @IsString({ message: 'Menu Title must be a string' })
  @ApiProperty()
  title: string;

  /**
   * controller - Backend controller/route identifier
   *
   * Validation Rules:
   * - @IsNotEmpty(): Required field
   * - @IsString(): Must be a string type
   *
   * Business Context:
   * - Typically maps to a backend controller or route path
   * - Used for routing and permission checking
   * - Should be unique within a menu group
   * - Often follows naming conventions (e.g., 'UserController', '/users')
   */
  @IsNotEmpty()
  @IsString({ message: 'Controller must be a string' })
  @ApiProperty()
  controller: string;

  /**
   * order_no - Display order/sequence in menu lists
   *
   * Validation Rules:
   * - @IsNotEmpty(): Required field
   * - @IsNumberString(): Accepts string or number input
   *
   * Business Context:
   * - Determines sort order in menu displays
   * - Lower numbers typically appear first
   * - @ApiProperty({ default: 0 }): Sets Swagger default value
   */
  @IsNotEmpty()
  @IsNumberString({}, { message: 'Order No must be a number or string' })
  @ApiProperty({ default: 0 })
  order_no: number | string;

  /**
   * is_visible - Controls menu visibility in UI
   *
   * Validation Rules:
   * - @IsNotEmpty(): Required field
   * - @IsNumberString(): Accepts string or number input
   *
   * Business Context:
   * - Typically a boolean flag (0 = hidden, 1 = visible)
   * - Allows hiding menus without deleting them
   * - Useful for feature toggles or role-based visibility
   * - @ApiProperty({ default: 0 }): Defaults to hidden/0
   */
  @IsNotEmpty()
  @IsNumberString({}, { message: 'Is Visible must be a number or string' })
  @ApiProperty({ default: 0 })
  is_visible: number | string;

  /**
   * active - Status flag for menu activation
   *
   * Validation Rules:
   * - @IsNotEmpty(): Required field
   * - @IsNumberOrStringDto(1, 'Status'): Custom validator with default value
   *
   * Business Context:
   * - Controls whether menu is active/inactive
   * - Different from is_visible (active might mean "available for use")
   * - Custom validator ensures proper type and provides default
   * - @ApiProperty({ default: 0 }): Defaults to inactive/0
   */
  @IsNotEmpty()
  @IsNumberOrStringDto(1, 'Status')
  @ApiProperty({ default: 0 })
  active: number | string;

  /**
   * actions - Array of menu actions/permissions
   *
   * Validation Rules:
   * - @IsArray(): Must be an array
   * - @ValidateNested({ each: true }): Validates each array item
   * - @Type(() => MenuActionDto): Enables proper transformation
   *
   * Business Context:
   * - Defines operations/actions available for this menu
   * - Examples: 'view', 'create', 'edit', 'delete'
   * - Each action can have its own permissions
   * - Optional field (can be empty array)
   *
   * Nested DTO Pattern:
   * - MenuActionDto defines structure for individual actions
   * - Allows complex nested validation
   */
  @IsArray()
  @ValidateNested({ each: true })
  @Type(() => MenuActionDto)
  actions: MenuActionDto[];
}
