import { ApiProperty, ApiPropertyOptional } from '@nestjs/swagger';
import {
  IsString,
  IsNotEmpty,
  IsNumber,
  IsOptional,
  Min,
  Max,
} from 'class-validator';

/**
 * Create Menu Actions Data Transfer Object (DTO)
 *
 * This DTO is used for creating new menu action entries in the application.
 * Menu actions represent individual operations or permissions that can be performed
 * within menu items (e.g., "create", "read", "update", "delete", "export").
 *
 * Menu actions are typically associated with:
 * - Specific controllers or API endpoints
 * - UI buttons or interaction elements
 * - Role-based permission systems
 *
 * @example
 * // Creating a new menu action for user creation:
 * {
 *   "name": "create_user",
 *   "order_no": 1,
 *   "active": 1,
 *   "is_visible": 1,
 *   "platform": 2,
 *   "by_user": 123
 * }
 *
 * @example
 * // Creating a hidden administrative action:
 * {
 *   "name": "purge_records",
 *   "order_no": 99,
 *   "active": 1,
 *   "is_visible": 0, // Hidden from UI
 *   "platform": 2,
 *   "by_user": 456
 * }
 */
export class CreateMenuActionsDto {
  /**
   * Unique identifier/name for the menu action.
   * Typically uses snake_case and should be descriptive of the action.
   *
   * @type {string}
   * @required
   * @example "create_user"
   * @example "export_reports"
   * @example "delete_records"
   *
   * @isString - Validation: Must be a string
   *   Error message: "name must be a string"
   *
   * @isNotEmpty - Validation: Cannot be empty string
   *   Error message: "name should not be empty"
   *
   * @apiProperty - Swagger documentation
   *
   * @note Consider adding pattern validation:
   *   @Matches(/^[a-z_]+$/, { message: 'Name must be lowercase with underscores' })
   */
  @ApiProperty({
    description: 'Unique identifier/name for the menu action (snake_case)',
    example: 'create_user',
    type: String,
  })
  @IsNotEmpty({ message: 'Action name is required' })
  @IsString({ message: 'Action name must be a string' })
  name: string;

  /**
   * Display order of the menu action within its parent menu.
   * Determines the sequence in which actions appear in the UI.
   *
   * @type {number}
   * @required
   * @default 0
   * @example 1 (first position)
   * @example 5 (fifth position)
   *
   * @isNumber - Validation: Must be a number
   *   Error message: "order must be a number"
   *
   * @isNotEmpty - Validation: Cannot be null or undefined
   *   Error message: "order_no should not be empty"
   *
   * @note Consider adding range validation:
   *   @Min(0, { message: 'Order cannot be negative' })
   *   @Max(999, { message: 'Order cannot exceed 999' })
   */
  @ApiProperty({
    description:
      'Display order within parent menu (lower numbers appear first)',
    example: 1,
    type: Number,
    default: 0,
    minimum: 0,
    maximum: 999,
  })
  @IsNotEmpty({ message: 'Display order is required' })
  @IsNumber({}, { message: 'Display order must be a number' })
  @Min(0, { message: 'Display order cannot be negative' })
  @Max(999, { message: 'Display order cannot exceed 999' })
  order_no: number;

  /**
   * Activation status of the menu action.
   * Determines whether the action is available in the system.
   *
   * @type {number}
   * @required
   * @default 0
   * @example 1 (active/available)
   * @example 0 (inactive/unavailable)
   *
   * @isNumber - Validation: Must be a number
   *   Error message: "active must be a number"
   *
   * @isNotEmpty - Validation: Cannot be null or undefined
   *   Error message: "active should not be empty"
   *
   * @note Consider using boolean or enum for better semantics:
   *   active: boolean;
   *   or
   *   @IsIn([0, 1], { message: 'Active must be either 0 or 1' })
   */
  @ApiProperty({
    description: 'Activation status (1 = active, 0 = inactive)',
    example: 1,
    type: Number,
    default: 0,
    enum: [0, 1],
  })
  @IsNotEmpty({ message: 'Active status is required' })
  @IsNumber({}, { message: 'Active status must be a number' })
  active: number;

  /**
   * Visibility flag for the menu action in the UI.
   * Controls whether the action is shown to users in menus/interfaces.
   *
   * @type {number}
   * @required
   * @default 0
   * @example 1 (visible in UI)
   * @example 0 (hidden from UI)
   *
   * @isNumber - Validation: Must be a number
   *   Error message: "Is Visible must be a number"
   *
   * @isNotEmpty - Validation: Cannot be null or undefined
   *   Error message: "is_visible should not be empty"
   *
   * @note This allows for hidden actions that can still be accessed
   * programmatically or through direct API calls.
   */
  @ApiProperty({
    description: 'UI visibility flag (1 = visible, 0 = hidden)',
    example: 1,
    type: Number,
    default: 0,
    enum: [0, 1],
  })
  @IsNotEmpty({ message: 'Visibility flag is required' })
  @IsNumber({}, { message: 'Visibility flag must be a number' })
  is_visible: number;

  /**
   * Platform identifier for the menu action.
   * Used to differentiate actions across different platforms (web, mobile, etc.).
   *
   * @type {number}
   * @required
   * @default 1
   * @example 1 (web platform)
   * @example 2 (mobile platform)
   * @example 3 (admin platform)
   *
   * @isNumber - Validation: Must be a number
   *   Error message: "Platform must be a number"
   *
   * @isNotEmpty - Validation: Cannot be null or undefined
   *   Error message: "platform should not be empty"
   *
   * @note Consider using an enum for platform types:
   *   enum Platform { WEB = 1, MOBILE = 2, ADMIN = 3 }
   *   platform: Platform;
   */
  @ApiProperty({
    description: 'Platform identifier (1=web, 2=mobile, 3=admin, etc.)',
    example: 2,
    type: Number,
    default: 1,
  })
  @IsNotEmpty({ message: 'Platform identifier is required' })
  @IsNumber({}, { message: 'Platform identifier must be a number' })
  platform: number;

  /**
   * User ID of the person creating the menu action.
   * Used for audit trail to track who created the action.
   *
   * @type {number}
   * @required
   * @example 123
   *
   * @isNumber - Validation: Must be a number
   *   Error message: "by_user must be a number"
   *
   * @note In practice, this should typically come from the authenticated
   * user's session rather than client input, for security reasons.
   * Consider making this field optional and populating it server-side.
   */
  @ApiProperty({
    description: 'ID of the user creating the menu action (for audit trail)',
    example: 123,
    type: Number,
  })
  @IsNumber({}, { message: 'Creator user ID must be a number' })
  by_user: number;
}
