import { ApiProperty } from '@nestjs/swagger';
import { 
  IsInt, 
  IsNotEmpty, 
  IsOptional, 
  IsArray, 
  IsString, 
  IsObject, 
  ValidateNested,
  IsEnum
} from 'class-validator';
import { Type } from 'class-transformer';
import { QuestionType } from 'src/common/enum/question-type.enum';
import { AnswerType } from 'src/common/enum/answer-type.enum';

/**
 * DTO for overriding section properties when cloning from template
 */
export class SectionOverrideForProgramDto {
  @ApiProperty({ 
    description: 'Override section name', 
    example: 'Personal Information (HDB MSD 2025)',
    required: false 
  })
  @IsOptional()
  @IsString()
  sectionName?: string;

  @ApiProperty({ 
    description: 'Override section description', 
    example: 'Modified description for this program',
    required: false 
  })
  @IsOptional()
  @IsString()
  sectionDescription?: string;

  @ApiProperty({ 
    description: 'Override display order', 
    example: 5,
    required: false 
  })
  @IsOptional()
  @IsInt()
  displayOrder?: number;

  @ApiProperty({ 
    description: 'Override conditional configuration', 
    example: { showIf: { questionId: 5, value: 'yes' } },
    required: false 
  })
  @IsOptional()
  @IsObject()
  conditionalConfig?: Record<string, any>;
}

/**
 * DTO for overriding question properties when cloning from template
 */
export class QuestionOverrideForProgramDto {
  @ApiProperty({ 
    description: 'Override question label/text', 
    example: 'What is your full name?',
    required: false 
  })
  @IsOptional()
  @IsString()
  label?: string;

  @ApiProperty({ 
    description: 'Override question configuration (validation rules, etc.)', 
    example: { isRequired: true, minCharacter: 5, maxCharacters: 100 },
    required: false 
  })
  @IsOptional()
  @IsObject()
  config?: Record<string, any>;

  @ApiProperty({ 
    description: 'Override display order', 
    example: 3,
    required: false 
  })
  @IsOptional()
  @IsInt()
  displayOrder?: number;
}

/**
 * DTO for question input - can be clone from template or create new
 * 
 * USAGE:
 * - Option 1: Clone from template question (provide templateQuestionId)
 * - Option 2: Create new question (provide label + type + answerType)
 * 
 * IMPORTANT:
 * - Must specify EXACTLY ONE of the two options above
 * - For dropdown/radio/checkbox/multiselect types: optionConfig is REQUIRED
 * - override can be used with Option 1 to customize cloned questions
 * 
 * @example Clone from template with override
 * {
 *   "templateQuestionId": 100,
 *   "override": {
 *     "label": "Full Name (As per ID)",
 *     "config": { "isRequired": true, "maxCharacters": 100 }
 *   }
 * }
 * 
 * @example Create new question
 * {
 *   "label": "Emergency Contact Phone",
 *   "type": "tel",
 *   "answerType": "string",
 *   "config": { "isRequired": true },
 *   "displayOrder": 1
 * }
 */
export class QuestionInputForProgramDto {
  // Option 1: Clone from template question
  @ApiProperty({ 
    description: 'Template question ID to clone from (mutually exclusive with label+type)', 
    example: 100,
    required: false 
  })
  @IsOptional()
  @IsInt()
  templateQuestionId?: number;

  // Option 2: Create new question
  @ApiProperty({ 
    description: 'Question label/text (required if creating new question)', 
    example: 'What is your email address?',
    required: false 
  })
  @IsOptional()
  @IsString()
  label?: string;

  @ApiProperty({ 
    description: 'Question type (required if creating new question)', 
    example: 'text',
    enum: QuestionType,
    required: false 
  })
  @IsOptional()
  @IsEnum(QuestionType)
  type?: QuestionType;

  @ApiProperty({ 
    description: 'Answer type (required if creating new question)', 
    example: 'string',
    enum: AnswerType,
    required: false 
  })
  @IsOptional()
  @IsEnum(AnswerType)
  answerType?: AnswerType;

  @ApiProperty({ 
    description: 'Question configuration', 
    example: { isRequired: true, maxCharacters: 100 },
    required: false 
  })
  @IsOptional()
  @IsObject()
  config?: Record<string, any>;

  @ApiProperty({ 
    description: 'Display order within section', 
    example: 1,
    required: false 
  })
  @IsOptional()
  @IsInt()
  displayOrder?: number;

  @ApiProperty({ 
    description: 'Option configuration for dropdown/radio/checkbox questions', 
    example: [{ value: 'yes', label: 'Yes' }, { value: 'no', label: 'No' }],
    required: false 
  })
  @IsOptional()
  @IsArray()
  optionConfig?: Record<string, any>[];

  @ApiProperty({ 
    description: 'Binding key for data mapping', 
    example: 'participant_name',
    required: false 
  })
  @IsOptional()
  @IsString()
  bindingKey?: string;

  @ApiProperty({ 
    description: 'Overrides to apply when cloning from template', 
    type: QuestionOverrideForProgramDto,
    required: false 
  })
  @IsOptional()
  @ValidateNested()
  @Type(() => QuestionOverrideForProgramDto)
  override?: QuestionOverrideForProgramDto;
}

/**
 * DTO for section input - can be clone from template or create new
 * 
 * USAGE:
 * - Option 1: Clone from template section (provide templateFormSectionId)
 * - Option 2: Create new section (provide sectionName + sectionKey)
 * - Option 3: Reference existing program section (provide programFormSectionId)
 * 
 * IMPORTANT:
 * - Must specify EXACTLY ONE of the three options above
 * - Questions array is REQUIRED for new/cloned sections, OPTIONAL for existing sections
 * 
 * SUBSECTIONS:
 * - Any section can have unlimited subsections
 * - Nesting depth is controlled by MAX_SECTION_NESTING_DEPTH constant
 * 
 * @example Clone from template section with override
 * {
 *   "templateFormSectionId": 10,
 *   "sectionOverride": {
 *     "sectionName": "Personal Details (HDB MSD 2025)",
 *     "displayOrder": 1
 *   },
 *   "questions": [
 *     {
 *       "templateQuestionId": 100,
 *       "override": { "label": "Full Name" }
 *     }
 *   ]
 * }
 * 
 * @example Create new custom section
 * {
 *   "sectionName": "Emergency Contact",
 *   "sectionKey": "EMERGENCY_CONTACT_HDB2025",
 *   "sectionDescription": "Please provide emergency contact details",
 *   "displayOrder": 2,
 *   "questions": [
 *     {
 *       "label": "Contact Name",
 *       "type": "text",
 *       "answerType": "string",
 *       "config": { "isRequired": true, "maxCharacters": 100 }
 *     }
 *   ]
 * }
 */
export class SectionInputForProgramDto {
  // Option 1: Clone from template section
  @ApiProperty({ 
    description: 'Template form section ID to clone from', 
    example: 10,
    required: false 
  })
  @IsOptional()
  @IsInt()
  templateFormSectionId?: number;

  // Option 2: Create new section
  @ApiProperty({ 
    description: 'Section name (required if creating new section)', 
    example: 'Personal Information',
    required: false 
  })
  @IsOptional()
  @IsString()
  sectionName?: string;

  @ApiProperty({ 
    description: 'Section key (required if creating new section)', 
    example: 'PERSONAL_INFO',
    required: false 
  })
  @IsOptional()
  @IsString()
  sectionKey?: string;

  // Option 3: Reference existing program section
  @ApiProperty({ 
    description: 'Existing program form section ID (use to add subsections or reference as subsection)', 
    example: 33,
    required: false 
  })
  @IsOptional()
  @IsInt()
  programFormSectionId?: number;

  @ApiProperty({ 
    description: 'Section description', 
    example: 'Please provide your personal details',
    required: false 
  })
  @IsOptional()
  @IsString()
  sectionDescription?: string;

  @ApiProperty({ 
    description: 'Display order', 
    example: 1,
    required: false 
  })
  @IsOptional()
  @IsInt()
  displayOrder?: number;

  @ApiProperty({ 
    description: 'Parent section ID for nested sections', 
    example: 5,
    required: false 
  })
  @IsOptional()
  @IsInt()
  parentSectionId?: number;

  @ApiProperty({ 
    description: 'Conditional configuration', 
    example: { showIf: { questionId: 10, value: 'yes' } },
    required: false 
  })
  @IsOptional()
  @IsObject()
  conditionalConfig?: Record<string, any>;

  @ApiProperty({ 
    description: 'Section override properties when cloning from template', 
    type: SectionOverrideForProgramDto,
    required: false 
  })
  @IsOptional()
  @ValidateNested()
  @Type(() => SectionOverrideForProgramDto)
  sectionOverride?: SectionOverrideForProgramDto;

  @ApiProperty({ 
    description: 'Questions to include in this section (REQUIRED for new/cloned sections, OPTIONAL for existing sections)', 
    type: [QuestionInputForProgramDto],
    isArray: true,
    required: false
  })
  @IsOptional()
  @IsArray()
  @ValidateNested({ each: true })
  @Type(() => QuestionInputForProgramDto)
  questions?: QuestionInputForProgramDto[];

  @ApiProperty({ 
    description: 'Nested subsections (optional) - allows creating hierarchical section structures', 
    type: [SectionInputForProgramDto],
    isArray: true,
    required: false
  })
  @IsOptional()
  @IsArray()
  @ValidateNested({ each: true })
  @Type(() => SectionInputForProgramDto)
  subsections?: SectionInputForProgramDto[];
}

/**
 * Main DTO for program form builder API (Template → Program)
 * 
 * @example
 * {
 *   "programId": 123,
 *   "sections": [
 *     {
 *       "templateFormSectionId": 10,
 *       "sectionOverride": {
 *         "sectionName": "Personal Information (HDB MSD 2025)",
 *         "displayOrder": 1
 *       },
 *       "questions": [
 *         {
 *           "templateQuestionId": 100,
 *           "override": {
 *             "label": "Full Name",
 *             "config": { "isRequired": true }
 *           }
 *         }
 *       ]
 *     },
 *     {
 *       "sectionName": "Emergency Contact",
 *       "sectionKey": "EMERGENCY_CONTACT",
 *       "displayOrder": 2,
 *       "questions": [
 *         {
 *           "label": "Contact Name",
 *           "type": "text",
 *           "answerType": "string",
 *           "config": { "isRequired": true, "maxCharacters": 100 }
 *         }
 *       ]
 *     }
 *   ],
 *   "createdBy": 1
 * }
 */
export class FormSectionProgramFormBuilderDto {
  @ApiProperty({ 
    description: 'Program ID to build form for (can be provided in request body or route parameter)', 
    example: 123,
    required: false
  })
  @IsOptional()
  @IsInt()
  programId?: number;

  @ApiProperty({ 
    description: 'Sections to create/clone (REQUIRED)', 
    type: [SectionInputForProgramDto],
    isArray: true,
    example: [
      {
        templateFormSectionId: 10,
        sectionOverride: {
          sectionName: 'Personal Details (HDB 2025)',
          displayOrder: 1
        },
        questions: [
          {
            templateQuestionId: 100,
            override: {
              label: 'Full Name',
              config: { isRequired: true }
            }
          }
        ]
      }
    ]
  })
  @IsArray()
  @IsNotEmpty()
  @ValidateNested({ each: true })
  @Type(() => SectionInputForProgramDto)
  sections: SectionInputForProgramDto[];

  @ApiProperty({
    description: 'User ID performing the operation',
    example: 1
  })
  @IsInt()
  @IsNotEmpty()
  createdBy: number;
}

/**
 * Response DTO for program form builder
 */
export class FormSectionProgramFormBuilderResponseDto {
  @ApiProperty({ 
    description: 'Success status',
    example: true
  })
  success: boolean;

  @ApiProperty({ 
    description: 'Response message',
    example: 'Program form built successfully'
  })
  message: string;

  @ApiProperty({ 
    description: 'Created program form sections with questions'
  })
  data: {
    programFormSections: any[];
    totalSectionsCreated: number;
    totalQuestionsCreated: number;
  };
}
