import { AbstractControl, ValidatorFn } from '@angular/forms';
import { TreeNode } from '@msfa-shared/components/tree-nodes-selector/services/tree-nodes-selector.service';

export class TreeNodeValidator {
  static IsValidTreeNode(
    validationFn: (treeNode: TreeNode | null | undefined) => boolean,
    nameOfError: string
  ): ValidatorFn {
    return (control: AbstractControl): { [key: string]: unknown } => {
      const isValid = validationFn(control.value);

      const validationObj = {};

      if (isValid) {
        return null;
      }

      validationObj[nameOfError] = { value: control.value as TreeNode };

      return validationObj;
    };
  }

  static Required(): ValidatorFn {
    return (control: AbstractControl): { [key: string]: unknown } => {
      const hasSelectedDescendantsOrIsSelectedLeaf = (treeNode: TreeNode): boolean => {
        if (!treeNode) {
          return false;
        }

        if (!treeNode.children) {
          return treeNode.isSelected;
        }

        return treeNode.children.some(childNode => hasSelectedDescendantsOrIsSelectedLeaf(childNode));
      };
      const isValid = hasSelectedDescendantsOrIsSelectedLeaf(control.value);

      const validationObj = {};

      if (isValid) {
        return null;
      }

      validationObj['required'] = { value: control.value as TreeNode };

      return validationObj;
    };
  }
}
