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

// Validator's to be applied to a FormGroup
export function dateRangeValidator(startDateField: string, endDateField: string): ValidatorFn {
  return (formGroup: AbstractControl): ValidationErrors | null => {
    const startDate = formGroup.get(startDateField)?.value;
    const endDate = formGroup.get(endDateField)?.value;

    if (startDate && endDate && new Date(startDate) > new Date(endDate)) {
      return { dateRangeInvalid: true };
    }
    return null;
  };
}

// Validator's to be applied to a field
// ====================================

// Validates that {thisDateControl} is BEFORE the {otherDateControl}
export function dateLTValidator(otherDateControlName: string): ValidatorFn {
  return (thisDateControl: AbstractControl): ValidationErrors | null => {
    const formGroup = thisDateControl.parent;
    const otherDateControl = formGroup?.get(otherDateControlName);
    
    if (!thisDateControl || !otherDateControl) return null;
    
    const thisDateValue = thisDateControl?.value;
    const otherDateValue = otherDateControl?.value;
    
    if (!thisDateValue || !otherDateValue) return null;
    
    if (thisDateValue && otherDateValue && new Date(thisDateValue) > new Date(otherDateValue)) {
      // apply validation to the other field
      otherDateControl.setErrors({ 
        dateGreaterThan: {
          'otherField': otherDateControlName,
          'dtThis': thisDateValue,
          'dtOther': otherDateValue
        } 
      }); 
      
      // apply validation to the validating field
      return { 
        dateLessThan: {
          'otherField': otherDateControlName,
          'dtThis': thisDateValue,
          'dtOther': otherDateValue
        }
      };                         
    } else {
      otherDateControl.setErrors(null);
      // otherDateControl.updateValueAndValidity();
      return null;
    }
  };
}

// Validates that {thisDateControl} is AFTER the {otherDateControl}
export function dateGTValidator(otherDateControlName: string): ValidatorFn {
  return (thisDateControl: AbstractControl): ValidationErrors | null => {
    const formGroup = thisDateControl.parent;
    const otherDateControl = formGroup?.get(otherDateControlName);
    
    if (!thisDateControl || !otherDateControl) return null;
    
    const thisDateValue = thisDateControl?.value;
    const otherDateValue = otherDateControl?.value;

    if (!thisDateValue || !otherDateValue) return null;

    if (thisDateValue && otherDateValue && new Date(thisDateValue) < new Date(otherDateValue)) {
      // apply validation to the other field
      otherDateControl.setErrors({ 
        dateLessThan: {
          'otherField': otherDateControlName,
          'dtThis': thisDateValue,
          'dtOther': otherDateValue
        }
      }); 
      
      // apply validation to the validating field
      return { 
        dateGreaterThan: {
          'otherField': otherDateControlName,
          'dtThis': thisDateValue,
          'dtOther': otherDateValue
        }          
      };
    } else {
      otherDateControl.setErrors(null);
      // otherDateControl.updateValueAndValidity();
      return null;
    }
    
  };
}