// Import Swagger decorators for API documentation
import { ApiProperty, ApiPropertyOptional } from '@nestjs/swagger';

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

// Import class-validator decorators for input validation
import {
  IsString,
  IsNotEmpty,
  IsOptional,
  IsArray,
  ValidateNested,
  IsInt,
} 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';

/**
 * UpdateMenuDto - Data Transfer Object for updating existing menu records
 *
 * This DTO defines the structure and validation rules for updating menu items.
 * It shares similarities with CreateMenuDto but includes update-specific fields
 * and different validation requirements.
 *
 * Key Differences from CreateMenuDto:
 * - ID field (optional in request, required in service)
 * - modified_by_user field for audit tracking
 * - All fields except ID are required for complete updates
 *
 * Design Pattern: Partial Update vs Full Update
 * - This appears to be a full update DTO (all fields required except optional ones)
 * - Could be enhanced with PartialType from @nestjs/mapped-types for partial updates
 *
 * Purpose:
 * - Used in PUT /menus endpoint for updating menu records
 * - Supports updating both menu data and associated actions
 * - Provides validation for all updatable fields
 */
export class UpdateMenuDto {
  /**
   * id - The unique identifier of the menu to update
   *
   * Validation Rules:
   * - @IsOptional(): Optional in DTO (service will validate)
   * - @IsInt(): Must be integer if provided
   *
   * Swagger Documentation:
   * - @ApiPropertyOptional({ example: 1 }): Shows as optional with example
   *
   * Business Context:
   * - Typically passed in request body for PUT operations
   * - Service will validate that ID is required and exists
   * - Alternative approach: Pass ID in URL path, exclude from DTO
   *
   * Implementation Note:
   * - Optional here but service will throw error if missing
   * - Could use @IsNotEmpty() if ID should be in DTO
   */
  @IsOptional()
  @IsInt()
  @ApiPropertyOptional({ example: 1 })
  id?: number;

  /**
   * menu_group_id - References the updated menu group
   *
   * Validation Rules:
   * - @IsNotEmpty(): Required field
   * - @IsNumberOrStringDto(0, 'Menu Group'): Custom validator with default
   *
   * Business Context:
   * - Allows moving menu to different menu group
   * - Must reference existing menu group
   * - Changing group may affect permissions/display hierarchy
   */
  @IsNotEmpty()
  @IsNumberOrStringDto(0, 'Menu Group')
  menu_group_id: number | string;

  /**
   * title - Updated display name of the menu item
   *
   * Validation Rules:
   * - @IsNotEmpty(): Required field
   * - @IsString(): Must be string type
   *
   * Swagger Documentation:
   * - @ApiProperty(): Required in Swagger
   *
   * Business Context:
   * - Changing title affects UI display and user experience
   * - Should maintain consistency across the application
   */
  @IsNotEmpty()
  @IsString({ message: 'Menu Title must be a string' })
  @ApiProperty()
  title: string;

  /**
   * controller - Updated backend controller/route identifier
   *
   * Validation Rules:
   * - @IsNotEmpty(): Required field
   * - @IsString(): Must be string type
   *
   * Business Context:
   * - Changing controller may break existing routes/permissions
   * - Should be validated for uniqueness within menu group
   * - May require updating related permissions and navigation
   */
  @IsNotEmpty()
  @IsString({ message: 'Controller must be a string' })
  @ApiProperty()
  controller: string;

  /**
   * order_no - Updated display order/sequence
   *
   * Validation Rules:
   * - @IsNotEmpty(): Required field
   * - @IsNumberOrStringDto(0, 'Order No'): Custom validator with default
   *
   * Business Context:
   * - Affects menu positioning in navigation
   * - Should be validated to avoid conflicts with other menus
   */
  @IsNotEmpty()
  @IsNumberOrStringDto(0, 'Order No')
  order_no: number | string;

  /**
   * is_visible - Updated visibility flag
   *
   * Validation Rules:
   * - @IsNotEmpty(): Required field
   * - @IsNumberOrStringDto(0, 'Is Visible'): Custom validator with default
   *
   * Business Context:
   * - Controls whether menu appears in navigation
   * - Useful for feature toggles or conditional access
   */
  @IsNotEmpty()
  @IsNumberOrStringDto(0, 'Is Visible')
  is_visible: number | string;

  /**
   * active - Updated status flag
   *
   * Validation Rules:
   * - @IsNotEmpty(): Required field
   * - @IsNumberOrStringDto(0, 'Status'): Custom validator with default
   *
   * Business Context:
   * - Different from is_visible (active vs visible)
   * - May control backend availability vs frontend display
   */
  @IsNotEmpty()
  @IsNumberOrStringDto(0, 'Status')
  active: number | string;

  /**
   * modified_by_user - User ID of the person making the update
   *
   * Validation Rules:
   * - @IsOptional(): Typically set by server, not client
   * - @IsInt(): Must be integer if provided
   *
   * Swagger Documentation:
   * - @ApiPropertyOptional({ example: 1 }): Optional with example
   *
   * Business Context:
   * - Usually populated by server from session/authentication
   * - Used for audit trails and change tracking
   * - Should not be client-controlled for security
   *
   * Implementation Note:
   * - Controller typically injects this from session data
   * - Service uses it to track who made changes
   */
  @IsOptional()
  @IsInt()
  @ApiPropertyOptional({ example: 1 })
  modified_by_user?: number;

  /**
   * actions - Updated 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:
   * - Complete replacement strategy (not partial update)
   * - Service will delete existing actions and create new ones
   * - Allows complete restructuring of menu permissions
   *
   * Implementation Consideration:
   * - Empty array means remove all actions
   * - Should be handled within transaction for consistency
   */
  @IsArray()
  @ValidateNested({ each: true })
  @Type(() => MenuActionDto)
  actions: MenuActionDto[];
}
