import { Injector, runInInjectionContext } from '@angular/core';
import { AsyncValidatorFn } from '@angular/forms';
import { uniqueValueValidator } from '@aurora';
import { Apollo } from 'apollo-angular';
import { map } from 'rxjs';
import { checkUniqueEmailAccountQuery } from '../../account/data-access/account.graphql';

/**
 * Async validator that consults `iamCheckUniqueEmailAccount` to verify the
 * email is not already taken. In edit mode, pass `avoidValues: [item.email]`
 * so the user's own email is not flagged as duplicate (filter is server-side).
 *
 * The backend returns a boolean: `true` when the email is available.
 *
 * Tolerates network errors (returns null) and ignores empty input.
 */
export const uniqueEmailValidator = (
  injector: Injector,
  avoidValues: string[] = [],
): AsyncValidatorFn =>
  uniqueValueValidator<string>(
    (value, avoid) =>
      runInInjectionContext(injector, () =>
        injector.get(Apollo).query<{ iamCheckUniqueEmailAccount: boolean }>({
          query: checkUniqueEmailAccountQuery,
          variables: { email: value.toLowerCase(), avoidEmails: avoid },
          fetchPolicy: 'no-cache',
        }),
      ).pipe(map((result) => result.data?.iamCheckUniqueEmailAccount ?? false)),
    { avoidValues, errorKey: 'uniqueEmail' },
  );
