import { UntypedFormGroup, ValidationErrors, ValidatorFn, Validators } from '@angular/forms';

/**
 * Angular form validator that requires a gender to be selected when a last name is provided.
 * This validator is specifically designed for B2B forms where gender becomes mandatory
 * only when personal information is entered.
 *
 * The validator looks for two specific form controls:
 * - 'gender': The control that becomes required
 * - 'lastName': The control that triggers the requirement
 *
 * @param control - The form group containing both 'gender' and 'lastName' controls
 * @returns Validation errors if gender is missing when lastName is set, null otherwise
 *
 * @example
 * ```typescript
 * const form = new FormGroup({
 *   gender: new FormControl(''),
 *   lastName: new FormControl(''),
 * }, {
 *   validators: [requireGenderWhenNameIsSet]
 * });
 * ```
 */
export function requireGenderWhenNameIsSet(control: UntypedFormGroup): ValidationErrors | null {
  const genderControl = control.get('gender');
  const nameControl = control.get('lastName');

  genderControl?.setErrors(null);

  if (nameControl && !Validators.required(nameControl)) {
    const errors = Validators.min(1)(genderControl) ? { required: true } : null;

    if (errors) {
      genderControl.setErrors(errors);
    }
    return errors;
  }
  return null;
}

/**
 * Angular form validator that implements mutual exclusivity between organisation name and personal details.
 * Either:
 * 1. Organisation name must be provided (company case), OR
 * 2. Both first name and last name must be provided (individual case)
 *
 * @param control - The form group containing 'firstName', 'lastName', and nested 'organisation.name' controls
 * @returns Validation errors if the mutual exclusivity rule is violated, null otherwise
 */
export function validateCompanyOrPersonalInfoRequired(
  control: UntypedFormGroup,
): ValidationErrors | null {
  const firstNameControl = control.get('firstName');
  const lastNameControl = control.get('lastName');
  const organisationControl = control.get('organisation');

  // Safely access the nested company name, with null checks
  const companyNameControl = organisationControl?.get('name') ?? organisationControl;

  if (!firstNameControl || !lastNameControl || !companyNameControl) {
    // If any control is missing, we can't validate
    return null;
  }

  const hasCompanyName = !!companyNameControl.value;
  const hasFirstName = !!firstNameControl.value;
  const hasLastName = !!lastNameControl.value;
  const hasPersonalInfo = hasFirstName || hasLastName;

  // Clear previous validation errors
  firstNameControl.setErrors(null);
  lastNameControl.setErrors(null);
  companyNameControl.setErrors(null);

  // Case 1: Neither company name nor personal info provided - require one of them
  if (!hasCompanyName && !hasPersonalInfo) {
    const errors = { required: true };
    companyNameControl.setErrors(errors);
    firstNameControl.setErrors(errors);
    lastNameControl.setErrors(errors);
    return { eitherCompanyOrPersonalRequired: true };
  }

  // Case 2: First name provided but last name missing
  if (hasFirstName && !hasLastName) {
    lastNameControl.setErrors({ required: true });
    return { lastNameRequired: true };
  }

  // Case 3: Last name provided but first name missing
  if (!hasFirstName && hasLastName) {
    firstNameControl.setErrors({ required: true });
    return { firstNameRequired: true };
  }

  // Valid: Either company name or complete personal info is provided
  return null;
}
