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

export function organisationB2bDeliveryValidator(): ValidatorFn | null {
  return (control: FormGroup): ValidationErrors | null => {
    let gender: AbstractControl;
    let firstName: AbstractControl;
    let lastName: AbstractControl;
    let organisation: AbstractControl;
    let isOrganisationSet: boolean;
    let isNameSet: boolean;

    // For Customer Create Form with Different Shipping Address
    if (control.get('differentShippingAddress') !== null) {
      gender = control.get('shippingAddress').get('gender');
      firstName = control.get('shippingAddress').get('firstName');
      lastName = control.get('shippingAddress').get('lastName');
      organisation = control.get('shippingAddress').get('organisation').get('name');
      isOrganisationSet = !!organisation.value;
      isNameSet = gender.value !== 0 && !!firstName.value && !!lastName.value;

      if (control.get('differentShippingAddress').value === true) {
        return validate(gender, firstName, lastName, organisation, isOrganisationSet, isNameSet);
      }
    } else {
      // Customer Shipping Create or Shipping Edit Forms
      gender = control.get('gender');
      firstName = control.get('firstName');
      lastName = control.get('lastName');
      organisation = control.get('organisation').get('name');
      isOrganisationSet = !!organisation.value;
      isNameSet = gender.value !== 0 && !!firstName.value && !!lastName.value;
      return validate(gender, firstName, lastName, organisation, isOrganisationSet, isNameSet);
    }
  };
}

function setNameValidation(gender: AbstractControl, firstName: AbstractControl, lastName: AbstractControl) {
  gender.setValidators([Validators.required, Validators.min(1)]);
  firstName.setValidators([Validators.required]);
  lastName.setValidators([Validators.required]);
}

function resetNameValidation(gender: AbstractControl, firstName: AbstractControl, lastName: AbstractControl) {
  gender.setValidators(null);
  firstName.setValidators(null);
  lastName.setValidators(null);
  gender.setErrors(null);
  firstName.setErrors(null);
  lastName.setErrors(null);
}

function setOrganisationValidation(organisation: AbstractControl) {
  organisation.setValidators([Validators.required]);
}

function resetOrganisationValidation(organisation: AbstractControl) {
  organisation.setValidators(null);
  organisation.setErrors(null);
}

function validate(
  gender: AbstractControl,
  firstName: AbstractControl,
  lastName: AbstractControl,
  organisation: AbstractControl,
  isOrganisationSet: boolean,
  isNameSet: boolean
): ValidationErrors | null {
  if (!isOrganisationSet && !isNameSet) {
    setNameValidation(gender, firstName, lastName);
    setOrganisationValidation(organisation);
    return { namesNotSet: true };
  } else if (!isOrganisationSet && isNameSet) {
    resetOrganisationValidation(organisation);
    return null;
  } else if (isOrganisationSet && !isNameSet) {
    resetNameValidation(gender, firstName, lastName);
    return null;
  } else if (isOrganisationSet && isNameSet) {
    return null;
  }
}
