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

/**
 * DTO for overriding section properties when cloning from template to program
 */
export class ProgramSectionOverrideDto {
  @ApiProperty({ 
    description: 'Override section name', 
    example: 'Program-specific Section Name',
    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 visibility', 
    example: true,
    required: false 
  })
  @IsOptional()
  isVisible?: boolean;

  @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
 */
export class ProgramQuestionOverrideDto {
  @ApiProperty({ 
    description: 'Override question label/text', 
    example: 'Modified Question Label',
    required: false 
  })
  @IsOptional()
  @IsString()
  label?: string;

  @ApiProperty({ 
    description: 'Override placeholder text', 
    example: 'Enter your custom text here',
    required: false 
  })
  @IsOptional()
  @IsString()
  placeholder?: string;

  @ApiProperty({ 
    description: 'Override help text', 
    example: 'This helps users understand the question',
    required: false 
  })
  @IsOptional()
  @IsString()
  helpText?: string;


  @ApiProperty({ 
    description: 'Override visibility', 
    example: true,
    required: false 
  })
  @IsOptional()
  isVisible?: boolean;

  @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 conditional configuration',
    required: false,
    type: Object,
  })
  @IsOptional()
  @IsObject()
  conditionalConfig?: Record<string, any>;

  @ApiProperty({ 
    description: 'Override required status', 
    example: true,
    required: false 
  })
  @IsOptional()
  isRequired?: boolean;
}

/**
 * DTO for question input at program level - can clone from master, template, or create new
 * 
 * USAGE:
 * - Option 1: Clone from master question (provide masterQuestionId) - bypasses template level
 * - Option 2: Clone from template question (provide templateQuestionId)
 * - Option 3: Create new question (provide label + type)
 * 
 * IMPORTANT:
 * - Must specify EXACTLY ONE of the three options above
 * - For dropdown/radio/checkbox/multiselect types: optionConfig is REQUIRED
 * - override can be used with Option 1 or 2 to customize cloned questions
 * 
 * @example Clone from master with override
 * {
 *   "masterQuestionId": 100,
 *   "override": {
 *     "label": "Full Name (As per ID)",
 *     "config": { "isRequired": true, "maxCharacters": 100 }
 *   }
 * }
 * 
 * @example Clone from template
 * {
 *   "templateQuestionId": 200,
 *   "override": {
 *     "placeholder": "Enter your email address"
 *   }
 * }
 * 
 * @example Create new question
 * {
 *   "label": "Emergency Contact Phone",
 *   "type": "tel",
 *   "config": { "isRequired": true },
 *   "placeholder": "+91 XXXXX XXXXX",
 *   "displayOrder": 1
 * }
 * 
 * @example Create dropdown question
 * {
 *   "label": "Relationship",
 *   "type": "dropdown",
 *   "optionConfig": [
 *     { "value": "parent", "label": "Parent" },
 *     { "value": "spouse", "label": "Spouse" },
 *     { "value": "sibling", "label": "Sibling" }
 *   ]
 * }
 */
export class ProgramQuestionInputDto {
  // Option 1: Clone from master question (direct)
  @ApiProperty({ 
    description: 'Master question ID to clone from (can skip template level)', 
    example: 100,
    required: false 
  })
  @IsOptional()
  @IsInt()
  masterQuestionId?: number;

  // Option 2: Clone from template question
  @ApiProperty({ 
    description: 'Template question ID to clone from', 
    example: 200,
    required: false 
  })
  @IsOptional()
  @IsInt()
  templateQuestionId?: number;

  // Option 3: Reuse existing question (move to different section)
  @ApiProperty({ 
    description: 'Existing question ID to reuse/move to this section', 
    example: 2348,
    required: false 
  })
  @IsOptional()
  @IsInt()
  questionId?: number;

  // Option 4: Create new question
  @ApiProperty({ 
    description: 'Question label/text (required if creating new question)', 
    example: 'Program-specific question',
    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: 'Question configuration', 
    example: { isRequired: true, maxCharacters: 100 },
    required: false 
  })
  @IsOptional()
  @IsObject()
  config?: Record<string, any>;

  @ApiProperty({
    description: 'Question-level conditional configuration',
    required: false,
    type: Object,
  })
  @IsOptional()
  @IsObject()
  conditionalConfig?: Record<string, any>;

  @ApiProperty({ 
    description: 'Placeholder text', 
    example: 'Enter your text',
    required: false 
  })
  @IsOptional()
  @IsString()
  placeholder?: string;

  @ApiProperty({ 
    description: 'Help text', 
    example: 'This field is for...',
    required: false 
  })
  @IsOptional()
  @IsString()
  helpText?: string;

  @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: 'Overrides to apply when cloning', 
    type: ProgramQuestionOverrideDto,
    required: false 
  })
  @IsOptional()
  @ValidateNested()
  @Type(() => ProgramQuestionOverrideDto)
  override?: ProgramQuestionOverrideDto;
}

/**
 * DTO for section input at program level
 * 
 * USAGE:
 * - Option 1: Clone from template section (provide templateFormSectionId)
 * - Option 2: Use existing program section (provide formSectionId)
 * - Option 3: Create new section (provide sectionName + sectionKey)
 * 
 * IMPORTANT:
 * - Must specify EXACTLY ONE of the three options above
 * - Questions array is REQUIRED and must not be empty
 * 
 * SUBSECTIONS (parentSectionId):
 * - Any section can have unlimited subsections
 * - Nesting depth is controlled by MAX_SECTION_NESTING_DEPTH constant in constants.ts
 * - If MAX_SECTION_NESTING_DEPTH = null: unlimited nesting depth
 * - If MAX_SECTION_NESTING_DEPTH = number: restricted to that depth (e.g., 1 = parent->child only)
 * - Example: Section A -> Subsection B -> Subsection C -> ... (depth controlled by constant)
 * 
 * @example Clone from template section with override
 * {
 *   "templateFormSectionId": 20,
 *   "sectionOverride": {
 *     "sectionName": "Participant Information",
 *     "displayOrder": 1
 *   },
 *   "questions": [
 *     {
 *       "templateQuestionId": 50,
 *       "override": { "label": "Full Name" }
 *     }
 *   ]
 * }
 * 
 * @example Use existing program section
 * {
 *   "formSectionId": 30,
 *   "questions": [
 *     {
 *       "masterQuestionId": 100
 *     }
 *   ]
 * }
 * 
 * @example Create new custom section
 * {
 *   "sectionName": "Emergency Contact",
 *   "sectionKey": "EMERGENCY_CONTACT",
 *   "sectionDescription": "Please provide emergency contact details",
 *   "displayOrder": 2,
 *   "questions": [
 *     {
 *       "label": "Contact Name",
 *       "type": "text",
 *       "config": { "isRequired": true, "maxCharacters": 100 }
 *     },
 *     {
 *       "label": "Relationship",
 *       "type": "dropdown",
 *       "optionConfig": [
 *         { "value": "parent", "label": "Parent" },
 *         { "value": "spouse", "label": "Spouse" }
 *       ]
 *     }
 *   ]
 * }
 * 
 * @example Create nested subsection
 * {
 *   "sectionName": "Arrival Information",
 *   "sectionKey": "ARRIVAL_INFO",
 *   "parentSectionId": 25,
 *   "displayOrder": 1,
 *   "questions": [
 *     {
 *       "label": "Arrival Date",
 *       "type": "date",
 *       "config": { "isRequired": true }
 *     }
 *   ]
 * }
 */
export class ProgramSectionInputDto {
  // Option 1: Clone from template section
  @ApiProperty({ 
    description: 'Template form section ID to clone from', 
    example: 20,
    required: false 
  })
  @IsOptional()
  @IsInt()
  templateFormSectionId?: number;

  // Option 2: Use existing program section
  @ApiProperty({ 
    description: 'Existing HDB form section ID to use', 
    example: 30,
    required: false 
  })
  @IsOptional()
  @IsInt()
  formSectionId?: number;

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

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

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

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

  @ApiProperty({ 
    description: 'Parent section ID to create subsection (nesting depth configured by MAX_SECTION_NESTING_DEPTH constant)', 
    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: ProgramSectionOverrideDto,
    required: false 
  })
  @IsOptional()
  @ValidateNested()
  @Type(() => ProgramSectionOverrideDto)
  sectionOverride?: ProgramSectionOverrideDto;

  @ApiProperty({ 
    description: 'Questions to include in this section (REQUIRED)', 
    type: [ProgramQuestionInputDto],
    isArray: true,
    example: [
      {
        masterQuestionId: 100,
        override: {
          label: 'Full Name',
          config: { isRequired: true }
        }
      },
      {
        label: 'Email Address',
        type: 'email',
        config: { isRequired: true },
        placeholder: 'your@email.com'
      }
    ]
  })
  @IsArray()
  @IsNotEmpty()
  @ValidateNested({ each: true })
  @Type(() => ProgramQuestionInputDto)
  questions: ProgramQuestionInputDto[];

  @ApiProperty({
    description: 'Inline nested sub-sections within this section. Sub-sections are automatically assigned this section as their parent.',
    type: () => [ProgramSectionInputDto],
    isArray: true,
    required: false,
    example: [
      {
        sectionName: 'Arrival Details',
        sectionKey: 'ARRIVAL_DETAILS',
        displayOrder: 1,
        questions: [
          { masterQuestionId: 21 }
        ],
        subSections: [
          {
            sectionName: 'Flight Details',
            sectionKey: 'FLIGHT_DETAILS',
            displayOrder: 1,
            questions: [
              { masterQuestionId: 22 }
            ]
          }
        ]
      }
    ]
  })
  @IsOptional()
  @IsArray()
  @ValidateNested({ each: true })
  @Type(() => ProgramSectionInputDto)
  subSections?: ProgramSectionInputDto[];
}

/**
 * Main DTO for program form builder API (Template/Master → Program)
 * 
 * This unified endpoint supports:
 * - **NEW: Direct template cloning** - Clone all sections/questions from a template at once
 * - Cloning sections from templates with optional overrides
 * - Using existing program sections
 * - Creating brand new custom sections
 * - Cloning questions from master (bypasses template level)
 * - Cloning questions from template with optional overrides
 * - Creating brand new custom questions
 * - Creating nested subsections (depth controlled by MAX_SECTION_NESTING_DEPTH constant)
 * - Mixing cloned and custom content in same request
 * 
 * DIRECT TEMPLATE CLONING:
 * - Provide programTemplateId and set cloneFromTemplate: true
 * - This will automatically clone ALL sections and questions from the template
 * - Optional: sections array can be empty when using direct template cloning
 * - If both template cloning and sections array are provided, both will be processed
 * 
 * VALIDATIONS:
 * - programId must exist
 * - createdBy user must exist
 * - If cloneFromTemplate: true, programTemplateId must be provided
 * - Each section must specify exactly one source (template/existing/new)
 * - Each section must have at least one question
 * - Each question must specify exactly one source (master/template/new)
 * - Questions requiring options (dropdown/radio/checkbox/multiselect) must include optionConfig
 * - Parent section must exist (if creating nested section)
 * - Nesting depth validated against MAX_SECTION_NESTING_DEPTH (null = unlimited)
 */
export class ProgramFormBuilderDto {
  @ApiProperty({ 
    description: 'Program ID to build form for', 
    example: 101 
  })
  @IsInt()
  @IsNotEmpty()
  programId: number;

  @ApiProperty({ 
    description: 'Program template ID to clone all sections and questions from (use with cloneFromTemplate: true)', 
    example: 3,
    required: false 
  })
  @IsOptional()
  @IsInt()
  programTemplateId?: number;

  @ApiProperty({ 
    description: 'Enable direct cloning from template (clones all sections and questions from programTemplateId)', 
    example: true,
    required: false,
    default: false
  })
  @IsOptional()
  @IsBoolean()
  cloneFromTemplate?: boolean;

  @ApiProperty({ 
    description: 'Sections to create/clone (optional if using direct template cloning, otherwise REQUIRED)', 
    type: [ProgramSectionInputDto],
    isArray: true,
    example: [
      {
        templateFormSectionId: 20,
        sectionOverride: {
          sectionName: 'Participant Information',
          displayOrder: 1
        },
        questions: [
          {
            templateQuestionId: 50,
            override: {
              label: 'Full Name',
              config: { isRequired: true }
            }
          }
        ]
      },
      {
        sectionName: 'Emergency Contact',
        sectionKey: 'EMERGENCY_CONTACT',
        displayOrder: 2,
        questions: [
          {
            label: 'Contact Name',
            type: 'text',
            config: { isRequired: true, maxCharacters: 100 }
          },
          {
            masterQuestionId: 100,
            override: {
              label: 'Contact Phone Number'
            }
          }
        ]
      }
    ]
  })
  @IsOptional()
  @IsArray()
  @ValidateNested({ each: true })
  @Type(() => ProgramSectionInputDto)
  sections?: ProgramSectionInputDto[];
}

/**
 * Response DTO for program form builder
 */
export class ProgramFormBuilderResponseDto {
  @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',
    example: {
      programFormSections: [
        {
          id: 41,
          name: 'Participant Information',
          key: 'PARTICIPANT_INFO',
          displayOrder: 1,
          programId: 101,
          createdAt: '2026-03-18T10:30:00Z'
        },
        {
          id: 42,
          name: 'Emergency Contact',
          key: 'EMERGENCY_CONTACT',
          displayOrder: 2,
          programId: 101,
          createdAt: '2026-03-18T10:30:00Z'
        }
      ],
      totalSectionsCreated: 2,
      totalQuestionsCreated: 6
    }
  })
  data: {
    programFormSections: any[];
    totalSectionsCreated: number;
    totalQuestionsCreated: number;
  };
}
