import {
  IsString,
  IsNotEmpty,
  IsNumber,
  IsBoolean,
  IsObject,
  IsArray,
  ValidateNested,
} from 'class-validator';
import { Type } from 'class-transformer';
import { ApiProperty, ApiPropertyOptional } from '@nestjs/swagger';
import { IColumnConfig } from 'src/utils/interfaces/config';

/**
 * Data Transfer Object (DTO) for saving or retrieving user-specific table settings.
 *
 * This DTO is used to manage personalized table configurations such as:
 * - Which columns are visible/hidden
 * - Column display order
 * - Pagination preferences
 * - Filter presets
 *
 * Settings are typically stored per user and per table type, allowing each user
 * to customize their view of data tables throughout the application.
 *
 * @example
 * // Saving table settings for user listing:
 * {
 *   "user_id": 123,
 *   "setting_type": "user_listing",
 *   "columns": [
 *     { "key": "name", "title": "Full Name", "is_checked": true },
 *     { "key": "email", "title": "Email Address", "is_checked": true },
 *     { "key": "phone", "title": "Phone Number", "is_checked": false }
 *   ],
 *   "is_affiliate": false
 * }
 *
 * @example
 * // For affiliate-specific view:
 * {
 *   "user_id": 456,
 *   "setting_type": "commission_report",
 *   "columns": [...],
 *   "is_affiliate": true
 * }
 */
export class TableSettingsDto {
  /**
   * ID of the user who owns these table settings.
   * Typically injected from session/auth token rather than client input.
   *
   * @type {number}
   * @required
   * @example 123
   *
   * @isNumber - Validation: Must be a number
   *   Error message: "user_id must be a number"
   *
   * @isNotEmpty - Validation: Cannot be null, undefined, or empty
   *   Error message: "user_id should not be empty"
   *
   * @security Note: In production, this should typically be derived from
   * the authenticated session rather than accepted from client input
   * to prevent users from modifying other users' settings.
   */
  @ApiProperty({
    description: 'ID of the user who owns these table settings',
    example: 123,
    type: Number,
  })
  @IsNotEmpty({ message: 'User ID is required' })
  @IsNumber({}, { message: 'User ID must be a number' })
  user_id: number;

  /**
   * Identifier for the type of table/view these settings apply to.
   * Used to differentiate settings for different tables in the application.
   *
   * @type {string}
   * @required
   * @example "user_listing"
   * @example "course_catalog"
   * @example "commission_report"
   *
   * @isString - Validation: Must be a string
   *   Error message: "setting_type must be a string"
   *
   * @isNotEmpty - Validation: Cannot be empty string
   *   Error message: "setting_type should not be empty"
   */
  @ApiProperty({
    description: 'Identifier for the table/view type',
    example: 'user_listing',
    type: String,
  })
  @IsNotEmpty({ message: 'Setting type is required' })
  @IsString({ message: 'Setting type must be a string' })
  setting_type: string;

  /**
   * Array of column configurations defining the table structure.
   * Each column configuration specifies display properties and visibility state.
   *
   * @type {IColumnConfig[]}
   * @required
   *
   * @isObject - Current validation (incorrect: should be @IsArray)
   * @isNotEmpty - Validation: Cannot be empty array
   *
   * @note There's a bug here: columns should be IColumnConfig[] not IColumnConfig
   * Current validation @IsObject is incorrect for an array
   */
  @ApiProperty({
    description: 'Array of column configurations',
    type: [Object],
    example: [
      { key: 'name', title: 'Full Name', is_checked: true },
      { key: 'email', title: 'Email', is_checked: true },
      { key: 'status', title: 'Status', is_checked: false },
    ],
  })
  @IsNotEmpty({ message: 'Columns configuration is required' })
  // @IsArray({ message: 'Columns must be an array' }) // Fixed: Should be @IsArray
  // @ValidateNested({ each: true }) // Validates each item in the array
  @Type(() => Object) // Enables class-transformer to handle nested validation
  columns: IColumnConfig[]; // Fixed: Should be array type

  /**
   * Flag indicating whether these settings are for an affiliate user.
   * Affiliates might see different columns or have different default settings.
   *
   * @type {boolean}
   * @required
   * @default false
   * @example false
   * @example true
   *
   * @isBoolean - Validation: Must be a boolean
   *   Error message: "is_affiliate must be a boolean"
   *
   * @isNotEmpty - Validation: Cannot be null or undefined
   *   Error message: "is_affiliate should not be empty"
   */
  @ApiProperty({
    description: 'Indicates if settings are for an affiliate user',
    example: false,
    type: Boolean,
    default: false,
  })
  @IsNotEmpty({ message: 'Affiliate flag is required' })
  @IsBoolean({ message: 'Affiliate flag must be a boolean' })
  is_affiliate: boolean = false;
}
