import pjson from '../../package.json';
import {
  CreateActiveUserInput, User, AddValuesResponse, UserToken, UserWithToken, Athlete, createClient, RegisterAthleteDto, Brand, CreateBrandDto, BrandGenqlSelection, AWSS3UploadUrl, AWSS3GetUploadDto, AWSS3UploadUrlGenqlSelection, UserTokenGenqlSelection, RefreshTokenInput, CreateTenantInput, Tenant, TenantGenqlSelection, TenantWithUserLogin, TenantWithUserLoginGenqlSelection, RegisterUserToDomainFromEmailInput, UserGenqlSelection, DecodedToken, Sponsorship, DomainCredential, SponsorshipGenqlSelection, CreateSponsorshipDto, SponsorAthleteInvitation, InviteAthletesDto, SponsorAthleteInvitationGenqlSelection, RegisterUserDto, VerificationCode, VerificationCodeGenqlSelection, UserWithTokenGenqlSelection, VerifyCodeDto, FindSponsorAthleteInvitationDto, FindVtxUserDto, City, CityGenqlSelection, SportLevel, SportLevelGenqlSelection, Sport, SportGenqlSelection, AthleteGenqlSelection, UserImages, UserImagesGenqlSelection, EditValueResponse, EditValueResponseGenqlSelection, EditValueDto, CreateAthleteCompetitionDto, AthleteCompetition, AthleteCompetitionGenqlSelection, SportsEventGenqlSelection, GetSportEventsDto, SportsEvent, CreateSportEventDto, GetAthleteCompetitionsDto, AthleteMembership, AthleteMembershipGenqlSelection, MembershipOrganizationReferenceGenqlSelection, MembershipOrganizationReference, CreateMembershipOrganizationDto, CreateAthleteMembershipDto, DeleteSingleValueDto, DeleteSingleValueResponse, DeleteSingleValueResponseGenqlSelection, FundRaisingCampaign, CreateFundingCampaignDto, FundRaisingCampaignGenqlSelection, AthleteQueryDto, AthleteQueryResponse, AthleteQueryResponseGenqlSelection, StripeAccountGenqlSelection, StripeSessionGenqlSelection, CreateStripeAccountDto, StripeAccount, StripeSession, StripeAccountReferenceGenqlSelection, StripeAccountReference, StripeCheckoutSessionGenqlSelection, StripeCheckoutSession, DonationCheckoutDto, GetDatabaseFileDto, TextDatabaseFileGenqlSelection, TextDatabaseFile, StripeQueryDto, StripeObject, StripeObjectGenqlSelection, SetFundingStatusDto,
  EditPictureResponseGenqlSelection, EditPictureResponse, AWSS3DeleteBucketFileDto, UploadAlbumsPicturesDto, AddValuesResponseGenqlSelection, AWSS3DeleteUseTypeFileDto,
  EditPictureDto,
  AlbumGenqlSelection,
  Album,
  CountryGenqlSelection,
  StateGenqlSelection,
  State,
  Country,
  AWSS3DeleteUseTypeKeyDto,
  AWSS3CallResultGenqlSelection,
  AthleteIntegrationReference,
  AWSS3CallResult,
  SetCompetitionResultDto,
  AthleteCompetitionResult,
  CreateVerificationCodeDto,
  CodeVerificationResponseGenqlSelection,
  CodeVerificationResponse,
  resetPasswordDto,
  DeleteValuesDto,
  DeleteValuesResponseGenqlSelection,
  existValueDto,
  ExistValueResponse,
  ExistValueResponseGenqlSelection,
  Receipt,
  ReceiptGenqlSelection,
  ReceiptUrlGenqlSelection,
  ReceiptUrl,
  GetReceiptDto
} from '../client';


import { ITypedBackendResponse } from './backend-response';

import { APICallHeaders, DEFAULT_HEADERS } from './api-call-headers';

import { buildErrorResponse, buildResponse } from './response-builder';
import { DOMAIN_SPONSOR } from './domains';
import { VTX_ERRORS } from '@vertikalx/vtx-core-common';
import { CodeVerificationResponseType, VerificationCodeType } from '@stackbus/common-types';



// DO NOT EXPORT
// FIXME: WE NEED TO REMOVE THIS CONSTANT COMPLETELY 
// SO WE CAN HAVE BUILDS THAT WORK REGARDLESS OF BACKEND URL
// AND WORK IN PROD, PRE-PROD AND LOCAL
// ISSUE WAS THAT WHEN RUNNING IN BROWSER THERE IS NO process.env.NODE
// SO IT WAS ALWAYS DEFAULTING TO PRODUCTION! @see getDefaultBackendUrl() below
// SO NOW WE HAVE A SINGLE CONSTANT, BUT WE REALLY NEED TO REMOVE IT
//const BACKEND_URL = 'https://backend.vtxathlete.com:443';  // <-- DO NOT EXPORT
//const BACKEND_URL = 'https://backend.vtxapp.net:443';  // <-- DO NOT EXPORT
const BACKEND_URL = 'http://localhost:3010';  // <-- DO NOT EXPORT



export class VTXBaseAPI {
  protected headers: APICallHeaders;
  protected backendUrl: string;

  protected static Logger = {
    debug: (str: string) => {
      //console.debug(str);
    },
    log: (str: string) => {
      console.log(str);
    },
    warn: (str: string) => {
      //console.warn(str);
    },
    error: (str: string) => {
      //console.error(str);
    },
  }

  constructor(headers?: APICallHeaders, backendUrl?: string) {
    this.headers = headers ?? DEFAULT_HEADERS;
    this.backendUrl = backendUrl ?? VTXBaseAPI.getDefaultBackendUrl();
  }


  public getHeaders(): APICallHeaders {
    return this.headers;
  }

  public setHeader(key: string, value: string) {
    this.headers[key] = value;
  }

  public static getDefaultBackendUrl() {
    let retValue :string = BACKEND_URL;

    /*
    let retValue = DEFAULT_PROD_URL;
    switch (process.env?.NODE_ENV) {
      case 'production':
        retValue = DEFAULT_PROD_URL;
        break;
      case 'preprod':
        retValue = DEFAULT_PREPROD_URL;
        break;
      case 'development':
      case 'devlocal':
        retValue = DEFAULT_DEV_LOCAL_URL;
        break;
      case 'devremote':
        retValue = DEFAULT_DEV_REMOTE_URL;
        break;
      default:
        retValue = DEFAULT_PROD_URL;
        break;

    }
    */
   

    return retValue;
  }

  public static getVersion(): string {
    return pjson?.version ?? '0.0.0';
  }

  public static isBrowser(): boolean {
    // Check if the environment is Node.js
    if (typeof process === 'object' && typeof require === 'function') {
      return false;
    }

    // Check if the environment is a
    // Service worker
    if (typeof importScripts === 'function') {
      return false;
    }

    // Check if the environment is a Browser
    if (typeof window === 'object') {
      return true;
    }

    return false;
  }

  public async findUserByEmail(
    email: string,
  ): Promise<ITypedBackendResponse<User>> {
    /*
        const headers: any = {};
        headers["Content-Type"] = "application/json";
        headers[SYSTEM_ID_HEADER] = system;      
        headers[SYSTEM_KEY_NAME_HEADER] = BACKEND_SYSTEM_KEY_NAME;
        headers[SYSTEM_KEY_VALUE_HEADER] = BACKEND_SYSTEM_KEY_VALUE;
      */
    const client = createClient({
      url: this.backendUrl + '/graphql',
      headers: this.headers,
    });

    const curatedEmail: string = email.trim().toLocaleLowerCase();

    let retValue: ITypedBackendResponse<User> = {};

    try {
      const response: any = await client.query({
        findUserByEmail: {
          __args: {
            email: curatedEmail,
          },
          _id: true,
          loginEmail: true,
          suspended: true,
          domains: {
            _id: true,
            name: true,
            description: true
          }
        },
      });


      VTXBaseAPI.Logger.debug('findUserByEmail Response:');
      VTXBaseAPI.Logger.debug(JSON.stringify(response, null, 2));

      retValue = buildResponse<User>(response, 'findUserByEmail',
        (r: any) => {
          const isResponseOk: boolean = true && response?.findUserByEmail?._id;
          return isResponseOk
        }
      );

    } catch (err1) {
      VTXBaseAPI.Logger.error('findUserByEmail err1:');
      VTXBaseAPI.Logger.error(err1);

      retValue = buildErrorResponse<User>(err1);
    }

    /*
          if (response?.findUserByEmail?._id) {
            try {
              retValue.data = response.findUserByEmail as User;
            } catch (casterr) {
              VTXBaseAPI.Logger.debug('Error trying to cast to User');
              retValue.errors = ['Error: Obtained incorrect data from Backend'];
            }
          } else if (response?.errors) {
            if (Array.isArray(response.errors)) {
              retValue.errors = response.errors;
            } else {
              retValue.errors = [response.errors];
            }
          } else if (response?.error) {
            if (Array.isArray(response.error)) {
              retValue.errors = response.error;
            } else {
              retValue.errors = [response.error];
            }
          } else {
            retValue.errors = ['Error: Obtained incorrect data from Backend'];
          }
        } catch (err1) {
          try {
            VTXBaseAPI.Logger.debug('ERROR trying to call server');
            VTXBaseAPI.Logger.debug(JSON.stringify(err1, null, 2));
          } catch (ex) {}
    
          if (Array.isArray(err1)) {
            retValue.errors = err1;
          } else {
            retValue.errors = [err1];
          }
        }
    */
    return retValue;
  }

  // TODO should be creating from user._id, NOT Email!
  public async loginUserFromEmail(
    loginEmail: string,
    loginMethod: string = ""
  ): Promise<ITypedBackendResponse<UserToken>> {

    const client = createClient({
      url: this.backendUrl + '/graphql',
      headers: this.headers,
    });

    const curatedEmail: string = loginEmail.trim().toLocaleLowerCase();

    let retValue: ITypedBackendResponse<UserToken> = {};

    try {
      const response: any = await client.mutation({
        loginUserFromEmail: {
          __args: {
            email: curatedEmail,
            loginMethod: loginMethod
          },
          actualToken: true,
          refreshToken: true,
        },
      });

      VTXBaseAPI.Logger.debug('loginUserFromEmail Response:');
      VTXBaseAPI.Logger.debug(JSON.stringify(response, null, 2));

      retValue = buildResponse<UserToken>(response, 'loginUserFromEmail',
        (r: any) => {
          const isResponseOk: boolean = true && response?.loginUserFromEmail?.actualToken;
          return isResponseOk
        }
      );

    } catch (err1) {
      VTXBaseAPI.Logger.error('loginUserFromEmail err1:');
      VTXBaseAPI.Logger.error(err1);

      retValue = buildErrorResponse<UserToken>(err1);
    }
    /*      
          VTXBaseAPI.Logger.debug(JSON.stringify(response, null, 2));
    
          if (response?.loginUserFromEmail?.actualToken) {
            try {
              retValue.data =
                response.loginUserFromEmail as UserToken;
            } catch (casterr) {
              VTXBaseAPI.Logger.debug('Error trying to cast to UserToken:');
              retValue.errors = ['Error: Obtained incorrect data from Backend'];
            }
          } else if (response?.errors) {
            if (Array.isArray(response.errors)) {
              retValue.errors = response.errors;
            } else {
              retValue.errors = [response.errors];
            }
          } else if (response?.error) {
            if (Array.isArray(response.error)) {
              retValue.errors = response.error;
            } else {
              retValue.errors = [response.error];
            }
          } else {
            retValue.errors = ['Error: Obtained incorrect data from Backend'];
          }
        } catch (err1) {
          VTXBaseAPI.Logger.debug(JSON.stringify(err1, null, 2));
          if (Array.isArray(err1)) {
            retValue.errors = err1;
          } else {
            retValue.errors = [err1];
          }
        }
    */
    return retValue;
  }


  public async createUserAndLogin(loginEmail: string): Promise<ITypedBackendResponse<UserWithToken>> {


    const client = createClient({
      url: this.backendUrl + "/graphql",
      headers: this.headers,
    });

    const curatedEmail: string = loginEmail.trim().toLowerCase();

    const payload: CreateActiveUserInput = {
      loginEmail: curatedEmail
    }


    let retValue: ITypedBackendResponse<UserWithToken> = {};

    try {
      const response: any = await client.mutation({
        createUserAndLogin: {
          __args: {
            user: payload
          },
          _id: true,
          loginEmail: true,
          suspended: true,
          token: {
            actualToken: true,
            refreshToken: true
          }
        }
      });


      VTXBaseAPI.Logger.debug('createUserAndLogin Response:');
      VTXBaseAPI.Logger.debug(JSON.stringify(response, null, 2));

      retValue = buildResponse<UserWithToken>(response, 'createUserAndLogin',
        (r: any) => {
          const isResponseOk: boolean = true && response?.createUserAndLogin?._id;
          return isResponseOk
        }
      );

    } catch (err1) {
      VTXBaseAPI.Logger.error('createUserAndLogin err1:');
      VTXBaseAPI.Logger.error(err1);

      retValue = buildErrorResponse<UserWithToken>(err1);
    }

    /*      
          if (response?.createUserAndLogin?._id){
            try{
              retValue.data = response.createUserAndLogin as UserWithToken;
            }catch(casterr){
              VTXBaseAPI.Logger.debug('Error trying to cast to UserToken:');
              retValue.errors = ['Error: Obtained incorrect data from Backend'];
            }
    
          }else if (response?.errors){
            if (Array.isArray(response.errors)){
              retValue.errors = response.errors;
            }else{
              retValue.errors = [response.errors];
            }           
    
          }else if (response?.error){
            
            if (Array.isArray(response.error)){
              retValue.errors = response.error;
            }else{
              retValue.errors = [response.error];
            }
    
          }else if (response?.data?._id){
            
            try{
              retValue.data = response?.data as UserWithToken;
            }catch(casterr){
              VTXBaseAPI.Logger.debug('Error trying to cast to UserWithToken:');
              retValue.errors = ['Error: Obtained incorrect data from Backend'];
            }
          }else{
            retValue.errors = ['Error: Obtained incorrect data from Backend'];
          }
          
        }catch(err1){
          VTXBaseAPI.Logger.debug(JSON.stringify(err1,null,2));
          if (Array.isArray(err1)){
            retValue.errors = err1;
          }else{
            retValue.errors = [err1];
          }        
        }
    */
    return retValue;
  }


  public async registerAthlete(payload: RegisterAthleteDto): Promise<ITypedBackendResponse<Athlete>> {

    const client = createClient({
      url: this.backendUrl + "/graphql",
      headers: this.headers,
    });

    let retValue: ITypedBackendResponse<Athlete> = {};


    const fields: AthleteGenqlSelection = {
      _id: true,
      firstName: true,
      lastName: true,
      screenName: true,
      dob: true,
      lgbt: true,
      competitionGender: true,
      country: {
        _id: true,
        name: true
      },
      location: {
        userProvidedLatitude: true,
        userProvidedLongitude: true,
        cityNameGeocode: true,
        stateNameGeocode: true,
        countryIso2CodeGeocode: true,
        timeZoneGeocode: true,
        latitudeGeocode: true,
        longitudeGeocode: true,
        city: {
          _id: true,
          name: true,
          localizedName: true,
          state: {
            _id: true,
            name: true,
            country: {
              _id: true,
              name: true
            }
          },
          latitude: true,
          longitude: true,
          timezone: true,
        }
      },
      trainer: true,
      trainerUrl: true,
      aboutMe: true,
      followStats: {
        followers: true,
        followed: true,
        raves: true,
        favorites: true
      },
      mainSport: {
        _id: true,
        name: true
      },
      mainSportLevel: {
        _id: true,
        label: true,
        index: true
      },
      scores: {
        vtxScore: true,
        socialScore: true,
        trainingScore: true,
        competitionScore: true
      },
      rankings: {
        worldRanking: {
          scope: true,
          scopeId: true,
          scopeName: true,
          position: true,
          total: true
        },
        countryRanking: {
          scope: true,
          scopeId: true,
          scopeName: true,
          position: true,
          total: true
        },
        stateRanking: {
          scope: true,
          scopeId: true,
          scopeName: true,
          position: true,
          total: true
        },
        cityRanking: {
          scope: true,
          scopeId: true,
          scopeName: true,
          position: true,
          total: true
        },
      },
      allSports: {
        _id: true,
        name: true
      },
      teams: {
        _id: true,
        name: true,
        description: true,
        //        sports: {
        //          _id: true,
        //          name: true
        //        },
        approved: true,
        logo: {
          _id: true,
          name: true,
          contentType: true,
          size: true,
          useType: true,
          url: true,
          key: true
        },
        banner: {
          _id: true,
          name: true,
          contentType: true,
          size: true,
          useType: true,
          url: true,
          key: true
        }

      },
      sponsorBrands: {
        _id: true,
        name: true,
        slogan: true,
        website: true,
        description: true,
        approved: true,
        published: true,
        logo: {
          _id: true,
          name: true,
          contentType: true,
          size: true,
          useType: true,
          url: true,
          key: true
        },
        //banner?: AWSS3FileGenqlSelection,
        stats: {
          campaigns: true,
          sponsorships: true,
          sports: true,
          athletes: true
        },
        operatorIds: true,

      },
      competitions: {
        _id: true,
        event: {
          _id: true,
          name: true,
          mainSport: {
            _id: true,
            name: true
          },
          eventWebSite: true,
          startDate: true,
          endDate: true,
          verified: true,
          banner: {
            _id: true,
            name: true,
            contentType: true,
            size: true,
            useType: true,
            url: true,
            key: true
          },
          location: {
            _id: true,
            userProvidedLatitude: true,
            userProvidedLongitude: true,
            cityNameGeocode: true,
            stateNameGeocode: true,
            countryIso2CodeGeocode: true,
            timeZoneGeocode: true,
            latitudeGeocode: true,
            longitudeGeocode: true,
            city: {
              _id: true,
              name: true,
              localizedName: true,
              state: {
                _id: true,
                name: true,
                country: {
                  _id: true,
                  name: true
                }
              },
              latitude: true,
              longitude: true,
              timezone: true,
            }
          },
        },
        participationDate: true,
        result: {
          _id: true,
          resultType: true,
          position: true,
          score: true,
          finishTimeMS: true,
          resultWebLink: true
        }
      },
      totalUpcomingCompetitions: true,
      totalPastCompetitions: true,
      profilePicture: {
        _id: true,
        name: true,
        contentType: true,
        size: true,
        useType: true,
        url: true,
        key: true
      },
      cardPicture: {
        _id: true,
        name: true,
        contentType: true,
        size: true,
        useType: true,
        url: true,
        key: true
      },
      preferences: {
        _id: true,
        showProfileHelper: true
      }
    };
    /*
        const fields:AthleteGenqlSelection = {
          _id: true,
          firstName: true,
          lastName:true,   
          screenName:true,
          dob:true,
          country:{
            _id: true,
            name:true
          },
          mainSport:{
            _id: true,
            name:true
          },
          mainSportLevel:{
            _id: true,
            label: true,
            index: true
          }
          
        }
    */
    try {
      const response: any = await client.mutation({
        registerAthlete: {
          __args: {
            input: payload
          },
          ...fields
        }
      });


      VTXBaseAPI.Logger.debug('registerAthlete Response:');
      VTXBaseAPI.Logger.debug(JSON.stringify(response, null, 2));

      retValue = buildResponse<Athlete>(response, 'registerAthlete',
        (r: any) => {
          const isResponseOk: boolean = true && response?.registerAthlete?._id;
          return isResponseOk
        }
      );

    } catch (err1) {
      VTXBaseAPI.Logger.error('registerAthlete err1:');
      VTXBaseAPI.Logger.error(err1);

      retValue = buildErrorResponse<Athlete>(err1);
    }
    /*      
          VTXBaseAPI.Logger.debug(JSON.stringify(response,null,2));
    
          if (response?.registerAthlete?._id){
            try{
              retValue.data = response?.registerAthlete as Athlete;
            }catch(casterr){
              VTXBaseAPI.Logger.debug('Error trying to cast to Athlete:');
              retValue.errors = ['Error: Obtained incorrect data from Backend'];
            }
    
          }else if (response?.errors){
            if (Array.isArray(response.errors)){
              retValue.errors = response.errors;
            }else{
              retValue.errors = [response.errors];
            }           
    
          }else if (response?.error){
            
            if (Array.isArray(response.error)){
              retValue.errors = response.error;
            }else{
              retValue.errors = [response.error];
            }
    
          }else if (response?.data?._id){
            
            try{
              retValue.data = response?.data as Athlete;
            }catch(casterr){
              VTXBaseAPI.Logger.debug('Error trying to cast to Athlete:');
              retValue.errors = ['Error: Obtained incorrect data from Backend'];
            }
          }else{
            retValue.errors = ['Error: Obtained incorrect data from Backend'];
          }
    
    
    
        }catch(err1){
          VTXBaseAPI.Logger.debug(JSON.stringify(err1,null,2));
          if (Array.isArray(err1)){
            retValue.errors = err1;
          }else{
            retValue.errors = [err1];
          }        
        }
    */
    return retValue;
  }

  public async findBrandByName(name: string, translations: boolean = false): Promise<ITypedBackendResponse<Brand>> {

    const client = createClient({
      url: this.backendUrl + "/graphql",
      headers: this.headers,
    });

    let retValue: ITypedBackendResponse<Brand> = {};


    try {

      let response: any = null;
      if (translations) {

        response = await client.query({
          getBrandByName: {
            __args: {
              name: name,
              translations: true
            },
            _id: true,
            name: true,
            slogan: true,
            website: true,
            description: true,
            logo: {
              name: true,
              contentType: true,
              size: true,
              useType: true,
              url: true,
              key: true
            },
            banner: {
              name: true,
              contentType: true,
              size: true,
              useType: true,
              url: true,
              key: true
            },
            translations: {
              name: true,
              slogan: true,
              description: true,
              language: true
            },
          }
        });

      } else {
        response = await client.query({
          getBrandByName: {
            __args: {
              name: name,
              translations: false
            },
            _id: true,
            name: true,
            slogan: true,
            website: true,
            description: true,
            logo: {
              name: true,
              contentType: true,
              size: true,
              useType: true,
              url: true,
              key: true
            },
            banner: {
              name: true,
              contentType: true,
              size: true,
              useType: true,
              url: true,
              key: true
            }
          }
        });

      }

      VTXBaseAPI.Logger.debug('getBrandByName Response:');
      VTXBaseAPI.Logger.debug(JSON.stringify(response, null, 2));

      retValue = buildResponse<Brand>(response, 'getBrandByName',
        (r: any) => {
          const isResponseOk: boolean = true && response?.getBrandByName?._id;
          return isResponseOk
        }
      );

    } catch (err1) {
      VTXBaseAPI.Logger.error('getBrandByName err1:');
      VTXBaseAPI.Logger.error(err1);

      retValue = buildErrorResponse<Brand>(err1);
    }

    /*
          if (response?.getBrandByName?._id){
            try{
              retValue.data = response?.getBrandByName as Brand;
            }catch(casterr){
              //VTXBaseAPI.Logger.debug('Error trying to cast to Brand:');
              retValue.errors = ['Error: Obtained incorrect data from Backend'];
            }
    
          }else if (response?.errors){
            if (Array.isArray(response.errors)){
              retValue.errors = response.errors;
            }else{
              retValue.errors = [response.errors];
            }           
    
          }else if (response?.error){
            
            if (Array.isArray(response.error)){
              retValue.errors = response.error;
            }else{
              retValue.errors = [response.error];
            }
    
          }else if (response?.data?._id){
            
            try{
              retValue.data = response?.data as Brand;
            }catch(casterr){
              //VTXBaseAPI.Logger.debug('Error trying to cast to Brand:');
              retValue.errors = ['Error: Obtained incorrect data from Backend'];
            }
          }else{
            retValue.errors = ['Error: Obtained incorrect data from Backend'];
          }
    
        }catch(err1){
          //VTXBaseAPI.Logger.debug(JSON.stringify(err1,null,2));
          if (Array.isArray(err1)){
            retValue.errors = err1;
          }else{
            retValue.errors = [err1];
          }        
        }
    */
    return retValue;
  }


  public async createBrand(dto: CreateBrandDto, desiredFields?: BrandGenqlSelection): Promise<ITypedBackendResponse<Brand>> {

    const client = createClient({
      url: this.backendUrl + "/graphql",
      headers: this.headers,
    });

    let retValue: ITypedBackendResponse<Brand> = {};

    const fields: BrandGenqlSelection = desiredFields ?? { _id: true };


    try {
      const response: any = await client.mutation({
        createBrand: {
          __args: {
            input: dto
          },
          ...fields
        }
      });


      VTXBaseAPI.Logger.debug('createBrand Response:');
      VTXBaseAPI.Logger.debug(JSON.stringify(response, null, 2));

      retValue = buildResponse<Brand>(response, 'createBrand',
        (r: any) => {
          const isResponseOk: boolean = true && response?.createBrand?._id;
          return isResponseOk
        }
      );

    } catch (err1) {
      VTXBaseAPI.Logger.error('createBrand err1:');
      VTXBaseAPI.Logger.error(err1);

      retValue = buildErrorResponse<Brand>(err1);
    }
    /*
    
          if (response?.createBrand?._id){
            try{
              retValue.data = response?.createBrand as Brand;
            }catch(casterr){
              VTXBaseAPI.Logger.debug('Error trying to cast to Brand:');
              retValue.errors = ['Error: Obtained incorrect data from Backend'];
            }
    
          }else if (response?.errors){
            if (Array.isArray(response.errors)){
              retValue.errors = response.errors;
            }else{
              retValue.errors = [response.errors];
            }           
    
          }else if (response?.error){
            
            if (Array.isArray(response.error)){
              retValue.errors = response.error;
            }else{
              retValue.errors = [response.error];
            }
    
          }else if (response?.data?._id){
            
            try{
              retValue.data = response?.data as Brand;
            }catch(casterr){
              VTXBaseAPI.Logger.debug('Error trying to cast to Brand:');
              retValue.errors = ['Error: Obtained incorrect data from Backend'];
            }
          }else{
            retValue.errors = ['Error: Obtained incorrect data from Backend'];
          }
    
    
    
        }catch(err1){
          VTXBaseAPI.Logger.debug(JSON.stringify(err1,null,2));
          if (Array.isArray(err1)){
            retValue.errors = err1;
          }else{
            retValue.errors = [err1];
          }        
        }
          */

    return retValue;
  }


  public async createSponsorship(dto: CreateSponsorshipDto, desiredFields?: SponsorshipGenqlSelection): Promise<ITypedBackendResponse<Sponsorship>> {

    const client = createClient({
      url: this.backendUrl + "/graphql",
      headers: this.headers,
    });

    let retValue: ITypedBackendResponse<Sponsorship> = {};

    const fields: SponsorshipGenqlSelection = desiredFields ?? { _id: true };


    try {
      const response: any = await client.mutation({
        createSponsorship: {
          __args: {
            input: dto
          },
          ...fields
        }
      });

      VTXBaseAPI.Logger.debug('createSponsorship Response:');
      VTXBaseAPI.Logger.debug(JSON.stringify(response, null, 2));

      retValue = buildResponse<Sponsorship>(response, 'createSponsorship',
        (r: any) => {
          const isResponseOk: boolean = true && response?.createSponsorship?._id;
          return isResponseOk
        }
      );

    } catch (err1) {
      VTXBaseAPI.Logger.error('createSponsorship err1:');
      VTXBaseAPI.Logger.error(err1);

      retValue = buildErrorResponse<Sponsorship>(err1);
    }

    /*      
          VTXBaseAPI.Logger.debug('Create Sponsorship Response:');
          VTXBaseAPI.Logger.debug(JSON.stringify(response,null,2));
    
          if (response?.createSponsorship?._id){
            try{
              retValue.data = response?.createSponsorship as Sponsorship;
            }catch(casterr){
              VTXBaseAPI.Logger.debug('Error trying to cast to Sponsorship:');
              retValue.errors = ['Error: Obtained incorrect data from Backend'];
            }
    
          }else if (response?.errors){
            if (Array.isArray(response.errors)){
              retValue.errors = response.errors;
            }else{
              retValue.errors = [response.errors];
            }           
    
          }else if (response?.error){
            
            if (Array.isArray(response.error)){
              retValue.errors = response.error;
            }else{
              retValue.errors = [response.error];
            }
    
          }else if (response?.data?._id){
            
            try{
              retValue.data = response?.data as Sponsorship;
            }catch(casterr){
              VTXBaseAPI.Logger.debug('Error trying to cast to Sponsorship:');
              retValue.errors = ['Error: Obtained incorrect data from Backend'];
            }
          }else{
            retValue.errors = ['Error: Obtained incorrect data from Backend'];
          }
    
    
    
        }catch(err1){
          VTXBaseAPI.Logger.debug(JSON.stringify(err1,null,2));
          if (Array.isArray(err1)){
            retValue.errors = err1;
          }else{
            retValue.errors = [err1];
          }        
        }
    */
    return retValue;
  }


  public async getS3UploadUrl(dto: AWSS3GetUploadDto): Promise<ITypedBackendResponse<AWSS3UploadUrl>> {

    const client = createClient({
      url: this.backendUrl + "/graphql",
      headers: this.headers,
    });

    let retValue: ITypedBackendResponse<AWSS3UploadUrl> = {};

    const fields: AWSS3UploadUrlGenqlSelection = {
      uploadUrl: true,
      fields: {
        key: true,
        value: true
      },
      downloadUrl: true,
      bucket: true,
      key: true
    };

    try {


      const response = await client.query({
        getUploadUrl: {
          __args: {
            input: dto
          },
          ...fields
        }
      });


      VTXBaseAPI.Logger.debug('getUploadUrl Response:');
      VTXBaseAPI.Logger.debug(JSON.stringify(response, null, 2));


      retValue = buildResponse<AWSS3UploadUrl>(response, 'getUploadUrl',
        (r: any) => {
          const isResponseOk: boolean = true && ((response?.getUploadUrl?.uploadUrl !== undefined) && (response?.getUploadUrl?.uploadUrl !== null))
          return isResponseOk;
        }
      );

    } catch (err1) {
      VTXBaseAPI.Logger.error('createSponsorship err1:');
      VTXBaseAPI.Logger.error(err1);

      retValue = buildErrorResponse<AWSS3UploadUrl>(err1);
    }

    /*      
    
          if (response?.getUploadUrl?.key){
            try{
              retValue.data = response?.getUploadUrl as AWSS3UploadUrl;
            }catch(casterr){
              VTXBaseAPI.Logger.debug('Error trying to cast to AWSS3UploadUrl:');
              retValue.errors = ['Error: Obtained incorrect data from Backend'];
            }
    
          }else{
            retValue.errors = ["Unable to generate correct upload URL"];
          }
    
        }catch(err1){
          VTXBaseAPI.Logger.debug(JSON.stringify(err1,null,2));
          if (Array.isArray(err1)){
            retValue.errors = err1;
          }else{
            retValue.errors = [err1];
          }        
        }
    */
    return retValue;

  }


  public async refreshToken(currentToken: string, refreshToken: string): Promise<ITypedBackendResponse<UserToken>> {
    const client = createClient({
      url: this.backendUrl + "/graphql",
      headers: this.headers,
    });

    VTXBaseAPI.Logger.debug('HEADERS:');
    VTXBaseAPI.Logger.debug(JSON.stringify(this.headers, null, 2));

    const fields: UserTokenGenqlSelection = {
      actualToken: true,
      refreshToken: true
    };

    const dto: RefreshTokenInput = {
      refreshToken: refreshToken
    };
    let retValue: ITypedBackendResponse<UserToken>;

    try {
      const response: any = await client.mutation({
        refreshToken: {
          __args: {
            dto: dto
          },
          ...fields
        }
      });

      VTXBaseAPI.Logger.debug('refreshToken Response:');
      VTXBaseAPI.Logger.debug(JSON.stringify(response, null, 2));

      retValue = buildResponse<UserToken>(response, 'refreshToken',
        (r: any) => {
          const isResponseOk: boolean = true && response?.refreshToken?.refreshToken;
          return isResponseOk
        }
      );

    } catch (err1) {
      VTXBaseAPI.Logger.error('refreshToken err1:');
      VTXBaseAPI.Logger.error(err1);

      retValue = buildErrorResponse<UserToken>(err1);
    }

    return retValue;
  }

  public async registerNewDomainTenant(input: CreateTenantInput): Promise<ITypedBackendResponse<Tenant>> {
    const client = createClient({
      url: this.backendUrl + "/graphql",
      headers: this.headers,
    });

    //VTXBaseAPI.Logger.debug('HEADERS:');
    //VTXBaseAPI.Logger.debug(JSON.stringify(this.headers, null, 2));

    const fields: TenantGenqlSelection = {
      _id: true,
      name: true,
      email: true,
      tenant_uri: true,
      owner: {
        _id: true,
        loginEmail: true,
        suspended: true
      },
      domain: {
        _id: true,
        name: true,
        description: true
      }
    };


    let retValue: ITypedBackendResponse<Tenant>;

    try {
      const response: any = await client.mutation({
        registerNewDomainTenant: {
          __args: {
            tenant: input
          },
          ...fields
        }
      });

      VTXBaseAPI.Logger.debug('registerNewDomainTenant Response:');
      VTXBaseAPI.Logger.debug(JSON.stringify(response, null, 2));

      retValue = buildResponse<Tenant>(response, 'registerNewDomainTenant',
        (r: any) => {
          const isResponseOk: boolean = true && response?.registerNewDomainTenant?._id;
          return isResponseOk
        }
      );

    } catch (err1) {
      VTXBaseAPI.Logger.error('registerNewDomainTenant err1:');
      VTXBaseAPI.Logger.error(err1);

      retValue = buildErrorResponse<Tenant>(err1);
    }

    return retValue;

  }

  public async registerNewDomainTenantWithLogin(input: CreateTenantInput): Promise<ITypedBackendResponse<TenantWithUserLogin>> {
    const client = createClient({
      url: this.backendUrl + "/graphql",
      headers: this.headers,
    });

    //VTXBaseAPI.Logger.debug('HEADERS:');
    //VTXBaseAPI.Logger.debug(JSON.stringify(this.headers, null, 2));

    const fields: TenantWithUserLoginGenqlSelection = {
      _id: true,
      name: true,
      email: true,
      tenant_uri: true,
      owner: {
        _id: true,
        loginEmail: true,
        suspended: true
      },
      domain: {
        _id: true,
        name: true,
        description: true
      },
      user: {
        _id: true,
        loginEmail: true,
        suspended: true,
        domains: {
          _id: true,
          name: true,
          description: true
        },
        token: {
          actualToken: true,
          refreshToken: true
        }
      }
    };


    let retValue: ITypedBackendResponse<TenantWithUserLogin>;

    try {
      const response: any = await client.mutation({
        registerNewDomainTenantWithLogin: {
          __args: {
            tenant: input
          },
          ...fields
        }
      });

      VTXBaseAPI.Logger.debug('registerNewDomainTenant Response:');
      VTXBaseAPI.Logger.debug(JSON.stringify(response, null, 2));

      retValue = buildResponse<TenantWithUserLogin>(response, 'TenantWithUserLogin',
        (r: any) => {
          const isResponseOk: boolean = true && response?.TenantWithUserLogin?._id;
          return isResponseOk
        }
      );

    } catch (err1) {
      VTXBaseAPI.Logger.error('registerNewDomainTenantWithLogin err1:');
      VTXBaseAPI.Logger.error(err1);

      retValue = buildErrorResponse<TenantWithUserLogin>(err1);
    }

    return retValue;

  }

  public async registerUserToDomainFromEmail(input: RegisterUserToDomainFromEmailInput): Promise<ITypedBackendResponse<User>> {
    const client = createClient({
      url: this.backendUrl + "/graphql",
      headers: this.headers,
    });

    //VTXBaseAPI.Logger.debug('HEADERS:');
    //VTXBaseAPI.Logger.debug(JSON.stringify(this.headers, null, 2));

    const fields: UserGenqlSelection = {
      _id: true,
      loginEmail: true,
      suspended: true,
      domains: {
        _id: true,
        name: true,
        description: true,
        tenant: {
          _id: true,
          name: true,
          tenant_uri: true
        }
      }
    };


    let retValue: ITypedBackendResponse<User>;

    try {
      const response: any = await client.mutation({
        registerUserToDomainFromEmail: {
          __args: {
            input: input
          },
          ...fields
        }
      });

      VTXBaseAPI.Logger.debug('registerUserToDomainFromEmail Response:');
      VTXBaseAPI.Logger.debug(JSON.stringify(response, null, 2));

      retValue = buildResponse<User>(response, 'registerUserToDomainFromEmail',
        (r: any) => {
          const isResponseOk: boolean = true && response?.registerUserToDomainFromEmail?.loginEmail;
          return isResponseOk
        }
      );

    } catch (err1) {
      VTXBaseAPI.Logger.error('registerUserToDomainFromEmail err1:');
      VTXBaseAPI.Logger.error(err1);

      retValue = buildErrorResponse<User>(err1);
    }

    return retValue;

  }

  public async getPublicSponsorships(): Promise<ITypedBackendResponse<Sponsorship[]>> {

    const client = createClient({
      url: this.backendUrl + "/graphql",
      headers: this.headers,
    });

    //VTXBaseAPI.Logger.debug('HEADERS:');
    //VTXBaseAPI.Logger.debug(JSON.stringify(this.headers, null, 2));

    const fields: SponsorshipGenqlSelection = {
      _id: true,
      title: true,
      description: true,
      cashValue: true,
      otherValue: true,
      brand: {
        _id: true,
        name: true,
        slogan: true,
        website: true,
        description: true,
        approved: true,
        published: true,
        logo: {
          _id: true,
          name: true,
          contentType: true,
          size: true,
          useType: true,
          url: true,
          key: true
        },
        banner: {
          _id: true,
          name: true,
          contentType: true,
          size: true,
          useType: true,
          url: true,
          key: true
        },
        stats: {
          campaigns: true,
          sponsorships: true,
          sports: true,
          athletes: true
        },
        operatorIds: true
      },
      banner: {
        _id: true,
        name: true,
        contentType: true,
        size: true,
        useType: true,
        url: true,
        key: true
      },
      criteria: {
        _id: true,
        label: true,
        qualifications: {
          on_AgeQualification: {
            type: true,
            value: true,
            operator: true
          },
          on_DistanceQualification: {
            type: true,
            maxDistance: true,
            latitude: true,
            longitude: true
          },
          on_GenderQualification: {
            type: true,
            operator: true,
            values: true
          },
          on_LocationQualification: {
            type: true,
            operator: true,
            countries: {
              _id: true,
              name: true
            },
            states: {
              _id: true,
              name: true,
              country: {
                _id: true,
                name: true
              }
            },
            cities: {
              _id: true,
              name: true,
              localizedName: true,
              state: {
                _id: true,
                name: true,
                country: {
                  _id: true,
                  name: true
                }
              },
              latitude: true,
              longitude: true,
              timezone: true
            }
          },
          on_NationalityQualification: {
            type: true,
            operator: true,
            countries: {
              _id: true,
              name: true
            }
          },
          on_ScoreQualification: {
            type: true,
            scoreType: true,
            operator: true,
            value: true
          },
          on_SportsLevelQualification: {
            type: true,
            operator: true,
            level: true
          },
          on_SportsQualification: {
            type: true,
            sports: true,
            operator: true
          }
        }
      },
      sponsorshipItems: {
        _id: true,
        quantity: true,
        title: true,
        value: true,
        type: true
      },
      deadline: true,
      startDate: true,
      duration: {
        length: true,
        unit: true
      },
      terms: true,
      isPrivate: true,
      stats: {
        totalApplications: true,
        newApplications: true,
        discardedApplications: true,
        selectedApplications: true,
        approvedApplications: true,
        grantedSponsorships: true,
        remainingSponsorships: true
      },
      approved: true,
      published: true
    };


    let retValue: ITypedBackendResponse<Sponsorship[]>;

    try {
      const response: any = await client.query({
        getPublicSponsorships: {
          __args: {},
          ...fields
        }
      });

      VTXBaseAPI.Logger.debug('getPublicSponsorships Response:');
      VTXBaseAPI.Logger.debug(JSON.stringify(response, null, 2));

      retValue = buildResponse<Sponsorship[]>(response, 'getPublicSponsorships',
        (r: any) => {
          VTXBaseAPI.Logger.debug(JSON.stringify(response, null, 2));
          const isResponseOk: boolean = true;//&& response?.getPublicSponsorships?._id;
          return isResponseOk
        }
      );

    } catch (err1) {
      VTXBaseAPI.Logger.error('getPublicSponsorships err1:');
      VTXBaseAPI.Logger.error(err1);

      retValue = buildErrorResponse<Sponsorship[]>(err1);
    }

    return retValue;


  }
  public async getTenantSponsorshipsFromUri(tenantUri: string, token: DecodedToken): Promise<ITypedBackendResponse<Sponsorship[]>> {

    if ((!tenantUri) || (tenantUri.trim() === "")) {
      return {
        error: {
          httpStatus: 400,
          code: VTX_ERRORS.INVALID_TENANT_URI.code,
          message: VTX_ERRORS.INVALID_TENANT_URI.description
        }
      };
    }

    const credential: DomainCredential | undefined = token.domains.find(c => {
      if (c.tenant) {
        if ((c.tenant.tenant_uri == tenantUri) && (c._id == DOMAIN_SPONSOR)) {

          return true;
        }
      }
      return false;
    });

    if (!credential) {

      return {
        error: {
          httpStatus: 400,
          code: VTX_ERRORS.INVALID_TENANT_URI_FOR_SPONSOR.code,
          message: "Tenant in domain SPONSOR not found in domains with URI " + tenantUri
        }
      };

    }

    const tenantId: string | null = credential.tenant?._id ?? null;

    if ((!tenantId) || (tenantId == "ALL")) {
      return {
        error: {
          httpStatus: 400,
          code: VTX_ERRORS.INVALID_TENANT_ID.code,
          message: VTX_ERRORS.INVALID_TENANT_ID.description
        }
      };
    }

    return this.getTenantSponsorships(tenantId);

  }
  public async getTenantSponsorships(tenantId: string): Promise<ITypedBackendResponse<Sponsorship[]>> {

    const client = createClient({
      url: this.backendUrl + "/graphql",
      headers: this.headers,
    });

    //VTXBaseAPI.Logger.debug('HEADERS:');
    //VTXBaseAPI.Logger.debug(JSON.stringify(this.headers, null, 2));

    const fields: SponsorshipGenqlSelection = {
      _id: true,
      title: true,
      description: true,
      cashValue: true,
      otherValue: true,
      brand: {
        _id: true,
        name: true,
        slogan: true,
        website: true,
        description: true,
        approved: true,
        published: true,
        logo: {
          _id: true,
          name: true,
          contentType: true,
          size: true,
          useType: true,
          url: true,
          key: true
        },
        banner: {
          _id: true,
          name: true,
          contentType: true,
          size: true,
          useType: true,
          url: true,
          key: true
        },
        stats: {
          campaigns: true,
          sponsorships: true,
          sports: true,
          athletes: true
        },
        operatorIds: true
      },
      banner: {
        _id: true,
        name: true,
        contentType: true,
        size: true,
        useType: true,
        url: true,
        key: true
      },
      criteria: {
        _id: true,
        label: true,
        qualifications: {
          on_AgeQualification: {
            type: true,
            value: true,
            operator: true
          },
          on_DistanceQualification: {
            type: true,
            maxDistance: true,
            latitude: true,
            longitude: true
          },
          on_GenderQualification: {
            type: true,
            operator: true,
            values: true
          },
          on_LocationQualification: {
            type: true,
            operator: true,
            countries: {
              _id: true,
              name: true
            },
            states: {
              _id: true,
              name: true,
              country: {
                _id: true,
                name: true
              }
            },
            cities: {
              _id: true,
              name: true,
              localizedName: true,
              state: {
                _id: true,
                name: true,
                country: {
                  _id: true,
                  name: true
                }
              },
              latitude: true,
              longitude: true,
              timezone: true
            }
          },
          on_NationalityQualification: {
            type: true,
            operator: true,
            countries: {
              _id: true,
              name: true
            }
          },
          on_ScoreQualification: {
            type: true,
            scoreType: true,
            operator: true,
            value: true
          },
          on_SportsLevelQualification: {
            type: true,
            operator: true,
            level: true
          },
          on_SportsQualification: {
            type: true,
            sports: true,
            operator: true
          }
        }
      },
      sponsorshipItems: {
        _id: true,
        quantity: true,
        title: true,
        value: true,
        type: true
      },
      deadline: true,
      startDate: true,
      duration: {
        length: true,
        unit: true
      },
      terms: true,
      isPrivate: true,
      stats: {
        totalApplications: true,
        newApplications: true,
        discardedApplications: true,
        selectedApplications: true,
        approvedApplications: true,
        grantedSponsorships: true,
        remainingSponsorships: true
      },
      approved: true,
      published: true
    };


    let retValue: ITypedBackendResponse<Sponsorship[]>;

    try {
      const response: any = await client.query({
        getTenantSponsorships: {
          __args: {},
          ...fields
        }
      });

      VTXBaseAPI.Logger.debug('getTenantSponsorships Response:');
      VTXBaseAPI.Logger.debug(JSON.stringify(response, null, 2));

      retValue = buildResponse<Sponsorship[]>(response, 'getTenantSponsorships',
        (r: any) => {
          VTXBaseAPI.Logger.debug(JSON.stringify(response, null, 2));
          const isResponseOk: boolean = true;//&& response?.getTenantSponsorships?._id;
          return isResponseOk
        }
      );

    } catch (err1) {
      VTXBaseAPI.Logger.error('getTenantSponsorships err1:');
      VTXBaseAPI.Logger.error(err1);

      retValue = buildErrorResponse<Sponsorship[]>(err1);
    }

    return retValue;


  }


  public async sendAthleteInvitations(input: InviteAthletesDto): Promise<ITypedBackendResponse<SponsorAthleteInvitation[]>> {
    const client = createClient({
      url: this.backendUrl + "/graphql",
      headers: this.headers,
    });

    //VTXBaseAPI.Logger.debug('HEADERS:');
    //VTXBaseAPI.Logger.debug(JSON.stringify(this.headers, null, 2));

    const fields: SponsorAthleteInvitationGenqlSelection = {
      _id: true,
      name: true,
      email: true,
      dateSent: true,
      sponsor: {
        _id: true,
        name: true,
        tenant: {
          _id: true,
          name: true,
          tenant_uri: true
        }
      },
      magicLink: {
        _id: true,
        code: true,
        type: true,
        url: true,
        expires: true,
        data: true,
        isExpired: true
      },
      brand: {
        _id: true,
        name: true,
        logo: {
          _id: true,
          name: true,
          contentType: true,
          url: true,
          useType: true
        },
        website: true
      },
      status: true
    };


    let retValue: ITypedBackendResponse<SponsorAthleteInvitation[]>;

    try {
      const response: any = await client.mutation({
        sendAthleteInvitations: {
          __args: {
            input: input
          },
          ...fields
        }
      });

      VTXBaseAPI.Logger.debug('sendAthleteInvitations Response:');
      VTXBaseAPI.Logger.debug(JSON.stringify(response, null, 2));

      retValue = buildResponse<SponsorAthleteInvitation[]>(response, 'sendAthleteInvitations',
        (r: any) => {
          const isResponseOk: boolean = true && Array.isArray(response?.sendAthleteInvitations);
          return isResponseOk
        }
      );

    } catch (err1) {
      VTXBaseAPI.Logger.error('sendAthleteInvitations err1:');
      VTXBaseAPI.Logger.error(err1);

      retValue = buildErrorResponse<SponsorAthleteInvitation[]>(err1);
    }

    return retValue;

  }

  public async registerSponsorUser(input: RegisterUserDto): Promise<ITypedBackendResponse<User>> {
    const client = createClient({
      url: this.backendUrl + "/graphql",
      headers: this.headers,
    });

    //VTXBaseAPI.Logger.debug('HEADERS:');
    //VTXBaseAPI.Logger.debug(JSON.stringify(this.headers, null, 2));

    const fields: UserGenqlSelection = {
      _id: true,
      loginEmail: true,
      suspended: true,
      domains: {
        _id: true,
        name: true,
        description: true,
        tenant: {
          _id: true,
          name: true,
          tenant_uri: true,
          domain: {
            _id: true,
            name: true,
            description: true
          }
        }
      }
    };


    let retValue: ITypedBackendResponse<User>;

    try {
      const response: any = await client.mutation({
        registerSponsorUser: {
          __args: {
            input: input
          },
          ...fields
        }
      });

      VTXBaseAPI.Logger.debug('registerSponsorUser Response:');
      VTXBaseAPI.Logger.debug(JSON.stringify(response, null, 2));

      retValue = buildResponse<User>(response, 'registerSponsorUser',
        (r: any) => {
          const isResponseOk: boolean = true && response?.registerSponsorUser._id;
          return isResponseOk
        }
      );

    } catch (err1) {
      VTXBaseAPI.Logger.error('registerSponsorUser err1:');
      VTXBaseAPI.Logger.error(err1);

      retValue = buildErrorResponse<User>(err1);
    }

    return retValue;

  }


  public async registerAthleteUser(input: RegisterUserDto): Promise<ITypedBackendResponse<User>> {
    const client = createClient({
      url: this.backendUrl + "/graphql",
      headers: this.headers,
    });

    //VTXBaseAPI.Logger.debug('HEADERS:');
    //VTXBaseAPI.Logger.debug(JSON.stringify(this.headers, null, 2));

    const fields: UserGenqlSelection = {
      _id: true,
      loginEmail: true,
      suspended: true,
      domains: {
        _id: true,
        name: true,
        description: true,
        tenant: {
          _id: true,
          name: true,
          tenant_uri: true,
          domain: {
            _id: true,
            name: true,
            description: true
          }
        }
      }
    };


    let retValue: ITypedBackendResponse<User>;

    try {
      const response: any = await client.mutation({
        registerAthleteUser: {
          __args: {
            input: input
          },
          ...fields
        }
      });

      VTXBaseAPI.Logger.debug('registerAthleteUser Response:');
      VTXBaseAPI.Logger.debug(JSON.stringify(response, null, 2));

      retValue = buildResponse<User>(response, 'registerAthleteUser',
        (r: any) => {
          const isResponseOk: boolean = true && response?.registerAthleteUser._id;
          return isResponseOk
        }
      );

    } catch (err1) {
      VTXBaseAPI.Logger.error('registerAthleteUser err1:');
      VTXBaseAPI.Logger.error(err1);

      retValue = buildErrorResponse<User>(err1);
    }

    return retValue;

  }

  public async preRegisterAthleteUser(input: RegisterUserDto): Promise<ITypedBackendResponse<VerificationCode>> {
    const client = createClient({
      url: this.backendUrl + "/graphql",
      headers: this.headers,
    });

    //VTXBaseAPI.Logger.debug('HEADERS:');
    //VTXBaseAPI.Logger.debug(JSON.stringify(this.headers, null, 2));

    const fields: VerificationCodeGenqlSelection = {
      _id: true,
      type: true,
      recipient: true,
      expires: true,
      //data:true, excuded purposely 
      isExpired: true,
      createdDate: true
    };


    let retValue: ITypedBackendResponse<VerificationCode>;

    try {
      const response: any = await client.mutation({
        preRegisterAthleteUser: {
          __args: {
            input: input
          },
          ...fields
        }
      });

      VTXBaseAPI.Logger.debug('preRegisterAthleteUser Response:');
      VTXBaseAPI.Logger.debug(JSON.stringify(response, null, 2));

      retValue = buildResponse<VerificationCode>(response, 'preRegisterAthleteUser',
        (r: any) => {
          const isResponseOk: boolean = true && response?.preRegisterAthleteUser._id;
          return isResponseOk
        }
      );

    } catch (err1) {
      VTXBaseAPI.Logger.error('preRegisterAthleteUser err1:');
      VTXBaseAPI.Logger.error(err1);

      retValue = buildErrorResponse<VerificationCode>(err1);
    }

    return retValue;

  }


  public async confirmAthleteUserRegistrationAndLogin(input: VerifyCodeDto): Promise<ITypedBackendResponse<UserWithToken>> {
    const client = createClient({
      url: this.backendUrl + "/graphql",
      headers: this.headers,
    });

    //VTXBaseAPI.Logger.debug('HEADERS:');
    //VTXBaseAPI.Logger.debug(JSON.stringify(this.headers, null, 2));

    const fields: UserWithTokenGenqlSelection = {
      _id: true,
      loginEmail: true,
      suspended: true,
      domains: {
        _id: true,
        name: true,
        description: true,
        tenant: {
          _id: true,
          name: true,
          tenant_uri: true,
          domain: {
            _id: true,
            name: true,
            description: true
          }
        }
      },
      token: {
        actualToken: true,
        refreshToken: true
      }
    };


    let retValue: ITypedBackendResponse<UserWithToken>;

    try {
      const response: any = await client.mutation({
        confirmAthleteUserRegistrationAndLogin: {
          __args: {
            input: input
          },
          ...fields
        }
      });

      VTXBaseAPI.Logger.debug('confirmAthleteUserRegistrationAndLogin Response:');
      VTXBaseAPI.Logger.debug(JSON.stringify(response, null, 2));

      retValue = buildResponse<UserWithToken>(response, 'confirmAthleteUserRegistrationAndLogin',
        (r: any) => {
          const isResponseOk: boolean = true && response?.confirmAthleteUserRegistrationAndLogin._id;
          return isResponseOk
        }
      );

    } catch (err1) {
      VTXBaseAPI.Logger.error('confirmAthleteUserRegistrationAndLogin err1:');
      VTXBaseAPI.Logger.error(err1);

      retValue = buildErrorResponse<UserWithToken>(err1);
    }

    return retValue;

  }


  public async confirmAthleteUserRegistration(input: VerifyCodeDto): Promise<ITypedBackendResponse<User>> {
    const client = createClient({
      url: this.backendUrl + "/graphql",
      headers: this.headers,
    });

    //VTXBaseAPI.Logger.debug('HEADERS:');
    //VTXBaseAPI.Logger.debug(JSON.stringify(this.headers, null, 2));

    const fields: UserGenqlSelection = {
      _id: true,
      loginEmail: true,
      suspended: true,
      domains: {
        _id: true,
        name: true,
        description: true,
        tenant: {
          _id: true,
          name: true,
          tenant_uri: true,
          domain: {
            _id: true,
            name: true,
            description: true
          }
        }
      }
    };


    let retValue: ITypedBackendResponse<User>;

    try {
      const response: any = await client.mutation({
        confirmAthleteUserRegistration: {
          __args: {
            input: input
          },
          ...fields
        }
      });

      VTXBaseAPI.Logger.debug('confirmAthleteUserRegistration Response:');
      VTXBaseAPI.Logger.debug(JSON.stringify(response, null, 2));

      retValue = buildResponse<User>(response, 'confirmAthleteUserRegistration',
        (r: any) => {
          const isResponseOk: boolean = true && response?.confirmAthleteUserRegistration._id;
          return isResponseOk
        }
      );

    } catch (err1) {
      VTXBaseAPI.Logger.error('confirmAthleteUserRegistration err1:');
      VTXBaseAPI.Logger.error(err1);

      retValue = buildErrorResponse<User>(err1);
    }

    return retValue;

  }


  public async findSponsorAthleteInvitation(dto: FindSponsorAthleteInvitationDto): Promise<ITypedBackendResponse<SponsorAthleteInvitation>> {

    const client = createClient({
      url: this.backendUrl + "/graphql",
      headers: this.headers,
    });

    //VTXBaseAPI.Logger.debug('HEADERS:');
    //VTXBaseAPI.Logger.debug(JSON.stringify(this.headers, null, 2));

    const fields: SponsorAthleteInvitationGenqlSelection = {
      _id: true,
      name: true,
      email: true,
      dateSent: true,
      sponsor: {
        _id: true,
        name: true,
        description: true,
        approved: true
      },
      magicLink: {
        _id: true,
        code: true,
        type: true,
        url: true,
        expires: true,
        isExpired: true
      },
      brand: {
        _id: true,
        name: true,
        slogan: true,
        website: true,
        description: true,
        approved: true,
        published: true,
        logo: {
          _id: true,
          name: true,
          contentType: true,
          size: true,
          useType: true,
          url: true,
          key: true
        },
        banner: {
          _id: true,
          name: true,
          contentType: true,
          size: true,
          useType: true,
          url: true,
          key: true
        }
      },
      status: true
    };


    let retValue: ITypedBackendResponse<SponsorAthleteInvitation>;

    try {
      const response: any = await client.query({
        findSponsorAthleteInvitation: {
          __args: {
            input: dto
          },
          ...fields
        }
      });

      VTXBaseAPI.Logger.debug('findSponsorAthleteInvitation Response:');
      VTXBaseAPI.Logger.debug(JSON.stringify(response, null, 2));

      retValue = buildResponse<SponsorAthleteInvitation>(response, 'findSponsorAthleteInvitation',
        (r: any) => {
          VTXBaseAPI.Logger.debug(JSON.stringify(response, null, 2));
          const isResponseOk: boolean = true && response?.findSponsorAthleteInvitation?._id;
          return isResponseOk
        }
      );

    } catch (err1) {
      VTXBaseAPI.Logger.error('findSponsorAthleteInvitation err1:');
      VTXBaseAPI.Logger.error(err1);

      retValue = buildErrorResponse<SponsorAthleteInvitation>(err1);
    }

    return retValue;


  }


  public async findVtxUser(dto: FindVtxUserDto): Promise<ITypedBackendResponse<User>> {

    const client = createClient({
      url: this.backendUrl + "/graphql",
      headers: this.headers,
    });

    //VTXBaseAPI.Logger.debug('HEADERS:');
    //VTXBaseAPI.Logger.debug(JSON.stringify(this.headers, null, 2));

    const fields: UserGenqlSelection = {
      _id: true,
      loginEmail: true,
      suspended: true,
      domains: {
        _id: true,
        name: true,
        description: true,
        tenant: {
          _id: true,
          name: true,
          tenant_uri: true,
          domain: {
            _id: true,
            name: true,
            description: true
          }
        }
      }
    };


    let retValue: ITypedBackendResponse<User>;

    try {
      const response: any = await client.query({
        findVtxUser: {
          __args: {
            input: dto
          },
          ...fields
        }
      });

      VTXBaseAPI.Logger.debug('findVtxUser Response:');
      VTXBaseAPI.Logger.debug(JSON.stringify(response, null, 2));

      retValue = buildResponse<User>(response, 'findVtxUser',
        (r: any) => {
          VTXBaseAPI.Logger.debug(JSON.stringify(response, null, 2));
          const isResponseOk: boolean = true && response?.findVtxUser?._id;
          return isResponseOk
        }
      );

    } catch (err1) {
      VTXBaseAPI.Logger.error('findVtxUser err1:');
      VTXBaseAPI.Logger.error(err1);

      retValue = buildErrorResponse<User>(err1);
    }

    return retValue;


  }

  public async findCitiesStartingWith(pattern: string): Promise<ITypedBackendResponse<City[]>> {


    const client = createClient({
      url: this.backendUrl + "/graphql",
      headers: this.headers,
    });

    //VTXBaseAPI.Logger.debug('HEADERS:');
    //VTXBaseAPI.Logger.debug(JSON.stringify(this.headers, null, 2));

    const fields: CityGenqlSelection = {
      _id: true,
      name: true,
      localizedName: true,
      state: {
        _id: true,
        name: true,
        country: {
          _id: true,
          name: true
        }
      },
      latitude: true,
      longitude: true,
      timezone: true
    };


    let retValue: ITypedBackendResponse<City[]>;

    try {
      const response: any = await client.query({
        findCitiesStartingWith: {
          __args: {
            text: pattern
          },
          ...fields
        }
      });

      VTXBaseAPI.Logger.debug('findCitiesStartingWith Response:');
      VTXBaseAPI.Logger.debug(JSON.stringify(response, null, 2));

      retValue = buildResponse<City[]>(response, 'findCitiesStartingWith',
        (r: any) => {
          VTXBaseAPI.Logger.debug(JSON.stringify(response, null, 2));
          const isResponseOk: boolean = true && Array.isArray(response?.findCitiesStartingWith)
          return isResponseOk
        }
      );

    } catch (err1) {
      VTXBaseAPI.Logger.error('findCitiesStartingWith err1:');
      VTXBaseAPI.Logger.error(err1);

      retValue = buildErrorResponse<City[]>(err1);
    }

    return retValue;

  }

  public async findCityById(cityId: string): Promise<ITypedBackendResponse<City>> {

    const client = createClient({
      url: this.backendUrl + "/graphql",
      headers: this.headers,
    });

    //VTXBaseAPI.Logger.debug('HEADERS:');
    //VTXBaseAPI.Logger.debug(JSON.stringify(this.headers, null, 2));

    const fields: CityGenqlSelection = {
      _id: true,
      name: true,
      localizedName: true,
      state: {
        _id: true,
        name: true,
        country: {
          _id: true,
          name: true
        }
      },
      latitude: true,
      longitude: true,
      timezone: true
    };


    let retValue: ITypedBackendResponse<City>;

    try {
      const response: any = await client.query({
        findCityById: {
          __args: {
            cityId: cityId
          },
          ...fields
        }
      });

      VTXBaseAPI.Logger.debug('findCityById Response:');
      VTXBaseAPI.Logger.debug(JSON.stringify(response, null, 2));

      retValue = buildResponse<City>(response, 'findCityById',
        (r: any) => {
          VTXBaseAPI.Logger.debug(JSON.stringify(response, null, 2));
          const isResponseOk: boolean = true && response?.findCityById?._id;
          return isResponseOk
        }
      );

    } catch (err1) {
      VTXBaseAPI.Logger.error('findCityById err1:');
      VTXBaseAPI.Logger.error(err1);

      retValue = buildErrorResponse<City>(err1);
    }

    return retValue;


  }

  public async getSportLevels(): Promise<ITypedBackendResponse<SportLevel[]>> {


    const client = createClient({
      url: this.backendUrl + "/graphql",
      headers: this.headers,
    });

    //VTXBaseAPI.Logger.debug('HEADERS:');
    //VTXBaseAPI.Logger.debug(JSON.stringify(this.headers, null, 2));

    const fields: SportLevelGenqlSelection = {
      _id: true,
      label: true,
      index: true
    };


    let retValue: ITypedBackendResponse<SportLevel[]>;

    try {
      const response: any = await client.query({
        getSportLevels: {
          __args: {
          },
          ...fields
        }
      });

      VTXBaseAPI.Logger.debug('getSportLevels Response:');
      VTXBaseAPI.Logger.debug(JSON.stringify(response, null, 2));

      retValue = buildResponse<SportLevel[]>(response, 'getSportLevels',
        (r: any) => {
          VTXBaseAPI.Logger.debug(JSON.stringify(response, null, 2));
          const isResponseOk: boolean = true && Array.isArray(response?.getSportLevels)
          return isResponseOk
        }
      );

    } catch (err1) {
      VTXBaseAPI.Logger.error('getSportLevels err1:');
      VTXBaseAPI.Logger.error(err1);

      retValue = buildErrorResponse<SportLevel[]>(err1);
    }

    return retValue;

  }

  public async getSports(): Promise<ITypedBackendResponse<Sport[]>> {


    const client = createClient({
      url: this.backendUrl + "/graphql",
      headers: this.headers,
    });

    //VTXBaseAPI.Logger.debug('HEADERS:');
    //VTXBaseAPI.Logger.debug(JSON.stringify(this.headers, null, 2));

    const fields: SportGenqlSelection = {
      _id: true,
      name: true
    };


    let retValue: ITypedBackendResponse<Sport[]>;

    try {
      const response: any = await client.query({
        getSports: {
          __args: {
          },
          ...fields
        }
      });

      VTXBaseAPI.Logger.debug('getSports Response:');
      VTXBaseAPI.Logger.debug(JSON.stringify(response, null, 2));

      retValue = buildResponse<Sport[]>(response, 'getSports',
        (r: any) => {
          VTXBaseAPI.Logger.debug(JSON.stringify(response, null, 2));
          const isResponseOk: boolean = true && Array.isArray(response?.getSports)
          return isResponseOk
        }
      );

    } catch (err1) {
      VTXBaseAPI.Logger.error('getSports err1:');
      VTXBaseAPI.Logger.error(err1);

      retValue = buildErrorResponse<Sport[]>(err1);
    }

    return retValue;

  }

  public async getStates(): Promise<ITypedBackendResponse<State[]>> {


    const client = createClient({
      url: this.backendUrl + "/graphql",
      headers: this.headers,
    });

    //VTXBaseAPI.Logger.debug('HEADERS:');
    //VTXBaseAPI.Logger.debug(JSON.stringify(this.headers, null, 2));

    const fields: StateGenqlSelection = {
      _id: true,
      name: true,
      country: {
        _id: true,
        name: true
      }
    };




    let retValue: ITypedBackendResponse<State[]>;

    try {

      const response: any = await client.query({
        getStates: {
          __args: {
          },
          ...fields
        }
      });

      VTXBaseAPI.Logger.debug('getStates Response:');
      VTXBaseAPI.Logger.debug(JSON.stringify(response, null, 2));


      retValue = buildResponse<State[]>(response, 'getStates',
        (r: any) => {
          VTXBaseAPI.Logger.debug(JSON.stringify(response, null, 2));
          const isResponseOk: boolean = true && Array.isArray(response?.getStates)
          return isResponseOk
        }
      );

    } catch (err1) {
      VTXBaseAPI.Logger.error('getStates err1:');
      VTXBaseAPI.Logger.error(err1);

      retValue = buildErrorResponse<State[]>(err1);
    }
    return retValue;

  }

  public async getCountries(): Promise<ITypedBackendResponse<Country[]>> {


    const client = createClient({
      url: this.backendUrl + "/graphql",
      headers: this.headers,
    });
    let retValue: ITypedBackendResponse<Country[]>;

    const fields: CountryGenqlSelection = {
      _id: true,
      name: true,
    };

    try {
      const response: any = await client.query({
        getCountries: {
          __args: {
          },
          ...fields
        }
      });

      VTXBaseAPI.Logger.debug('getCountries Response:');
      VTXBaseAPI.Logger.debug(JSON.stringify(response, null, 2));

      retValue = buildResponse<Country[]>(response, 'getCountries',
        (r: any) => {
          VTXBaseAPI.Logger.debug(JSON.stringify(response, null, 2));
          const isResponseOk: boolean = true && Array.isArray(response?.getCountries)
          return isResponseOk
        }
      );

    } catch (err1) {
      VTXBaseAPI.Logger.error('getCountries err1:');
      VTXBaseAPI.Logger.error(err1);

      retValue = buildErrorResponse<Country[]>(err1);
    }

    return retValue;

  }


  public async loginUserFromCredentialsVtx(
    username: string,
    password: string
  ): Promise<ITypedBackendResponse<UserWithToken>> {

    const client = createClient({
      url: this.backendUrl + '/graphql',
      headers: this.headers,
    });

    const curatedEmail: string = username.trim().toLocaleLowerCase();

    let retValue: ITypedBackendResponse<UserWithToken> = {};

    const fields: UserWithTokenGenqlSelection = {
      _id: true,
      loginEmail: true,
      suspended: true,
      domains: {
        _id: true,
        name: true,
        description: true,
        tenant: {
          _id: true,
          name: true,
          tenant_uri: true,
          domain: {
            _id: true,
            name: true,
            description: true
          }
        }
      },
      loginMethods: true,
      token: {
        actualToken: true,
        refreshToken: true
      }
    }



    try {
      const response: any = await client.mutation({
        loginUserFromCredentialsVtx: {
          __args: {
            username: curatedEmail,
            password: password
          },
          ...fields
        },
      });

      VTXBaseAPI.Logger.debug('loginUserFromCredentialsVtx Response:');
      VTXBaseAPI.Logger.debug(JSON.stringify(response, null, 2));

      retValue = buildResponse<UserWithToken>(response, 'loginUserFromCredentialsVtx',
        (r: any) => {
          const isResponseOk: boolean = true && response?.loginUserFromCredentialsVtx?.actualToken;
          return isResponseOk
        }
      );

    } catch (err1) {
      VTXBaseAPI.Logger.error('loginUserFromCredentialsVtx err1:');
      VTXBaseAPI.Logger.error(err1);

      retValue = buildErrorResponse<UserWithToken>(err1);
    }

    return retValue;
  }

  public async validateUserCredentialsVtx(
    username: string,
    password: string
  ): Promise<ITypedBackendResponse<User>> {

    const client = createClient({
      url: this.backendUrl + '/graphql',
      headers: this.headers,
    });

    const curatedEmail: string = username.trim().toLocaleLowerCase();

    let retValue: ITypedBackendResponse<User> = {};

    const fields: UserGenqlSelection = {
      _id: true,
      loginEmail: true,
      suspended: true,
      domains: {
        _id: true,
        name: true,
        description: true,
        tenant: {
          _id: true,
          name: true,
          tenant_uri: true,
          domain: {
            _id: true,
            name: true,
            description: true
          }
        }
      },
      loginMethods: true
    }

    try {
      const response: any = await client.query({
        validateUserCredentials: {
          __args: {
            username: curatedEmail,
            password: password
          },
          ...fields
        },
      });

      VTXBaseAPI.Logger.debug('validateUserCredentials Response:');
      VTXBaseAPI.Logger.debug(JSON.stringify(response, null, 2));

      retValue = buildResponse<User>(response, 'validateUserCredentials',
        (r: any) => {
          const isResponseOk: boolean = true && response?.validateUserCredentials?._id;
          return isResponseOk
        }
      );

    } catch (err1) {
      VTXBaseAPI.Logger.error('validateUserCredentials err1:');
      VTXBaseAPI.Logger.error(err1);

      retValue = buildErrorResponse<User>(err1);
    }

    return retValue;
  }

  public async findAthleteForUser(loginEmail: string): Promise<ITypedBackendResponse<Athlete>> {

    const client = createClient({
      url: this.backendUrl + "/graphql",
      headers: this.headers,
    });

    let retValue: ITypedBackendResponse<Athlete> = {};

    const fields: AthleteGenqlSelection = {
      _id: true,
      firstName: true,
      lastName: true,
      screenName: true,
      dob: true,
      lgbt: true,
      competitionGender: true,
      country: {
        _id: true,
        name: true
      },
      location: {
        userProvidedLatitude: true,
        userProvidedLongitude: true,
        cityNameGeocode: true,
        stateNameGeocode: true,
        countryIso2CodeGeocode: true,
        timeZoneGeocode: true,
        latitudeGeocode: true,
        longitudeGeocode: true,
        city: {
          _id: true,
          name: true,
          localizedName: true,
          state: {
            _id: true,
            name: true,
            country: {
              _id: true,
              name: true
            }
          },
          latitude: true,
          longitude: true,
          timezone: true,
        }
      },
      trainer: true,
      trainerUrl: true,
      aboutMe: true,
      followStats: {
        followers: true,
        followed: true,
        raves: true,
        favorites: true
      },
      mainSport: {
        _id: true,
        name: true
      },
      mainSportLevel: {
        _id: true,
        label: true,
        index: true
      },
      scores: {
        vtxScore: true,
        socialScore: true,
        trainingScore: true,
        competitionScore: true
      },
      rankings: {
        worldRanking: {
          scope: true,
          scopeId: true,
          scopeName: true,
          position: true,
          total: true
        },
        countryRanking: {
          scope: true,
          scopeId: true,
          scopeName: true,
          position: true,
          total: true
        },
        stateRanking: {
          scope: true,
          scopeId: true,
          scopeName: true,
          position: true,
          total: true
        },
        cityRanking: {
          scope: true,
          scopeId: true,
          scopeName: true,
          position: true,
          total: true
        },
      },
      allSports: {
        _id: true,
        name: true
      },
      teams: {
        _id: true,
        name: true,
        description: true,
        //        sports: {
        //          _id: true,
        //          name: true
        //        },
        approved: true,
        logo: {
          _id: true,
          name: true,
          contentType: true,
          size: true,
          useType: true,
          url: true,
          key: true
        },
        banner: {
          _id: true,
          name: true,
          contentType: true,
          size: true,
          useType: true,
          url: true,
          key: true
        }

      },
      sponsorBrands: {
        _id: true,
        name: true,
        slogan: true,
        website: true,
        description: true,
        approved: true,
        published: true,
        logo: {
          _id: true,
          name: true,
          contentType: true,
          size: true,
          useType: true,
          url: true,
          key: true
        },
        //banner?: AWSS3FileGenqlSelection,
        stats: {
          campaigns: true,
          sponsorships: true,
          sports: true,
          athletes: true
        },
        operatorIds: true,

      },
      competitions: {
        _id: true,
        event: {
          _id: true,
          name: true,
          mainSport: {
            _id: true,
            name: true
          },
          eventWebSite: true,
          startDate: true,
          endDate: true,
          verified: true,
          location: {
            _id: true,
            userProvidedLatitude: true,
            userProvidedLongitude: true,
            cityNameGeocode: true,
            stateNameGeocode: true,
            countryIso2CodeGeocode: true,
            timeZoneGeocode: true,
            latitudeGeocode: true,
            longitudeGeocode: true,
            city: {
              _id: true,
              name: true,
              localizedName: true,
              state: {
                _id: true,
                name: true,
                country: {
                  _id: true,
                  name: true
                }
              },
              latitude: true,
              longitude: true,
              timezone: true,
            }
          },
          banner: {
            _id: true,
            name: true,
            contentType: true,
            size: true,
            useType: true,
            url: true,
            key: true
          }
        },
        participationDate: true,
        result: {
          _id: true,
          resultType: true,
          position: true,
          score: true,
          finishTimeMS: true,
          resultWebLink: true
        }
      },
      affiliations: {
        _id: true,
        organization: {
          _id: true,
          shortName: true,
          acronym: true,
          fullName: true,
          website: true,
          logo: {
            _id: true,
            name: true,
            contentType: true,
            size: true,
            useType: true,
            url: true,
            key: true
          }
        },
        membershipNumber: true,
        membershipType: true,
        issueDate: true,
        expirationDate: true,
      },
      totalUpcomingCompetitions: true,
      totalPastCompetitions: true,
      profilePicture: {
        _id: true,
        name: true,
        contentType: true,
        size: true,
        useType: true,
        url: true,
        key: true
      },
      cardPicture: {
        _id: true,
        name: true,
        contentType: true,
        size: true,
        useType: true,
        url: true,
        key: true
      },
      bannerPicture: {
        _id: true,
        name: true,
        contentType: true,
        size: true,
        useType: true,
        url: true,
        key: true
      },
      preferences: {
        _id: true,
        showProfileHelper: true,
        defaultAlbum: {
          _id: true,
          label: true,
          description: true,
        }
      },
      currentCampaign: {
        _id: true,
        budgetMode: true,
        status: true,
        title: true,
        motivation: true,
        website: true,
        fundsRequired: true,
        initialFundsObtained: true,
        fundsObtained: true,
        location: {
          _id: true,
          userProvidedLatitude: true,
          userProvidedLongitude: true,
          cityNameGeocode: true,
          stateNameGeocode: true,
          countryIso2CodeGeocode: true,
          timeZoneGeocode: true,
          latitudeGeocode: true,
          longitudeGeocode: true,
          city: {
            _id: true,
            name: true,
            localizedName: true,
            state: {
              _id: true,
              name: true,
              country: {
                _id: true,
                name: true
              }
            },
            latitude: true,
            longitude: true,
            timezone: true,
          }
        },
        endingDate: true,
        budget: {
          _id: true,
          initialFunds: true,
          totalRequired: true,
          items: {
            _id: true,
            quantity: true,
            concept: true,
            itemCost: true
          }
        },
        competitions: {
          _id: true,
          event: {
            _id: true,
            name: true,
            mainSport: {
              _id: true,
              name: true
            },
            eventWebSite: true,
            startDate: true,
            endDate: true,
            verified: true,
            banner: {
              _id: true,
              name: true,
              contentType: true,
              size: true,
              useType: true,
              url: true,
              key: true
            },
            location: {
              _id: true,
              userProvidedLatitude: true,
              userProvidedLongitude: true,
              cityNameGeocode: true,
              stateNameGeocode: true,
              countryIso2CodeGeocode: true,
              timeZoneGeocode: true,
              latitudeGeocode: true,
              longitudeGeocode: true,
              city: {
                _id: true,
                name: true,
                localizedName: true,
                state: {
                  _id: true,
                  name: true,
                  country: {
                    _id: true,
                    name: true
                  }
                },
                latitude: true,
                longitude: true,
                timezone: true,
              }
            },
          },
          participationDate: true,
          result: {
            _id: true,
            resultType: true,
            position: true,
            score: true,
            finishTimeMS: true,
            resultWebLink: true
          }
        }
      },
      stripeAccountReference: {
        _id: true,
        stripeAccountId: true,
        account: {
          id: true,
          object: true,
          business_type: true,
          country: true,
          email: true,
          capabilities: {
            acss_debit_payments: true,
            affirm_payments: true,
            afterpay_clearpay_payments: true,
            alma_payments: true,
            amazon_pay_payments: true,
            au_becs_debit_payments: true,
            bacs_debit_payments: true,
            bancontact_payments: true,
            bank_transfer_payments: true,
            blik_payments: true,
            boleto_payments: true,
            card_issuing: true,
            card_payments: true,
            cartes_bancaires_payments: true,
            cashapp_payments: true,
            eps_payments: true,
            fpx_payments: true,
            gb_bank_transfer_payments: true,
            giropay_payments: true,
            grabpay_payments: true,
            ideal_payments: true,
            india_international_payments: true,
            jcb_payments: true,
            jp_bank_transfer_payments: true,
            kakao_pay_payments: true,
            klarna_payments: true,
            konbini_payments: true,
            kr_card_payments: true,
            legacy_payments: true,
            link_payments: true,
            mobilepay_payments: true,
            multibanco_payments: true,
            mx_bank_transfer_payments: true,
            naver_pay_payments: true,
            oxxo_payments: true,
            p24_payments: true,
            pay_by_bank_payments: true,
            payco_payments: true,
            paynow_payments: true,
            promptpay_payments: true,
            revolut_pay_payments: true,
            samsung_pay_payments: true,
            sepa_bank_transfer_payments: true,
            sepa_debit_payments: true,
            sofort_payments: true,
            swish_payments: true,
            tax_reporting_us_1099_k: true,
            tax_reporting_us_1099_misc: true,
            transfers: true,
            treasury: true,
            twint_payments: true,
            us_bank_account_ach_payments: true,
            us_bank_transfer_payments: true,
            zip_payments: true

          },
          requirements: {
            alternatives: {
              alternative_fields_due: true,
              original_fields_due: true
            },
            current_deadline: true,
            currently_due: true,
            disabled_reason: true,
            errors: {
              code: true,
              reason: true,
              requirement: true
            },
            eventually_due: true,
            past_due: true,
            pending_verification: true
          },
          future_requirements: {
            alternatives: {
              alternative_fields_due: true,
              original_fields_due: true
            },
            current_deadline: true,
            currently_due: true,
            disabled_reason: true,
            errors: {
              code: true,
              reason: true,
              requirement: true
            },
            eventually_due: true,
            past_due: true,
            pending_verification: true
          },
          type: true,
          charges_enabled: true,
          payouts_enabled: true,
          created: true,
          default_currency: true

        }
      }
    };

    try {

      let response: any = null;

      response = await client.query({
        findAthleteForUser: {
          __args: {
            loginEmail: loginEmail
          },
          ...fields
        }
      });



      VTXBaseAPI.Logger.debug('findAthleteForUser Response:');
      VTXBaseAPI.Logger.debug(JSON.stringify(response, null, 2));

      retValue = buildResponse<Athlete>(response, 'findAthleteForUser',
        (r: any) => {
          const isResponseOk: boolean = true && response?.findAthleteForUser?._id;
          return isResponseOk
        }
      );

    } catch (err1) {
      VTXBaseAPI.Logger.error('findAthleteForUser err1:');
      VTXBaseAPI.Logger.error(err1);

      retValue = buildErrorResponse<Athlete>(err1);
    }

    return retValue;
  }


  public async getBrands(): Promise<ITypedBackendResponse<Brand[]>> {

    const client = createClient({
      url: this.backendUrl + "/graphql",
      headers: this.headers,
    });

    //VTXBaseAPI.Logger.debug('HEADERS:');
    //VTXBaseAPI.Logger.debug(JSON.stringify(this.headers, null, 2));

    const fields: BrandGenqlSelection = {
      _id: true,
      name: true,
      slogan: true,
      website: true,
      description: true,
      approved: true,
      published: true,
      logo: {
        _id: true,
        name: true,
        contentType: true,
        size: true,
        useType: true,
        url: true,
        key: true
      },
      banner: {
        _id: true,
        name: true,
        contentType: true,
        size: true,
        useType: true,
        url: true,
        key: true
      },
      stats: {
        campaigns: true,
        sponsorships: true,
        sports: true,
        athletes: true
      },
      operatorIds: true
    };


    let retValue: ITypedBackendResponse<Brand[]>;

    try {
      const response: any = await client.query({
        brands: {
          __args: {},
          ...fields
        }
      });

      VTXBaseAPI.Logger.debug('brands Response:');
      VTXBaseAPI.Logger.debug(JSON.stringify(response, null, 2));

      retValue = buildResponse<Brand[]>(response, 'brands',
        (r: any) => {
          VTXBaseAPI.Logger.debug(JSON.stringify(response, null, 2));
          const isResponseOk: boolean = true && Array.isArray(response?.brands);
          return isResponseOk
        }
      );

    } catch (err1) {
      VTXBaseAPI.Logger.error('brands err1:');
      VTXBaseAPI.Logger.error(err1);

      retValue = buildErrorResponse<Brand[]>(err1);
    }

    return retValue;


  }

  public async getAthletes(): Promise<ITypedBackendResponse<Athlete[]>> {

    const client = createClient({
      url: this.backendUrl + "/graphql",
      headers: this.headers,
    });

    //VTXBaseAPI.Logger.debug('HEADERS:');
    //VTXBaseAPI.Logger.debug(JSON.stringify(this.headers, null, 2));

    const fields: AthleteGenqlSelection = {
      _id: true,
      firstName: true,
      lastName: true,
      screenName: true,
      dob: true,
      lgbt: true,
      competitionGender: true,
      country: {
        _id: true,
        name: true
      },
      location: {
        userProvidedLatitude: true,
        userProvidedLongitude: true,
        cityNameGeocode: true,
        stateNameGeocode: true,
        countryIso2CodeGeocode: true,
        timeZoneGeocode: true,
        latitudeGeocode: true,
        longitudeGeocode: true,
        city: {
          _id: true,
          name: true,
          localizedName: true,
          state: {
            _id: true,
            name: true,
            country: {
              _id: true,
              name: true
            }
          },
          latitude: true,
          longitude: true,
          timezone: true,
        }
      },
      trainer: true,
      trainerUrl: true,
      aboutMe: true,
      followStats: {
        followers: true,
        followed: true,
        raves: true,
        favorites: true
      },
      mainSport: {
        _id: true,
        name: true
      },
      mainSportLevel: {
        _id: true,
        label: true,
        index: true
      },
      scores: {
        vtxScore: true,
        socialScore: true,
        trainingScore: true,
        competitionScore: true
      },
      rankings: {
        worldRanking: {
          scope: true,
          scopeId: true,
          scopeName: true,
          position: true,
          total: true
        },
        countryRanking: {
          scope: true,
          scopeId: true,
          scopeName: true,
          position: true,
          total: true
        },
        stateRanking: {
          scope: true,
          scopeId: true,
          scopeName: true,
          position: true,
          total: true
        },
        cityRanking: {
          scope: true,
          scopeId: true,
          scopeName: true,
          position: true,
          total: true
        },
      },
      allSports: {
        _id: true,
        name: true
      },
      teams: {
        _id: true,
        name: true,
        description: true,
        //        sports: {
        //          _id: true,
        //          name: true
        //        },
        approved: true,
        logo: {
          _id: true,
          name: true,
          contentType: true,
          size: true,
          useType: true,
          url: true,
          key: true
        },
        banner: {
          _id: true,
          name: true,
          contentType: true,
          size: true,
          useType: true,
          url: true,
          key: true
        }

      },
      sponsorBrands: {
        _id: true,
        name: true,
        slogan: true,
        website: true,
        description: true,
        approved: true,
        published: true,
        logo: {
          _id: true,
          name: true,
          contentType: true,
          size: true,
          useType: true,
          url: true,
          key: true
        },
        //banner?: AWSS3FileGenqlSelection,
        stats: {
          campaigns: true,
          sponsorships: true,
          sports: true,
          athletes: true
        },
        operatorIds: true,

      },
      competitions: {
        _id: true,
        event: {
          _id: true,
          name: true,
          mainSport: {
            _id: true,
            name: true
          },
          eventWebSite: true,
          startDate: true,
          endDate: true,
          verified: true,
          banner: {
            _id: true,
            name: true,
            contentType: true,
            size: true,
            useType: true,
            url: true,
            key: true
          },
          location: {
            _id: true,
            userProvidedLatitude: true,
            userProvidedLongitude: true,
            cityNameGeocode: true,
            stateNameGeocode: true,
            countryIso2CodeGeocode: true,
            timeZoneGeocode: true,
            latitudeGeocode: true,
            longitudeGeocode: true,
            city: {
              _id: true,
              name: true,
              localizedName: true,
              state: {
                _id: true,
                name: true,
                country: {
                  _id: true,
                  name: true
                }
              },
              latitude: true,
              longitude: true,
              timezone: true,
            }
          },
        },
        participationDate: true,
        result: {
          _id: true,
          resultType: true,
          position: true,
          score: true,
          finishTimeMS: true,
          resultWebLink: true
        }
      },
      totalUpcomingCompetitions: true,
      totalPastCompetitions: true,
      profilePicture: {
        _id: true,
        name: true,
        contentType: true,
        size: true,
        useType: true,
        url: true,
        key: true
      },
      cardPicture: {
        _id: true,
        name: true,
        contentType: true,
        size: true,
        useType: true,
        url: true,
        key: true
      },
      preferences: {
        _id: true,
        showProfileHelper: true
      }
    };


    let retValue: ITypedBackendResponse<Athlete[]>;

    try {
      const response: any = await client.query({
        getAthletes: {
          __args: {},
          ...fields
        }
      });

      VTXBaseAPI.Logger.debug('getAthletes Response:');
      VTXBaseAPI.Logger.debug(JSON.stringify(response, null, 2));

      retValue = buildResponse<Athlete[]>(response, 'getAthletes',
        (r: any) => {
          VTXBaseAPI.Logger.debug(JSON.stringify(response, null, 2));
          const isResponseOk: boolean = true && Array.isArray(response?.getAthletes);
          return isResponseOk
        }
      );

    } catch (err1) {
      VTXBaseAPI.Logger.error('getAthletes err1:');
      VTXBaseAPI.Logger.error(err1);

      retValue = buildErrorResponse<Athlete[]>(err1);
    }

    return retValue;


  }

  public async searchAthletes(searchString: string): Promise<ITypedBackendResponse<Athlete[]>> {

    const client = createClient({
      url: this.backendUrl + "/graphql",
      headers: this.headers,
    });

    //VTXBaseAPI.Logger.debug('HEADERS:');
    //VTXBaseAPI.Logger.debug(JSON.stringify(this.headers, null, 2));

    const fields: AthleteGenqlSelection = {
      _id: true,
      firstName: true,
      lastName: true,
      screenName: true,
      dob: true,
      lgbt: true,
      competitionGender: true,
      country: {
        _id: true,
        name: true
      },
      location: {
        userProvidedLatitude: true,
        userProvidedLongitude: true,
        cityNameGeocode: true,
        stateNameGeocode: true,
        countryIso2CodeGeocode: true,
        timeZoneGeocode: true,
        latitudeGeocode: true,
        longitudeGeocode: true,
        city: {
          _id: true,
          name: true,
          localizedName: true,
          state: {
            _id: true,
            name: true,
            country: {
              _id: true,
              name: true
            }
          },
          latitude: true,
          longitude: true,
          timezone: true,
        }
      },
      trainer: true,
      trainerUrl: true,
      aboutMe: true,
      followStats: {
        followers: true,
        followed: true,
        raves: true,
        favorites: true
      },
      mainSport: {
        _id: true,
        name: true
      },
      mainSportLevel: {
        _id: true,
        label: true,
        index: true
      },
      scores: {
        vtxScore: true,
        socialScore: true,
        trainingScore: true,
        competitionScore: true
      },
      rankings: {
        worldRanking: {
          scope: true,
          scopeId: true,
          scopeName: true,
          position: true,
          total: true
        },
        countryRanking: {
          scope: true,
          scopeId: true,
          scopeName: true,
          position: true,
          total: true
        },
        stateRanking: {
          scope: true,
          scopeId: true,
          scopeName: true,
          position: true,
          total: true
        },
        cityRanking: {
          scope: true,
          scopeId: true,
          scopeName: true,
          position: true,
          total: true
        },
      },
      allSports: {
        _id: true,
        name: true
      },
      teams: {
        _id: true,
        name: true,
        description: true,
        //        sports: {
        //          _id: true,
        //          name: true
        //        },
        approved: true,
        logo: {
          _id: true,
          name: true,
          contentType: true,
          size: true,
          useType: true,
          url: true,
          key: true
        },
        banner: {
          _id: true,
          name: true,
          contentType: true,
          size: true,
          useType: true,
          url: true,
          key: true
        }

      },
      sponsorBrands: {
        _id: true,
        name: true,
        slogan: true,
        website: true,
        description: true,
        approved: true,
        published: true,
        logo: {
          _id: true,
          name: true,
          contentType: true,
          size: true,
          useType: true,
          url: true,
          key: true
        },
        //banner?: AWSS3FileGenqlSelection,
        stats: {
          campaigns: true,
          sponsorships: true,
          sports: true,
          athletes: true
        },
        operatorIds: true,

      },
      competitions: {
        _id: true,
        event: {
          _id: true,
          name: true,
          mainSport: {
            _id: true,
            name: true
          },
          eventWebSite: true,
          startDate: true,
          endDate: true,
          verified: true,
          banner: {
            _id: true,
            name: true,
            contentType: true,
            size: true,
            useType: true,
            url: true,
            key: true
          },
          location: {
            _id: true,
            userProvidedLatitude: true,
            userProvidedLongitude: true,
            cityNameGeocode: true,
            stateNameGeocode: true,
            countryIso2CodeGeocode: true,
            timeZoneGeocode: true,
            latitudeGeocode: true,
            longitudeGeocode: true,
            city: {
              _id: true,
              name: true,
              localizedName: true,
              state: {
                _id: true,
                name: true,
                country: {
                  _id: true,
                  name: true
                }
              },
              latitude: true,
              longitude: true,
              timezone: true,
            }
          },
        },
        participationDate: true,
        result: {
          _id: true,
          resultType: true,
          position: true,
          score: true,
          finishTimeMS: true,
          resultWebLink: true
        }
      },
      totalUpcomingCompetitions: true,
      totalPastCompetitions: true,
      profilePicture: {
        _id: true,
        name: true,
        contentType: true,
        size: true,
        useType: true,
        url: true,
        key: true
      },
      cardPicture: {
        _id: true,
        name: true,
        contentType: true,
        size: true,
        useType: true,
        url: true,
        key: true
      },
      preferences: {
        _id: true,
        showProfileHelper: true
      }
    };


    let retValue: ITypedBackendResponse<Athlete[]>;

    try {
      const response: any = await client.query({
        searchAthletes: {
          __args: {
            searchString: searchString
          },
          ...fields
        }
      });

      VTXBaseAPI.Logger.debug('searchAthletes Response:');
      VTXBaseAPI.Logger.debug(JSON.stringify(response, null, 2));

      retValue = buildResponse<Athlete[]>(response, 'searchAthletes',
        (r: any) => {
          VTXBaseAPI.Logger.debug(JSON.stringify(response, null, 2));
          const isResponseOk: boolean = true && Array.isArray(response?.searchAthletes);
          return isResponseOk
        }
      );

    } catch (err1) {
      VTXBaseAPI.Logger.error('searchAthletes err1:');
      VTXBaseAPI.Logger.error(err1);

      retValue = buildErrorResponse<Athlete[]>(err1);
    }

    return retValue;


  }

  public async getRecommendedAthletes(loginEmail: string): Promise<ITypedBackendResponse<Athlete[]>> {

    const client = createClient({
      url: this.backendUrl + "/graphql",
      headers: this.headers,
    });

    //VTXBaseAPI.Logger.debug('HEADERS:');
    //VTXBaseAPI.Logger.debug(JSON.stringify(this.headers, null, 2));

    const fields: AthleteGenqlSelection = {
      _id: true,
      firstName: true,
      lastName: true,
      screenName: true,
      dob: true,
      lgbt: true,
      competitionGender: true,
      country: {
        _id: true,
        name: true
      },
      location: {
        userProvidedLatitude: true,
        userProvidedLongitude: true,
        cityNameGeocode: true,
        stateNameGeocode: true,
        countryIso2CodeGeocode: true,
        timeZoneGeocode: true,
        latitudeGeocode: true,
        longitudeGeocode: true,
        city: {
          _id: true,
          name: true,
          localizedName: true,
          state: {
            _id: true,
            name: true,
            country: {
              _id: true,
              name: true
            }
          },
          latitude: true,
          longitude: true,
          timezone: true,
        }
      },
      trainer: true,
      trainerUrl: true,
      aboutMe: true,
      followStats: {
        followers: true,
        followed: true,
        raves: true,
        favorites: true
      },
      mainSport: {
        _id: true,
        name: true
      },
      mainSportLevel: {
        _id: true,
        label: true,
        index: true
      },
      scores: {
        vtxScore: true,
        socialScore: true,
        trainingScore: true,
        competitionScore: true
      },
      rankings: {
        worldRanking: {
          scope: true,
          scopeId: true,
          scopeName: true,
          position: true,
          total: true
        },
        countryRanking: {
          scope: true,
          scopeId: true,
          scopeName: true,
          position: true,
          total: true
        },
        stateRanking: {
          scope: true,
          scopeId: true,
          scopeName: true,
          position: true,
          total: true
        },
        cityRanking: {
          scope: true,
          scopeId: true,
          scopeName: true,
          position: true,
          total: true
        },
      },
      allSports: {
        _id: true,
        name: true
      },
      teams: {
        _id: true,
        name: true,
        description: true,
        //        sports: {
        //          _id: true,
        //          name: true
        //        },
        approved: true,
        logo: {
          _id: true,
          name: true,
          contentType: true,
          size: true,
          useType: true,
          url: true,
          key: true
        },
        banner: {
          _id: true,
          name: true,
          contentType: true,
          size: true,
          useType: true,
          url: true,
          key: true
        }

      },
      sponsorBrands: {
        _id: true,
        name: true,
        slogan: true,
        website: true,
        description: true,
        approved: true,
        published: true,
        logo: {
          _id: true,
          name: true,
          contentType: true,
          size: true,
          useType: true,
          url: true,
          key: true
        },
        //banner?: AWSS3FileGenqlSelection,
        stats: {
          campaigns: true,
          sponsorships: true,
          sports: true,
          athletes: true
        },
        operatorIds: true,

      },
      competitions: {
        _id: true,
        event: {
          _id: true,
          name: true,
          mainSport: {
            _id: true,
            name: true
          },
          eventWebSite: true,
          startDate: true,
          endDate: true,
          verified: true,
          banner: {
            _id: true,
            name: true,
            contentType: true,
            size: true,
            useType: true,
            url: true,
            key: true
          },
          location: {
            _id: true,
            userProvidedLatitude: true,
            userProvidedLongitude: true,
            cityNameGeocode: true,
            stateNameGeocode: true,
            countryIso2CodeGeocode: true,
            timeZoneGeocode: true,
            latitudeGeocode: true,
            longitudeGeocode: true,
            city: {
              _id: true,
              name: true,
              localizedName: true,
              state: {
                _id: true,
                name: true,
                country: {
                  _id: true,
                  name: true
                }
              },
              latitude: true,
              longitude: true,
              timezone: true,
            }
          },
        },
        participationDate: true,
        result: {
          _id: true,
          resultType: true,
          position: true,
          score: true,
          finishTimeMS: true,
          resultWebLink: true
        }
      },
      totalUpcomingCompetitions: true,
      totalPastCompetitions: true,
      profilePicture: {
        _id: true,
        name: true,
        contentType: true,
        size: true,
        useType: true,
        url: true,
        key: true
      },
      cardPicture: {
        _id: true,
        name: true,
        contentType: true,
        size: true,
        useType: true,
        url: true,
        key: true
      },
      preferences: {
        _id: true,
        showProfileHelper: true
      }
    };


    let retValue: ITypedBackendResponse<Athlete[]>;

    try {
      const response: any = await client.query({
        getRecommendedAthletes: {
          __args: {
            loginEmail: loginEmail
          },
          ...fields
        }
      });

      VTXBaseAPI.Logger.debug('getRecommendedAthletes Response:');
      VTXBaseAPI.Logger.debug(JSON.stringify(response, null, 2));

      retValue = buildResponse<Athlete[]>(response, 'getRecommendedAthletes',
        (r: any) => {
          VTXBaseAPI.Logger.debug(JSON.stringify(response, null, 2));
          const isResponseOk: boolean = true && Array.isArray(response?.getRecommendedAthletes);
          return isResponseOk
        }
      );

    } catch (err1) {
      VTXBaseAPI.Logger.error('getRecommendedAthletes err1:');
      VTXBaseAPI.Logger.error(err1);

      retValue = buildErrorResponse<Athlete[]>(err1);
    }

    return retValue;


  }


  public async getSponsorAthletesForTenant(): Promise<ITypedBackendResponse<Athlete[]>> {

    const client = createClient({
      url: this.backendUrl + "/graphql",
      headers: this.headers,
    });

    //VTXBaseAPI.Logger.debug('HEADERS:');
    //VTXBaseAPI.Logger.debug(JSON.stringify(this.headers, null, 2));

    const fields: AthleteGenqlSelection = {
      _id: true,
      firstName: true,
      lastName: true,
      screenName: true,
      dob: true,
      lgbt: true,
      competitionGender: true,
      country: {
        _id: true,
        name: true
      },
      location: {
        userProvidedLatitude: true,
        userProvidedLongitude: true,
        cityNameGeocode: true,
        stateNameGeocode: true,
        countryIso2CodeGeocode: true,
        timeZoneGeocode: true,
        latitudeGeocode: true,
        longitudeGeocode: true,
        city: {
          _id: true,
          name: true,
          localizedName: true,
          state: {
            _id: true,
            name: true,
            country: {
              _id: true,
              name: true
            }
          },
          latitude: true,
          longitude: true,
          timezone: true,
        }
      },
      trainer: true,
      trainerUrl: true,
      aboutMe: true,
      followStats: {
        followers: true,
        followed: true,
        raves: true,
        favorites: true
      },
      mainSport: {
        _id: true,
        name: true
      },
      mainSportLevel: {
        _id: true,
        label: true,
        index: true
      },
      scores: {
        vtxScore: true,
        socialScore: true,
        trainingScore: true,
        competitionScore: true
      },
      rankings: {
        worldRanking: {
          scope: true,
          scopeId: true,
          scopeName: true,
          position: true,
          total: true
        },
        countryRanking: {
          scope: true,
          scopeId: true,
          scopeName: true,
          position: true,
          total: true
        },
        stateRanking: {
          scope: true,
          scopeId: true,
          scopeName: true,
          position: true,
          total: true
        },
        cityRanking: {
          scope: true,
          scopeId: true,
          scopeName: true,
          position: true,
          total: true
        },
      },
      allSports: {
        _id: true,
        name: true
      },
      teams: {
        _id: true,
        name: true,
        description: true,
        //        sports: {
        //          _id: true,
        //          name: true
        //        },
        approved: true,
        logo: {
          _id: true,
          name: true,
          contentType: true,
          size: true,
          useType: true,
          url: true,
          key: true
        },
        banner: {
          _id: true,
          name: true,
          contentType: true,
          size: true,
          useType: true,
          url: true,
          key: true
        }

      },
      sponsorBrands: {
        _id: true,
        name: true,
        slogan: true,
        website: true,
        description: true,
        approved: true,
        published: true,
        logo: {
          _id: true,
          name: true,
          contentType: true,
          size: true,
          useType: true,
          url: true,
          key: true
        },
        //banner?: AWSS3FileGenqlSelection,
        stats: {
          campaigns: true,
          sponsorships: true,
          sports: true,
          athletes: true
        },
        operatorIds: true,

      },
      competitions: {
        _id: true,
        event: {
          _id: true,
          name: true,
          mainSport: {
            _id: true,
            name: true
          },
          eventWebSite: true,
          startDate: true,
          endDate: true,
          verified: true,
          banner: {
            _id: true,
            name: true,
            contentType: true,
            size: true,
            useType: true,
            url: true,
            key: true
          },
          location: {
            _id: true,
            userProvidedLatitude: true,
            userProvidedLongitude: true,
            cityNameGeocode: true,
            stateNameGeocode: true,
            countryIso2CodeGeocode: true,
            timeZoneGeocode: true,
            latitudeGeocode: true,
            longitudeGeocode: true,
            city: {
              _id: true,
              name: true,
              localizedName: true,
              state: {
                _id: true,
                name: true,
                country: {
                  _id: true,
                  name: true
                }
              },
              latitude: true,
              longitude: true,
              timezone: true,
            }
          },
        },
        participationDate: true,
        result: {
          _id: true,
          resultType: true,
          position: true,
          score: true,
          finishTimeMS: true,
          resultWebLink: true
        }
      },
      totalUpcomingCompetitions: true,
      totalPastCompetitions: true,
      profilePicture: {
        _id: true,
        name: true,
        contentType: true,
        size: true,
        useType: true,
        url: true,
        key: true
      },
      cardPicture: {
        _id: true,
        name: true,
        contentType: true,
        size: true,
        useType: true,
        url: true,
        key: true
      },
      preferences: {
        _id: true,
        showProfileHelper: true
      }
    };


    let retValue: ITypedBackendResponse<Athlete[]>;

    try {
      const response: any = await client.query({
        getSponsorAthletesForTenant: {
          __args: {},
          ...fields
        }
      });

      VTXBaseAPI.Logger.debug('getSponsorAthletesForTenant Response:');
      VTXBaseAPI.Logger.debug(JSON.stringify(response, null, 2));

      retValue = buildResponse<Athlete[]>(response, 'getSponsorAthletesForTenant',
        (r: any) => {
          VTXBaseAPI.Logger.debug(JSON.stringify(response, null, 2));
          const isResponseOk: boolean = true && Array.isArray(response?.getSponsorAthletesForTenant);
          return isResponseOk
        }
      );

    } catch (err1) {
      VTXBaseAPI.Logger.error('getSponsorAthletesForTenant err1:');
      VTXBaseAPI.Logger.error(err1);

      retValue = buildErrorResponse<Athlete[]>(err1);
    }

    return retValue;


  }



  public async getUserImagesFromEmail(loginEmail: string): Promise<ITypedBackendResponse<UserImages>> {

    const client = createClient({
      url: this.backendUrl + "/graphql",
      headers: this.headers,
    });

    //VTXBaseAPI.Logger.debug('HEADERS:');
    //VTXBaseAPI.Logger.debug(JSON.stringify(this.headers, null, 2));

    const fields: UserImagesGenqlSelection = {
      profilePictureUrl: true,
      cardPictureUrl: true,
      bannerPictureUrl: true
    };


    let retValue: ITypedBackendResponse<UserImages>;

    try {
      const response: any = await client.query({
        getUserImagesFromEmail: {
          __args: {
            loginEmail: loginEmail
          },
          ...fields
        }
      });

      VTXBaseAPI.Logger.debug('getUserImagesFromEmail Response:');
      VTXBaseAPI.Logger.debug(JSON.stringify(response, null, 2));

      retValue = buildResponse<UserImages>(response, 'getUserImagesFromEmail',
        (r: any) => {
          VTXBaseAPI.Logger.debug(JSON.stringify(response, null, 2));
          const isResponseOk: boolean = true && response?.getUserImagesFromEmail;
          return isResponseOk
        }
      );

    } catch (err1) {
      VTXBaseAPI.Logger.error('getUserImagesFromEmail err1:');
      VTXBaseAPI.Logger.error(err1);

      retValue = buildErrorResponse<UserImages>(err1);
    }

    return retValue;


  }




  // This method can ONLY be called logged in and passing userToken in headers
  public async editAboutMe(
    newValue: string
  ): Promise<ITypedBackendResponse<EditValueResponse>> {

    console.log('HEADERS:');
    console.log(JSON.stringify(this.headers, null, 2));

    const client = createClient({
      url: this.backendUrl + '/graphql',
      headers: this.headers,
    });


    let retValue: ITypedBackendResponse<EditValueResponse> = {};

    const fields: EditValueResponseGenqlSelection = {
      field: true,
      oldValue: true,
      newValue: true,
      changed: true
    };

    const dto: EditValueDto = {
      field: 'aboutMe',
      newValue: newValue
    }

    try {
      const response: any = await client.mutation({
        editProfileValue: {
          __args: {
            input: dto
          },
          ...fields
        },
      });

      VTXBaseAPI.Logger.debug('editProfileValue Response:');
      VTXBaseAPI.Logger.debug(JSON.stringify(response, null, 2));

      retValue = buildResponse<EditValueResponse>(response, 'editProfileValue',
        (r: any) => {
          const isResponseOk: boolean = true && response?.editProfileValue?.field;
          return isResponseOk
        }
      );

    } catch (err1) {
      VTXBaseAPI.Logger.error('editProfileValue err1:');
      VTXBaseAPI.Logger.error(err1);

      retValue = buildErrorResponse<EditValueResponse>(err1);
    }

    return retValue;
  }

  // This method can ONLY be called logged in and passing userToken in headers
  public async editProfileValue(
    newValue: string,
    field: string
  ): Promise<ITypedBackendResponse<EditValueResponse>> {

    const client = createClient({
      url: this.backendUrl + '/graphql',
      headers: this.headers,
    });


    let retValue: ITypedBackendResponse<EditValueResponse> = {};

    const fields: EditValueResponseGenqlSelection = {
      field: true,
      oldValue: true,
      newValue: true,
      changed: true
    };

    const dto: EditValueDto = {
      field: field,
      newValue: newValue
    }

    try {
      const response: any = await client.mutation({
        editProfileValue: {
          __args: {
            input: dto
          },
          ...fields
        },
      });

      VTXBaseAPI.Logger.debug('editProfileValue Response:');
      VTXBaseAPI.Logger.debug(JSON.stringify(response, null, 2));

      retValue = buildResponse<EditValueResponse>(response, 'editProfileValue',
        (r: any) => {
          const isResponseOk: boolean = true && response?.editProfileValue?.field;
          return isResponseOk
        }
      );

    } catch (err1) {
      VTXBaseAPI.Logger.error('editProfileValue err1:');
      VTXBaseAPI.Logger.error(err1);

      retValue = buildErrorResponse<EditValueResponse>(err1);
    }

    return retValue;
  }

  public async addAthleteCompetition(
    dto: CreateAthleteCompetitionDto
  ): Promise<ITypedBackendResponse<AthleteCompetition>> {

    console.log('HEADERS:');
    console.log(JSON.stringify(this.headers, null, 2));

    const client = createClient({
      url: this.backendUrl + '/graphql',
      headers: this.headers,
    });


    let retValue: ITypedBackendResponse<AthleteCompetition> = {};

    const fields: AthleteCompetitionGenqlSelection = {
      _id: true,
      event: {
        _id: true,
        name: true,
        mainSport: {
          _id: true,
          name: true
        },
        eventWebSite: true,
        startDate: true,
        endDate: true,
        verified: true,
        banner: {
          _id: true,
          name: true,
          contentType: true,
          size: true,
          useType: true,
          url: true,
          key: true
        },
        location: {
          _id: true,
          userProvidedLatitude: true,
          userProvidedLongitude: true,
          cityNameGeocode: true,
          stateNameGeocode: true,
          countryIso2CodeGeocode: true,
          timeZoneGeocode: true,
          latitudeGeocode: true,
          longitudeGeocode: true,
          city: {
            _id: true,
            name: true,
            localizedName: true,
            state: {
              _id: true,
              name: true,
              country: {
                _id: true,
                name: true
              }
            },
            latitude: true,
            longitude: true,
            timezone: true,
          }
        },
      },
      participationDate: true,
      competitionNumber: true,
      result: {
        resultType: true,
        position: true,
        score: true,
        finishTimeMS: true,
        resultWebLink: true
      },
      fundRaisingCampaignIds: true
    };



    try {
      const response: any = await client.mutation({
        addAthleteCompetition: {
          __args: {
            input: dto
          },
          ...fields
        },
      });

      VTXBaseAPI.Logger.debug('addAthleteCompetition Response:');
      VTXBaseAPI.Logger.debug(JSON.stringify(response, null, 2));

      retValue = buildResponse<AthleteCompetition>(response, 'addAthleteCompetition',
        (r: any) => {
          const isResponseOk: boolean = true && response?.addAthleteCompetition?._id;
          return isResponseOk
        }
      );

    } catch (err1) {
      VTXBaseAPI.Logger.error('addAthleteCompetition err1:');
      VTXBaseAPI.Logger.error(err1);

      retValue = buildErrorResponse<AthleteCompetition>(err1);
    }

    return retValue;
  }


  public async getSportsEvents(dto: GetSportEventsDto): Promise<ITypedBackendResponse<SportsEvent[]>> {

    const client = createClient({
      url: this.backendUrl + "/graphql",
      headers: this.headers,
    });

    //VTXBaseAPI.Logger.debug('HEADERS:');
    //VTXBaseAPI.Logger.debug(JSON.stringify(this.headers, null, 2));

    const fields: SportsEventGenqlSelection = {
      _id: true,
      name: true,
      eventWebSite: true,
      mainSport: {
        _id: true,
        name: true
      },
      startDate: true,
      endDate: true,
      verified: true,
      banner: {
        _id: true,
        name: true,
        contentType: true,
        size: true,
        useType: true,
        url: true,
        key: true
      },
      location: {
        _id: true,
        userProvidedLatitude: true,
        userProvidedLongitude: true,
        cityNameGeocode: true,
        stateNameGeocode: true,
        countryIso2CodeGeocode: true,
        timeZoneGeocode: true,
        latitudeGeocode: true,
        longitudeGeocode: true,
        city: {
          _id: true,
          name: true,
          localizedName: true,
          state: {
            _id: true,
            name: true,
            country: {
              _id: true,
              name: true
            }
          },
          latitude: true,
          longitude: true,
          timezone: true,
        }
      }
    };


    let retValue: ITypedBackendResponse<SportsEvent[]>;

    try {
      const response: any = await client.query({
        getSportsEvents: {
          __args: {
            input: dto
          },
          ...fields
        }
      });

      VTXBaseAPI.Logger.debug('getSportsEvents Response:');
      VTXBaseAPI.Logger.debug(JSON.stringify(response, null, 2));

      retValue = buildResponse<SportsEvent[]>(response, 'getSportsEvents',
        (r: any) => {
          VTXBaseAPI.Logger.debug(JSON.stringify(response, null, 2));
          const isResponseOk: boolean = true && Array.isArray(response?.getSportsEvents);
          return isResponseOk
        }
      );

    } catch (err1) {
      VTXBaseAPI.Logger.error('getSportsEvents err1:');
      VTXBaseAPI.Logger.error(err1);

      retValue = buildErrorResponse<SportsEvent[]>(err1);
    }

    return retValue;


  }


  public async createSportsEvent(
    dto: CreateSportEventDto
  ): Promise<ITypedBackendResponse<SportsEvent>> {

    console.log('HEADERS:');
    console.log(JSON.stringify(this.headers, null, 2));

    const client = createClient({
      url: this.backendUrl + '/graphql',
      headers: this.headers,
    });


    let retValue: ITypedBackendResponse<SportsEvent> = {};

    const fields: SportsEventGenqlSelection = {
      _id: true,
      name: true,
      eventWebSite: true,
      mainSport: {
        _id: true,
        name: true
      },
      startDate: true,
      endDate: true,
      verified: true,
      banner: {
        _id: true,
        name: true,
        contentType: true,
        size: true,
        useType: true,
        url: true,
        key: true
      },
      location: {
        _id: true,
        userProvidedLatitude: true,
        userProvidedLongitude: true,
        cityNameGeocode: true,
        stateNameGeocode: true,
        countryIso2CodeGeocode: true,
        timeZoneGeocode: true,
        latitudeGeocode: true,
        longitudeGeocode: true,
        city: {
          _id: true,
          name: true,
          localizedName: true,
          state: {
            _id: true,
            name: true,
            country: {
              _id: true,
              name: true
            }
          },
          latitude: true,
          longitude: true,
          timezone: true,
        }
      }
    };



    try {
      const response: any = await client.mutation({
        createSportsEvent: {
          __args: {
            input: dto
          },
          ...fields
        },
      });

      VTXBaseAPI.Logger.debug('createSportsEvent Response:');
      VTXBaseAPI.Logger.debug(JSON.stringify(response, null, 2));

      retValue = buildResponse<SportsEvent>(response, 'createSportsEvent',
        (r: any) => {
          const isResponseOk: boolean = true && response?.createSportsEvent?._id;
          return isResponseOk
        }
      );

    } catch (err1) {
      VTXBaseAPI.Logger.error('createSportsEvent err1:');
      VTXBaseAPI.Logger.error(err1);

      retValue = buildErrorResponse<SportsEvent>(err1);
    }

    return retValue;
  }



  public async getAthleteCompetitions(dto: GetAthleteCompetitionsDto): Promise<ITypedBackendResponse<AthleteCompetition[]>> {

    const client = createClient({
      url: this.backendUrl + "/graphql",
      headers: this.headers,
    });

    //VTXBaseAPI.Logger.debug('HEADERS:');
    //VTXBaseAPI.Logger.debug(JSON.stringify(this.headers, null, 2));

    const fields: AthleteCompetitionGenqlSelection = {
      _id: true,
      event: {
        _id: true,
        name: true,
        mainSport: {
          _id: true,
          name: true,
          resultType: true,
        },
        eventWebSite: true,
        startDate: true,
        endDate: true,
        verified: true,
        banner: {
          _id: true,
          name: true,
          contentType: true,
          size: true,
          useType: true,
          url: true,
          key: true
        },
        location: {
          _id: true,
          userProvidedLatitude: true,
          userProvidedLongitude: true,
          cityNameGeocode: true,
          stateNameGeocode: true,
          countryIso2CodeGeocode: true,
          timeZoneGeocode: true,
          latitudeGeocode: true,
          longitudeGeocode: true,
          city: {
            _id: true,
            name: true,
            localizedName: true,
            state: {
              _id: true,
              name: true,
              country: {
                _id: true,
                name: true
              }
            },
            latitude: true,
            longitude: true,
            timezone: true,
          }
        },
      },
      participationDate: true,
      competitionNumber: true,
      result: {
        resultType: true,
        position: true,
        score: true,
        finishTimeMS: true,
        resultWebLink: true,
        outcome: true,
        totalParticipants: true,
        adversary: true,
        genderPosition: true,
        genderParticipants: true,
        categoryPosition: true,
        categoryParticipants: true,
        categoryName: true
      },
      fundRaisingCampaignIds: true,
      budget: {
        _id: true,
        totalRequired: true,
        initialFunds: true,
        items: {
          _id: true,
          quantity: true,
          concept: true,
          itemCost: true
        }
      }
    };


    let retValue: ITypedBackendResponse<AthleteCompetition[]>;

    try {
      const response: any = await client.query({
        getAthleteCompetitions: {
          __args: {
            input: dto
          },
          ...fields
        }
      });

      VTXBaseAPI.Logger.debug('getSportsEvents Response:');
      VTXBaseAPI.Logger.debug(JSON.stringify(response, null, 2));

      retValue = buildResponse<AthleteCompetition[]>(response, 'getAthleteCompetitions',
        (r: any) => {
          VTXBaseAPI.Logger.debug(JSON.stringify(response, null, 2));
          const isResponseOk: boolean = true && Array.isArray(response?.getAthleteCompetitions);
          return isResponseOk
        }
      );

    } catch (err1) {
      VTXBaseAPI.Logger.error('getAthleteCompetitions err1:');
      VTXBaseAPI.Logger.error(err1);

      retValue = buildErrorResponse<AthleteCompetition[]>(err1);
    }

    return retValue;


  }


  public async getAthleteMemberships(athleteId: string): Promise<ITypedBackendResponse<AthleteMembership[]>> {

    const client = createClient({
      url: this.backendUrl + "/graphql",
      headers: this.headers,
    });

    //VTXBaseAPI.Logger.debug('HEADERS:');
    //VTXBaseAPI.Logger.debug(JSON.stringify(this.headers, null, 2));

    const fields: AthleteMembershipGenqlSelection = {
      _id: true,
      organization: {
        _id: true,
        shortName: true,
        acronym: true,
        fullName: true,
        website: true,
        verified: true,
        logo: {
          _id: true,
          name: true,
          contentType: true,
          size: true,
          useType: true,
          url: true,
          key: true
        },
        country: {
          _id: true,
          name: true
        },
        sport: {
          _id: true,
          name: true
        }
      },
      athlete: {
        _id: true,
        firstName: true,
        lastName: true,
        screenName: true,
        dob: true,
        lgbt: true,
        competitionGender: true,
        country: {
          _id: true,
          name: true
        },
        location: {
          userProvidedLatitude: true,
          userProvidedLongitude: true,
          cityNameGeocode: true,
          stateNameGeocode: true,
          countryIso2CodeGeocode: true,
          timeZoneGeocode: true,
          latitudeGeocode: true,
          longitudeGeocode: true,
          city: {
            _id: true,
            name: true,
            localizedName: true,
            state: {
              _id: true,
              name: true,
              country: {
                _id: true,
                name: true
              }
            },
            latitude: true,
            longitude: true,
            timezone: true,
          }
        },
        trainer: true,
        trainerUrl: true,
        aboutMe: true,
        followStats: {
          followers: true,
          followed: true,
          raves: true,
          favorites: true
        },
        mainSport: {
          _id: true,
          name: true
        },
        mainSportLevel: {
          _id: true,
          label: true,
          index: true
        },
        scores: {
          vtxScore: true,
          socialScore: true,
          trainingScore: true,
          competitionScore: true
        },
        rankings: {
          worldRanking: {
            scope: true,
            scopeId: true,
            scopeName: true,
            position: true,
            total: true
          },
          countryRanking: {
            scope: true,
            scopeId: true,
            scopeName: true,
            position: true,
            total: true
          },
          stateRanking: {
            scope: true,
            scopeId: true,
            scopeName: true,
            position: true,
            total: true
          },
          cityRanking: {
            scope: true,
            scopeId: true,
            scopeName: true,
            position: true,
            total: true
          },
        },
        totalUpcomingCompetitions: true,
        totalPastCompetitions: true,
        profilePicture: {
          _id: true,
          name: true,
          contentType: true,
          size: true,
          useType: true,
          url: true,
          key: true
        },
        cardPicture: {
          _id: true,
          name: true,
          contentType: true,
          size: true,
          useType: true,
          url: true,
          key: true
        }

      },
      membershipNumber: true,
      membershipType: true,
      issueDate: true,
      expirationDate: true

    };


    let retValue: ITypedBackendResponse<AthleteMembership[]>;

    try {
      const response: any = await client.query({
        getAthleteMemberships: {
          __args: {
            athleteId: athleteId
          },
          ...fields
        }
      });

      VTXBaseAPI.Logger.debug('getAthleteMemberships Response:');
      VTXBaseAPI.Logger.debug(JSON.stringify(response, null, 2));

      retValue = buildResponse<AthleteMembership[]>(response, 'getAthleteMemberships',
        (r: any) => {
          VTXBaseAPI.Logger.debug(JSON.stringify(response, null, 2));
          const isResponseOk: boolean = true && Array.isArray(response?.getAthleteMemberships);
          return isResponseOk
        }
      );

    } catch (err1) {
      VTXBaseAPI.Logger.error('getAthleteMemberships err1:');
      VTXBaseAPI.Logger.error(err1);

      retValue = buildErrorResponse<AthleteMembership[]>(err1);
    }

    return retValue;


  }


  public async deleteAthleteCompetition(
    dto: DeleteSingleValueDto
  ): Promise<ITypedBackendResponse<DeleteSingleValueResponse>> {

    console.log('HEADERS:');
    console.log(JSON.stringify(this.headers, null, 2));

    const client = createClient({
      url: this.backendUrl + '/graphql',
      headers: this.headers,
    });


    let retValue: ITypedBackendResponse<DeleteSingleValueResponse> = {};

    const fields: DeleteSingleValueResponseGenqlSelection = {
      idToDelete: true,
      deleted: true,
      failureReason: {
        code: true,
        message: true
      }
    };

    try {
      const response: any = await client.mutation({
        deleteAthleteCompetition: {
          __args: {
            input: dto
          },
          ...fields
        },
      });

      VTXBaseAPI.Logger.debug('deleteAthleteCompetition Response:');
      VTXBaseAPI.Logger.debug(JSON.stringify(response, null, 2));

      retValue = buildResponse<DeleteSingleValueResponse>(response, 'deleteAthleteCompetition',
        (r: any) => {
          const isResponseOk: boolean = true && response?.deleteAthleteCompetition?.idToDelete;
          return isResponseOk
        }
      );

    } catch (err1) {
      VTXBaseAPI.Logger.error('deleteAthleteCompetition err1:');
      VTXBaseAPI.Logger.error(err1);

      retValue = buildErrorResponse<DeleteSingleValueResponse>(err1);
    }

    return retValue;
  }

  public async createFundingCampaign(
    dto: CreateFundingCampaignDto
  ): Promise<ITypedBackendResponse<FundRaisingCampaign>> {

    console.log('HEADERS:');
    console.log(JSON.stringify(this.headers, null, 2));

    const client = createClient({
      url: this.backendUrl + '/graphql',
      headers: this.headers,
    });


    let retValue: ITypedBackendResponse<FundRaisingCampaign> = {};

    const fields: FundRaisingCampaignGenqlSelection = {
      _id: true,
      budgetMode: true,
      status: true,
      title: true,
      motivation: true,
      website: true,
      fundsRequired: true,
      initialFundsObtained: true,
      fundsObtained: true,
      vtxComissionPct: true,
      location: {
        userProvidedLatitude: true,
        userProvidedLongitude: true,
        cityNameGeocode: true,
        stateNameGeocode: true,
        countryIso2CodeGeocode: true,
        timeZoneGeocode: true,
        latitudeGeocode: true,
        longitudeGeocode: true,
        city: {
          _id: true,
          name: true,
          localizedName: true,
          state: {
            _id: true,
            name: true,
            country: {
              _id: true,
              name: true
            }
          },
          latitude: true,
          longitude: true,
          timezone: true,
        }
      },
      endingDate: true,
      budget: {
        initialFunds: true,
        totalRequired: true,
        items: {
          _id: true,
          quantity: true,
          concept: true,
          itemCost: true
        }
      },
      competitions: {
        _id: true,
        event: {
          _id: true,
          name: true,
          mainSport: {
            _id: true,
            name: true
          },
          eventWebSite: true,
          startDate: true,
          endDate: true,
          verified: true,
          banner: {
            _id: true,
            name: true,
            contentType: true,
            size: true,
            useType: true,
            url: true,
            key: true
          },
          location: {
            _id: true,
            userProvidedLatitude: true,
            userProvidedLongitude: true,
            cityNameGeocode: true,
            stateNameGeocode: true,
            countryIso2CodeGeocode: true,
            timeZoneGeocode: true,
            latitudeGeocode: true,
            longitudeGeocode: true,
            city: {
              _id: true,
              name: true,
              localizedName: true,
              state: {
                _id: true,
                name: true,
                country: {
                  _id: true,
                  name: true
                }
              },
              latitude: true,
              longitude: true,
              timezone: true,
            }
          },
        },
        participationDate: true,
        competitionNumber: true,
        result: {
          resultType: true,
          position: true,
          score: true,
          finishTimeMS: true,
          resultWebLink: true
        },
        fundRaisingCampaignIds: true
      }
    };

    try {
      const response: any = await client.mutation({
        createFundingCampaign: {
          __args: {
            input: dto
          },
          ...fields
        },
      });

      VTXBaseAPI.Logger.log("==================HERE=====================================");
      VTXBaseAPI.Logger.log('createFundingCampaign Response:');
      VTXBaseAPI.Logger.log(JSON.stringify(response, null, 2));
      VTXBaseAPI.Logger.log("==================DONE=====================================");

      retValue = buildResponse<FundRaisingCampaign>(response, 'createFundingCampaign',
        (r: any) => {
          const isResponseOk: boolean = true && response?.createFundingCampaign?._id;
          return isResponseOk
        }
      );

    } catch (err1) {
      VTXBaseAPI.Logger.log("************** ERROR *******************************");
      VTXBaseAPI.Logger.log('createFundingCampaign err1:');
      VTXBaseAPI.Logger.log(err1);
      VTXBaseAPI.Logger.log("************** DONE ERROR **************************");

      retValue = buildErrorResponse<FundRaisingCampaign>(err1);
    }

    return retValue;
  }

  public async createMembershipOrganization(dto: CreateMembershipOrganizationDto, desiredFields?: MembershipOrganizationReferenceGenqlSelection): Promise<ITypedBackendResponse<MembershipOrganizationReference>> {

    const client = createClient({
      url: this.backendUrl + "/graphql",
      headers: this.headers,
    });

    //VTXBaseAPI.Logger.debug('HEADERS:');
    //VTXBaseAPI.Logger.debug(JSON.stringify(this.headers, null, 2));

    const fields: MembershipOrganizationReferenceGenqlSelection = desiredFields ?? { _id: true };


    let retValue: ITypedBackendResponse<MembershipOrganizationReference>;

    try {
      const response: any = await client.mutation({
        createMembershipOrganization: {
          __args: {
            input: dto
          },
          ...fields
        }
      });

      VTXBaseAPI.Logger.debug('createMembershipOrganization Response:');
      VTXBaseAPI.Logger.debug(JSON.stringify(response, null, 2));

      retValue = buildResponse<MembershipOrganizationReference>(response, 'createMembershipOrganization',
        (r: any) => {
          VTXBaseAPI.Logger.debug(JSON.stringify(response, null, 2));
          const isResponseOk: boolean = true && response?.createMembershipOrganization?._id;
          return isResponseOk
        }
      );

    } catch (err1) {
      VTXBaseAPI.Logger.error('createMembershipOrganization err1:');
      VTXBaseAPI.Logger.error(err1);

      retValue = buildErrorResponse<MembershipOrganizationReference>(err1);
    }

    return retValue;
  }

  public async getMembershipOrganizations(): Promise<ITypedBackendResponse<MembershipOrganizationReference[]>> {
    const client = createClient({
      url: this.backendUrl + "/graphql",
      headers: this.headers,
    });


    const fields: MembershipOrganizationReferenceGenqlSelection = {
      _id: true,
      shortName: true,
      acronym: true,
      fullName: true,
      website: true,
      verified: true,
      logo: {
        _id: true,
        name: true,
        contentType: true,
        size: true,
        useType: true,
        url: true,
        key: true
      },
      country: {
        _id: true,
        name: true
      },
      sport: {
        _id: true,
        name: true

      }
    };

    let retValue: ITypedBackendResponse<MembershipOrganizationReference[]>;

    try {
      const response: any = await client.query({
        getMembershipOrganizations: {
          __args: {},
          ...fields
        }
      });

      VTXBaseAPI.Logger.debug('getMembershipOrganizations Response:');
      VTXBaseAPI.Logger.debug(JSON.stringify(response, null, 2));

      retValue = buildResponse<MembershipOrganizationReference[]>(response, 'getMembershipOrganizations',
        (r: any) => {
          VTXBaseAPI.Logger.debug(JSON.stringify(response, null, 2));
          const isResponseOk: boolean = true && Array.isArray(response?.getMembershipOrganizations);
          return isResponseOk
        }
      );
    }
    catch (err1) {
      VTXBaseAPI.Logger.error('getMembershipOrganizations err1:');
      VTXBaseAPI.Logger.error(err1);

      retValue = buildErrorResponse<MembershipOrganizationReference[]>(err1);
    }

    return retValue;

  }

  public async createAthleteMembershipAffilation(dto: CreateAthleteMembershipDto, desiredFields?: AthleteMembershipGenqlSelection): Promise<ITypedBackendResponse<AthleteMembership>> {
    const client = createClient({
      url: this.backendUrl + "/graphql",
      headers: this.headers,
    });

    const fields: AthleteMembershipGenqlSelection = desiredFields ?? { _id: true };

    let retValue: ITypedBackendResponse<AthleteMembership> = {};
    try {
      const response: any = await client.mutation({
        createAthleteMembershipAffilation: {
          __args: {
            input: dto
          },
          ...fields
        }
      });
      VTXBaseAPI.Logger.debug('createAthleteMembershipAffilation Response:');
      VTXBaseAPI.Logger.debug(JSON.stringify(response, null, 2));

      retValue = buildResponse<AthleteMembership>(response, 'createAthleteMembershipAffilation',
        (r: any) => {
          VTXBaseAPI.Logger.debug(JSON.stringify(response, null, 2));
          const isResponseOk: boolean = true && response?.createAthleteMembershipAffilation?._id;
          return isResponseOk
        }
      );
    } catch (error1) {
      VTXBaseAPI.Logger.error('createAthleteMembershipAffilation err1:');
      VTXBaseAPI.Logger.error(error1);
      retValue = buildErrorResponse<AthleteMembership>(error1);

    }

    return retValue;
  }

  public async deleteMembershipAffiliation(dto: DeleteSingleValueDto): Promise<ITypedBackendResponse<DeleteSingleValueResponse>> {
    const client = createClient({
      url: this.backendUrl + "/graphql",
      headers: this.headers,
    });

    const fields: DeleteSingleValueResponseGenqlSelection = {
      idToDelete: true,
      deleted: true,
      failureReason: {
        code: true,
        message: true
      }
    };

    let retValue: ITypedBackendResponse<DeleteSingleValueResponse> = {};
    try {
      const response: any = await client.mutation({
        deleteAthleteMembershipAffilation: {
          __args: {
            input: dto
          },
          ...fields
        }
      });
      VTXBaseAPI.Logger.debug('deleteAthleteMembershipAffilation Response:');
      VTXBaseAPI.Logger.debug(JSON.stringify(response, null, 2));

      retValue = buildResponse<DeleteSingleValueResponse>(response, 'deleteAthleteMembershipAffilation',
        (r: any) => {
          VTXBaseAPI.Logger.debug(JSON.stringify(response, null, 2));
          const isResponseOk: boolean = true && response?.deleteAthleteMembershipAffilation?.idToDelete;
          return isResponseOk
        }
      );
    } catch (error1) {
      VTXBaseAPI.Logger.error('deleteAthleteMembershipAffilation err1:');
      VTXBaseAPI.Logger.error(error1);
      retValue = buildErrorResponse<DeleteSingleValueResponse>(error1);

    }

    return retValue;
  }



  public async queryAthleteFundingCampaigns(dto: AthleteQueryDto): Promise<ITypedBackendResponse<AthleteQueryResponse>> {

    const client = createClient({
      url: this.backendUrl + "/graphql",
      headers: this.headers,
    });

    //VTXBaseAPI.Logger.debug('HEADERS:');
    //VTXBaseAPI.Logger.debug(JSON.stringify(this.headers, null, 2));

    const fieldsAthlete: AthleteGenqlSelection = {
      _id: true,
      firstName: true,
      lastName: true,
      screenName: true,
      dob: true,
      lgbt: true,
      competitionGender: true,
      country: {
        _id: true,
        //name: true
      },
      location: {
        //userProvidedLatitude: true,
        //userProvidedLongitude: true,
        //cityNameGeocode: true,
        //stateNameGeocode: true,
        //countryIso2CodeGeocode: true,
        //timeZoneGeocode: true,
        //latitudeGeocode: true,
        //longitudeGeocode: true,
        city: {
          //_id: true,
          name: true,
          //localizedName: true,
          state: {
            //_id: true,
            name: true,
            country: {
              _id: true,
              //name: true
            }
          },
          //latitude: true,
          //longitude: true,
          //timezone: true,
        }
      },
      //trainer: true,
      //trainerUrl: true,
      aboutMe: true,
      mainSport: {
        //_id: true,
        name: true
      },
      mainSportLevel: {
        //_id: true,
        label: true,
        //index: true
      },
      scores: {
        vtxScore: true,
        //socialScore: true,
        //trainingScore: true,
        //competitionScore: true
      },
      /*competitions: {
        _id: true,
        event: {
          _id: true,
          name: true,
          mainSport: {
            _id: true,
            name: true
          },
          eventWebSite: true,
          startDate: true,
          endDate: true,
          verified: true,
          banner: {
            _id: true,
            name: true,
            contentType: true,
            size: true,
            useType: true,
            url: true,
            key: true
          },
          location: {
            _id: true,
            userProvidedLatitude: true,
            userProvidedLongitude: true,
            cityNameGeocode: true,
            stateNameGeocode: true,
            countryIso2CodeGeocode: true,
            timeZoneGeocode: true,
            latitudeGeocode: true,
            longitudeGeocode: true,
            city: {
              _id: true,
              name: true,
              localizedName: true,
              state: {
                _id: true,
                name: true,
                country: {
                  _id: true,
                  name: true
                }
              },
              latitude: true,
              longitude: true,
              timezone: true,
            }
          },
        },
        participationDate: true,
        result: {
          _id: true,
          resultType: true,
          position: true,
          score: true,
          finishTimeMS: true,
          resultWebLink: true
        }
      },
      totalUpcomingCompetitions: true,
      totalPastCompetitions: true,
      profilePicture: {
        _id: true,
        name: true,
        contentType: true,
        size: true,
        useType: true,
        url: true,
        key: true
      },*/
      cardPicture: {
        //_id: true,
        //name: true,
        //contentType: true,
        //size: true,
        //useType: true,
        url: true,
        //key: true
      },
      currentCampaign: {
        _id: true,//
        //budgetMode: true,
        status: true,//
        title: true,//
        motivation: true,//
        //website: true,
        fundsRequired: true,//
        initialFundsObtained: true,//
        fundsObtained: true,//
        /*location: {
          _id: true,
          userProvidedLatitude: true,
          userProvidedLongitude: true,
          cityNameGeocode: true,
          stateNameGeocode: true,
          countryIso2CodeGeocode: true,
          timeZoneGeocode: true,
          latitudeGeocode: true,
          longitudeGeocode: true,
          city: {
            _id: true,
            name: true,
            localizedName: true,
            state: {
              _id: true,
              name: true,
              country: {
                _id: true,
                name: true
              }
            },
            latitude: true,
            longitude: true,
            timezone: true,
          }
        },*/
        endingDate: true,//
        /*budget: {
          _id: true,
          initialFunds: true,
          totalRequired: true,
          items: {
            _id: true,
            quantity: true,
            concept: true,
            itemCost: true
          }
        },*/
        /*competitions: {
          _id: true,
          event: {
            _id: true,
            name: true,
            mainSport: {
              _id: true,
              name: true
            },
            eventWebSite: true,
            startDate: true,
            endDate: true,
            verified: true,
            banner: {
              _id: true,
              name: true,
              contentType: true,
              size: true,
              useType: true,
              url: true,
              key: true
            },
            location: {
              _id: true,
              userProvidedLatitude: true,
              userProvidedLongitude: true,
              cityNameGeocode: true,
              stateNameGeocode: true,
              countryIso2CodeGeocode: true,
              timeZoneGeocode: true,
              latitudeGeocode: true,
              longitudeGeocode: true,
              city: {
                _id: true,
                name: true,
                localizedName: true,
                state: {
                  _id: true,
                  name: true,
                  country: {
                    _id: true,
                    name: true
                  }
                },
                latitude: true,
                longitude: true,
                timezone: true,
              }
            },
          },
          participationDate: true,
          result: {
            _id: true,
            resultType: true,
            position: true,
            score: true,
            finishTimeMS: true,
            resultWebLink: true
          }
        }*/
      }
    };

    const fields: AthleteQueryResponseGenqlSelection = {
      athletes: fieldsAthlete,
      cursor: {
        sort: {
          sortField: true,
          order: true
        },
        initialCursorId: true,
        nextCursorId: true,
        initialCursorValue: true,
        nextCursorValue: true,
        limit: true,
        retrieved: true,
        isLastPage: true
      }
    }


    let retValue: ITypedBackendResponse<AthleteQueryResponse>;

    try {
      const response: any = await client.query({
        queryAthleteFundingCampaigns: {
          __args: { input: dto },
          ...fields
        }
      });

      VTXBaseAPI.Logger.debug('queryAthleteFundingCampaigns Response:');
      VTXBaseAPI.Logger.debug(JSON.stringify(response, null, 2));

      retValue = buildResponse<AthleteQueryResponse>(response, 'queryAthleteFundingCampaigns',
        (r: any) => {
          VTXBaseAPI.Logger.debug(JSON.stringify(response, null, 2));
          const isResponseOk: boolean = true && Array.isArray(response?.queryAthleteFundingCampaigns?.athletes);
          return isResponseOk
        }
      );

    } catch (err1) {
      VTXBaseAPI.Logger.error('queryAthleteFundingCampaigns err1:');
      VTXBaseAPI.Logger.error(err1);

      retValue = buildErrorResponse<AthleteQueryResponse>(err1);
    }

    return retValue;


  }


  public async createStripeAccount(dto: CreateStripeAccountDto, desiredFields?: StripeAccountReferenceGenqlSelection): Promise<ITypedBackendResponse<StripeAccountReference>> {
    const client = createClient({
      url: this.backendUrl + "/graphql",
      headers: this.headers,
    });

    const fields: StripeAccountReferenceGenqlSelection = desiredFields ?? {
      _id: true,
      stripeAccountId: true,
      account: {
        id: true,
        object: true,
        business_type: true,
        country: true,
        email: true,
        capabilities: {
          acss_debit_payments: true,
          affirm_payments: true,
          afterpay_clearpay_payments: true,
          alma_payments: true,
          amazon_pay_payments: true,
          au_becs_debit_payments: true,
          bacs_debit_payments: true,
          bancontact_payments: true,
          bank_transfer_payments: true,
          blik_payments: true,
          boleto_payments: true,
          card_issuing: true,
          card_payments: true,
          cartes_bancaires_payments: true,
          cashapp_payments: true,
          eps_payments: true,
          fpx_payments: true,
          gb_bank_transfer_payments: true,
          giropay_payments: true,
          grabpay_payments: true,
          ideal_payments: true,
          india_international_payments: true,
          jcb_payments: true,
          jp_bank_transfer_payments: true,
          kakao_pay_payments: true,
          klarna_payments: true,
          konbini_payments: true,
          kr_card_payments: true,
          legacy_payments: true,
          link_payments: true,
          mobilepay_payments: true,
          multibanco_payments: true,
          mx_bank_transfer_payments: true,
          naver_pay_payments: true,
          oxxo_payments: true,
          p24_payments: true,
          pay_by_bank_payments: true,
          payco_payments: true,
          paynow_payments: true,
          promptpay_payments: true,
          revolut_pay_payments: true,
          samsung_pay_payments: true,
          sepa_bank_transfer_payments: true,
          sepa_debit_payments: true,
          sofort_payments: true,
          swish_payments: true,
          tax_reporting_us_1099_k: true,
          tax_reporting_us_1099_misc: true,
          transfers: true,
          treasury: true,
          twint_payments: true,
          us_bank_account_ach_payments: true,
          us_bank_transfer_payments: true,
          zip_payments: true

        },
        requirements: {
          alternatives: {
            alternative_fields_due: true,
            original_fields_due: true
          },
          current_deadline: true,
          currently_due: true,
          disabled_reason: true,
          errors: {
            code: true,
            reason: true,
            requirement: true
          },
          eventually_due: true,
          past_due: true,
          pending_verification: true
        },
        future_requirements: {
          alternatives: {
            alternative_fields_due: true,
            original_fields_due: true
          },
          current_deadline: true,
          currently_due: true,
          disabled_reason: true,
          errors: {
            code: true,
            reason: true,
            requirement: true
          },
          eventually_due: true,
          past_due: true,
          pending_verification: true
        },
        type: true,
        charges_enabled: true,
        payouts_enabled: true,
        created: true,
        default_currency: true

      }
    };

    fields._id = true; // must include ID for response verification

    let retValue: ITypedBackendResponse<StripeAccountReference> = {};
    try {
      const response: any = await client.mutation({
        createStripeAccount: {
          __args: {
            input: dto
          },
          ...fields
        }
      });
      VTXBaseAPI.Logger.debug('createStripeAccount Response:');
      VTXBaseAPI.Logger.debug(JSON.stringify(response, null, 2));

      retValue = buildResponse<StripeAccountReference>(response, 'createStripeAccount',
        (r: any) => {
          VTXBaseAPI.Logger.debug(JSON.stringify(response, null, 2));
          const isResponseOk: boolean = true && response?.createStripeAccount?._id;
          return isResponseOk
        }
      );
    } catch (error1) {
      VTXBaseAPI.Logger.error('createStripeAccount err1:');
      VTXBaseAPI.Logger.error(error1);
      retValue = buildErrorResponse<StripeAccountReference>(error1);

    }

    return retValue;
  }

  public async createAthleteStripeSession(desiredFields?: StripeSessionGenqlSelection): Promise<ITypedBackendResponse<StripeSession>> {
    const client = createClient({
      url: this.backendUrl + "/graphql",
      headers: this.headers,
    });

    const fields: StripeSessionGenqlSelection = desiredFields ?? {
      account: true,
      client_secret: true,
      expires_at: true,
      livemode: true
    };

    fields.client_secret = true; // must include client_secret for response verification

    let retValue: ITypedBackendResponse<StripeSession> = {};
    try {
      const response: any = await client.mutation({
        createAthleteStripeSession: {
          __args: {
          },
          ...fields
        }
      });
      VTXBaseAPI.Logger.debug('createAthleteStripeSession Response:');
      VTXBaseAPI.Logger.debug(JSON.stringify(response, null, 2));

      retValue = buildResponse<StripeSession>(response, 'createAthleteStripeSession',
        (r: any) => {
          VTXBaseAPI.Logger.debug(JSON.stringify(response, null, 2));
          const isResponseOk: boolean = true && response?.createAthleteStripeSession?.client_secret;
          return isResponseOk
        }
      );
    } catch (error1) {
      VTXBaseAPI.Logger.error('createAthleteStripeSession err1:');
      VTXBaseAPI.Logger.error(error1);
      retValue = buildErrorResponse<StripeSession>(error1);

    }

    return retValue;
  }


  public async createStripeCheckoutSession(dto: DonationCheckoutDto, desiredFields?: StripeCheckoutSessionGenqlSelection): Promise<ITypedBackendResponse<StripeCheckoutSession>> {
    const client = createClient({
      url: this.backendUrl + "/graphql",
      headers: this.headers,
    });

    const fields: StripeCheckoutSessionGenqlSelection = desiredFields ?? {
      client_secret: true,
      expires_at: true,
      livemode: true
    };

    fields.client_secret = true; // must include client_secret for response verification

    let retValue: ITypedBackendResponse<StripeCheckoutSession> = {};
    try {
      const response: any = await client.mutation({
        createStripeCheckoutSession: {
          __args: {
            input: dto
          },
          ...fields
        }
      });
      VTXBaseAPI.Logger.debug('createStripeCheckoutSession Response:');
      VTXBaseAPI.Logger.debug(JSON.stringify(response, null, 2));

      retValue = buildResponse<StripeCheckoutSession>(response, 'createStripeCheckoutSession',
        (r: any) => {
          VTXBaseAPI.Logger.debug(JSON.stringify(response, null, 2));
          const isResponseOk: boolean = true && response?.createStripeCheckoutSession?.client_secret;
          return isResponseOk
        }
      );
    } catch (error1) {
      VTXBaseAPI.Logger.error('createStripeCheckoutSession err1:');
      VTXBaseAPI.Logger.error(error1);
      retValue = buildErrorResponse<StripeCheckoutSession>(error1);

    }

    return retValue;
  }




  public async getDatabaseTextFile(dto: GetDatabaseFileDto, desiredFields?: TextDatabaseFileGenqlSelection): Promise<ITypedBackendResponse<TextDatabaseFile>> {


    //VTXBaseAPI.Logger.log("getTextDatabaseFile HEADERS:\n" + JSON.stringify(this.headers, null, 2));

    const client = createClient({
      url: this.backendUrl + "/graphql",
      headers: this.headers,
    });


    const fields: TextDatabaseFileGenqlSelection = desiredFields ? { ...desiredFields } : {
      _id: true,
      identifier: true,
      version: true,
      contentType: true,
      updated: true,
      created: true,
      content: true
    };

    fields._id = true; // MUST return ID as we use for response verification

    let retValue: ITypedBackendResponse<TextDatabaseFile>;

    try {
      const response: any = await client.query({
        getDatabaseTextFile: {
          __args: { input: dto },
          ...fields
        }
      });

      VTXBaseAPI.Logger.debug('getDatabaseTextFile Response:');
      VTXBaseAPI.Logger.debug(JSON.stringify(response, null, 2));

      retValue = buildResponse<TextDatabaseFile>(response, 'getDatabaseTextFile',
        (r: any) => {
          VTXBaseAPI.Logger.debug(JSON.stringify(response, null, 2));
          const isResponseOk: boolean = true && response?.getDatabaseTextFile._id;
          return isResponseOk
        }
      );
    }
    catch (err1) {
      VTXBaseAPI.Logger.error('getDatabaseTextFile err1:');
      VTXBaseAPI.Logger.error(err1);

      retValue = buildErrorResponse<TextDatabaseFile>(err1);
    }

    return retValue;

  }

  public async getReceiptUrl(dto: GetReceiptDto): Promise<ITypedBackendResponse<ReceiptUrl>> {
    const client = createClient({
      url: this.backendUrl + "/graphql",
      headers: this.headers,
    });
    const fields: ReceiptUrlGenqlSelection = {
      receiptId: true
    };
    let retValue: ITypedBackendResponse<ReceiptUrl>;
    try {
      const response: any = await client.query({
        getReceiptUrl: {
          __args: { input: dto },
          ...fields
        }
      });
      VTXBaseAPI.Logger.debug('getReceiptUrl Response:');
      VTXBaseAPI.Logger.debug(JSON.stringify(response, null, 2));
      retValue = buildResponse<ReceiptUrl>(response, 'getReceiptUrl',
        (r: any) => {
          VTXBaseAPI.Logger.debug(JSON.stringify(response, null, 2));
          const isResponseOk: boolean = true && response?.getReceiptUrl?.receiptId;
          return isResponseOk;
        }
      );
    } catch (err1) {
      VTXBaseAPI.Logger.error('getReceiptUrl err1:');
      VTXBaseAPI.Logger.error(err1);
      retValue = buildErrorResponse<ReceiptUrl>(err1);
    }
    return retValue;
  }
  
  public async stripeQuery(dto: StripeQueryDto): Promise<ITypedBackendResponse<StripeObject>> {

    const client = createClient({
      url: this.backendUrl + "/graphql",
      headers: this.headers,
    });


    const fields: StripeObjectGenqlSelection = {
      type: true,
      json: true
    };


    let retValue: ITypedBackendResponse<StripeObject>;

    try {
      const response: any = await client.query({
        stripeQuery: {
          __args: { input: dto },
          ...fields
        }
      });

      VTXBaseAPI.Logger.debug('stripeQuery Response:');
      VTXBaseAPI.Logger.debug(JSON.stringify(response, null, 2));

      retValue = buildResponse<StripeObject>(response, 'stripeQuery',
        (r: any) => {
          VTXBaseAPI.Logger.debug(JSON.stringify(response, null, 2));
          const isResponseOk: boolean = true && response?.stripeQuery.type;
          return isResponseOk
        }
      );
    }
    catch (err1) {
      VTXBaseAPI.Logger.error('stripeQuery err1:');
      VTXBaseAPI.Logger.error(err1);

      retValue = buildErrorResponse<StripeObject>(err1);
    }

    return retValue;

  }

  public async setFundingStatus(
    dto: SetFundingStatusDto, desiredFields?: FundRaisingCampaignGenqlSelection
  ): Promise<ITypedBackendResponse<FundRaisingCampaign>> {

    //console.log('HEADERS:');
    //console.log(JSON.stringify(this.headers, null,2));

    const client = createClient({
      url: this.backendUrl + '/graphql',
      headers: this.headers,
    });


    let retValue: ITypedBackendResponse<FundRaisingCampaign> = {};

    const fields: FundRaisingCampaignGenqlSelection = desiredFields ?? {
      _id: true,
      budgetMode: true,
      status: true,
      title: true,
      motivation: true,
      website: true,
      fundsRequired: true,
      initialFundsObtained: true,
      fundsObtained: true,
      vtxComissionPct: true,
      location: {
        userProvidedLatitude: true,
        userProvidedLongitude: true,
        cityNameGeocode: true,
        stateNameGeocode: true,
        countryIso2CodeGeocode: true,
        timeZoneGeocode: true,
        latitudeGeocode: true,
        longitudeGeocode: true,
        city: {
          _id: true,
          name: true,
          localizedName: true,
          state: {
            _id: true,
            name: true,
            country: {
              _id: true,
              name: true
            }
          },
          latitude: true,
          longitude: true,
          timezone: true,
        }
      },
      endingDate: true,
      budget: {
        initialFunds: true,
        totalRequired: true,
        items: {
          _id: true,
          quantity: true,
          concept: true,
          itemCost: true
        }
      },
      competitions: {
        _id: true,
        event: {
          _id: true,
          name: true,
          mainSport: {
            _id: true,
            name: true
          },
          eventWebSite: true,
          startDate: true,
          endDate: true,
          verified: true,
          banner: {
            _id: true,
            name: true,
            contentType: true,
            size: true,
            useType: true,
            url: true,
            key: true
          },
          location: {
            _id: true,
            userProvidedLatitude: true,
            userProvidedLongitude: true,
            cityNameGeocode: true,
            stateNameGeocode: true,
            countryIso2CodeGeocode: true,
            timeZoneGeocode: true,
            latitudeGeocode: true,
            longitudeGeocode: true,
            city: {
              _id: true,
              name: true,
              localizedName: true,
              state: {
                _id: true,
                name: true,
                country: {
                  _id: true,
                  name: true
                }
              },
              latitude: true,
              longitude: true,
              timezone: true,
            }
          },
        },
        participationDate: true,
        competitionNumber: true,
        result: {
          resultType: true,
          position: true,
          score: true,
          finishTimeMS: true,
          resultWebLink: true
        },
        fundRaisingCampaignIds: true
      }
    };

    fields._id = true; // required


    try {
      const response: any = await client.mutation({
        setFundingStatus: {
          __args: {
            input: dto
          },
          ...fields
        },
      });

      VTXBaseAPI.Logger.log("==================HERE=====================================");
      VTXBaseAPI.Logger.log('setFundingStatus Response:');
      VTXBaseAPI.Logger.log(JSON.stringify(response, null, 2));
      VTXBaseAPI.Logger.log("==================DONE=====================================");

      retValue = buildResponse<FundRaisingCampaign>(response, 'setFundingStatus',
        (r: any) => {
          const isResponseOk: boolean = true && response?.setFundingStatus?._id;
          return isResponseOk
        }
      );

    } catch (err1) {
      VTXBaseAPI.Logger.log("************** ERROR *******************************");
      VTXBaseAPI.Logger.log('setFundingStatus err1:');
      VTXBaseAPI.Logger.log(err1);
      VTXBaseAPI.Logger.log("************** DONE ERROR **************************");

      retValue = buildErrorResponse<FundRaisingCampaign>(err1);
    }

    return retValue;
  }
  //--------------------------


  public async findAthleteForIdPublic(id: string): Promise<ITypedBackendResponse<Athlete>> {

    const client = createClient({
      url: this.backendUrl + "/graphql",
      headers: this.headers,
    });

    let retValue: ITypedBackendResponse<Athlete> = {};

    const fields: AthleteGenqlSelection = {
      _id: true,
      firstName: true,
      lastName: true,
      screenName: true,
      dob: true,
      lgbt: true,
      competitionGender: true,
      country: {
        _id: true,
        name: true
      },
      location: {
        userProvidedLatitude: true,
        userProvidedLongitude: true,
        cityNameGeocode: true,
        stateNameGeocode: true,
        countryIso2CodeGeocode: true,
        timeZoneGeocode: true,
        latitudeGeocode: true,
        longitudeGeocode: true,
        city: {
          _id: true,
          name: true,
          localizedName: true,
          state: {
            _id: true,
            name: true,
            country: {
              _id: true,
              name: true
            }
          },
          latitude: true,
          longitude: true,
          timezone: true,
        }
      },
      trainer: true,
      trainerUrl: true,
      aboutMe: true,
      followStats: {
        followers: true,
        followed: true,
        raves: true,
        favorites: true
      },
      mainSport: {
        _id: true,
        name: true
      },
      mainSportLevel: {
        _id: true,
        label: true,
        index: true
      },
      scores: {
        vtxScore: true,
        socialScore: true,
        trainingScore: true,
        competitionScore: true
      },
      rankings: {
        worldRanking: {
          scope: true,
          scopeId: true,
          scopeName: true,
          position: true,
          total: true
        },
        countryRanking: {
          scope: true,
          scopeId: true,
          scopeName: true,
          position: true,
          total: true
        },
        stateRanking: {
          scope: true,
          scopeId: true,
          scopeName: true,
          position: true,
          total: true
        },
        cityRanking: {
          scope: true,
          scopeId: true,
          scopeName: true,
          position: true,
          total: true
        },
      },
      allSports: {
        _id: true,
        name: true
      },
      teams: {
        _id: true,
        name: true,
        description: true,
        //        sports: {
        //          _id: true,
        //          name: true
        //        },
        approved: true,
        logo: {
          _id: true,
          name: true,
          contentType: true,
          size: true,
          useType: true,
          url: true,
          key: true
        },
        banner: {
          _id: true,
          name: true,
          contentType: true,
          size: true,
          useType: true,
          url: true,
          key: true
        }

      },
      sponsorBrands: {
        _id: true,
        name: true,
        slogan: true,
        website: true,
        description: true,
        approved: true,
        published: true,
        logo: {
          _id: true,
          name: true,
          contentType: true,
          size: true,
          useType: true,
          url: true,
          key: true
        },
        //banner?: AWSS3FileGenqlSelection,
        stats: {
          campaigns: true,
          sponsorships: true,
          sports: true,
          athletes: true
        },
        operatorIds: true,

      },
      competitions: {
        _id: true,
        event: {
          _id: true,
          name: true,
          mainSport: {
            _id: true,
            name: true
          },
          eventWebSite: true,
          startDate: true,
          endDate: true,
          verified: true,
          location: {
            _id: true,
            userProvidedLatitude: true,
            userProvidedLongitude: true,
            cityNameGeocode: true,
            stateNameGeocode: true,
            countryIso2CodeGeocode: true,
            timeZoneGeocode: true,
            latitudeGeocode: true,
            longitudeGeocode: true,
            city: {
              _id: true,
              name: true,
              localizedName: true,
              state: {
                _id: true,
                name: true,
                country: {
                  _id: true,
                  name: true
                }
              },
              latitude: true,
              longitude: true,
              timezone: true,
            }
          },
          banner: {
            _id: true,
            name: true,
            contentType: true,
            size: true,
            useType: true,
            url: true,
            key: true
          }
        },
        participationDate: true,
        result: {
          _id: true,
          resultType: true,
          position: true,
          score: true,
          finishTimeMS: true,
          resultWebLink: true,
          totalParticipants: true,
        }
      },
      affiliations: {
        _id: true,
        organization: {
          _id: true,
          shortName: true,
          acronym: true,
          fullName: true,
          website: true,
          logo: {
            _id: true,
            name: true,
            contentType: true,
            size: true,
            useType: true,
            url: true,
            key: true
          }
        },
        membershipNumber: true,
        membershipType: true,
        issueDate: true,
        expirationDate: true,
      },
      totalUpcomingCompetitions: true,
      totalPastCompetitions: true,
      profilePicture: {
        _id: true,
        name: true,
        contentType: true,
        size: true,
        useType: true,
        url: true,
        key: true
      },
      cardPicture: {
        _id: true,
        name: true,
        contentType: true,
        size: true,
        useType: true,
        url: true,
        key: true
      },
      bannerPicture: {
        _id: true,
        name: true,
        contentType: true,
        size: true,
        useType: true,
        url: true,
        key: true
      },
      preferences: {
        _id: true,
        showProfileHelper: true,
        defaultAlbum: {
          _id: true,
          label: true,
          description: true,
          photos: {
            _id: true,
            photo: {
              _id: true,
              name: true,
              contentType: true,
              size: true,
              useType: true,
              url: true,
              key: true
            },
            }
        }
      },
      currentCampaign: {
        _id: true,
        budgetMode: true,
        status: true,
        title: true,
        motivation: true,
        website: true,
        fundsRequired: true,
        initialFundsObtained: true,
        fundsObtained: true,
        location: {
          _id: true,
          userProvidedLatitude: true,
          userProvidedLongitude: true,
          cityNameGeocode: true,
          stateNameGeocode: true,
          countryIso2CodeGeocode: true,
          timeZoneGeocode: true,
          latitudeGeocode: true,
          longitudeGeocode: true,
          city: {
            _id: true,
            name: true,
            localizedName: true,
            state: {
              _id: true,
              name: true,
              country: {
                _id: true,
                name: true
              }
            },
            latitude: true,
            longitude: true,
            timezone: true,
          }
        },
        endingDate: true,
        budget: {
          _id: true,
          initialFunds: true,
          totalRequired: true,
          items: {
            _id: true,
            quantity: true,
            concept: true,
            itemCost: true
          }
        },
        competitions: {
          _id: true,
          event: {
            _id: true,
            name: true,
            mainSport: {
              _id: true,
              name: true
            },
            eventWebSite: true,
            startDate: true,
            endDate: true,
            verified: true,
            banner: {
              _id: true,
              name: true,
              contentType: true,
              size: true,
              useType: true,
              url: true,
              key: true
            },
            location: {
              _id: true,
              userProvidedLatitude: true,
              userProvidedLongitude: true,
              cityNameGeocode: true,
              stateNameGeocode: true,
              countryIso2CodeGeocode: true,
              timeZoneGeocode: true,
              latitudeGeocode: true,
              longitudeGeocode: true,
              city: {
                _id: true,
                name: true,
                localizedName: true,
                state: {
                  _id: true,
                  name: true,
                  country: {
                    _id: true,
                    name: true
                  }
                },
                latitude: true,
                longitude: true,
                timezone: true,
              }
            },
          },
          participationDate: true,
          result: {
            _id: true,
            resultType: true,
            position: true,
            score: true,
            finishTimeMS: true,
            resultWebLink: true,
            totalParticipants: true,
          }
        }
      },
    };

    try {

      let response: any = null;

      response = await client.query({
        findAthletebyIdpublic: {
          __args: {
            athleteId: id
          },
          ...fields
        }
      });



      VTXBaseAPI.Logger.debug('findAthletebyIdpublic Response:');
      VTXBaseAPI.Logger.debug(JSON.stringify(response, null, 2));

      retValue = buildResponse<Athlete>(response, 'findAthletebyIdpublic',
        (r: any) => {
          const isResponseOk: boolean = true && response?.findAthletebyIdpublic?._id;
          return isResponseOk
        }
      );

    } catch (err1) {
      VTXBaseAPI.Logger.error('findAthleteForUser err1:');
      VTXBaseAPI.Logger.error(err1);

      retValue = buildErrorResponse<Athlete>(err1);
    }

    return retValue;
  }


  public async editPicture(
    newPicDto: EditPictureDto
  ): Promise<ITypedBackendResponse<EditPictureResponse>> {

    console.log('HEADERS:');
    console.log(JSON.stringify(this.headers, null, 2));

    const client = createClient({
      url: this.backendUrl + '/graphql',
      headers: this.headers,
    });


    let retValue: ITypedBackendResponse<EditPictureResponse> = {};

    const fields: EditPictureResponseGenqlSelection = {
      field: true,
      oldValue: {
        _id: true,
        name: true,
        contentType: true,
        size: true,
        useType: true,
        url: true,
        key: true
      },
      newValue: {
        _id: true,
        name: true,
        contentType: true,
        size: true,
        useType: true,
        url: true,
        key: true
      },
      changed: true
    };



    try {
      const response: any = await client.mutation({
        editPicture: {
          __args: {
            input: newPicDto
          },
          ...fields
        },
      });

      VTXBaseAPI.Logger.debug('editPicture Response:');
      VTXBaseAPI.Logger.debug(JSON.stringify(response, null, 2));

      retValue = buildResponse<EditPictureResponse>(response, 'editPicture',
        (r: any) => {
          const isResponseOk: boolean = true && response?.editPicture?.field;
          return isResponseOk
        }
      );

    } catch (err1) {
      VTXBaseAPI.Logger.error('editProfileValue err1:');
      VTXBaseAPI.Logger.error(err1);

      retValue = buildErrorResponse<EditPictureResponse>(err1);
    }

    return retValue;
  }



  public async addAlbumsPictures(
    dto: UploadAlbumsPicturesDto
  ): Promise<ITypedBackendResponse<AddValuesResponse>> {

    console.log('HEADERS:');
    console.log(JSON.stringify(this.headers, null, 2));

    const client = createClient({
      url: this.backendUrl + '/graphql',
      headers: this.headers,
    });

    let retValue: ITypedBackendResponse<AddValuesResponse> = {};

    const fields: AddValuesResponseGenqlSelection = {
      added: true,
      failedToAdd: true,
      failureReason: {
        code: true,
        message: true
      },
      result: true,
    };

    try {
      const response: any = await client.mutation({
        AddAlbumPictures: {
          __args: {
            input: dto
          },
          ...fields
        },
      });

      console.log('AddAlbumsPictures Response:');
      console.log(JSON.stringify(response, null, 2));


      retValue = buildResponse<AddValuesResponse>(response, 'AddAlbumPictures',
        (r: any) => {
          const isResponseOk: boolean = response?.AddAlbumPictures?.result === 'success' || response?.AddAlbumPictures?.result === 'partial';
          return isResponseOk
        }
      );

    } catch (err1) {
      console.error('addPictures err1:');
      console.error(err1);

      retValue = buildErrorResponse<AddValuesResponse>(err1);
    }

    console.log('retValue:');
    console.log(JSON.stringify(retValue, null, 2));
    return retValue;
  }

  public async editAlbumsPictures(
    dto: UploadAlbumsPicturesDto
  ): Promise<ITypedBackendResponse<Album>> {

    console.log('HEADERS:');
    console.log(JSON.stringify(this.headers, null, 2));

    const client = createClient({
      url: this.backendUrl + '/graphql',
      headers: this.headers,
    });

    let retValue: ITypedBackendResponse<Album> = {};

    const fields: AlbumGenqlSelection = {
      label: true,
      description: true,
      photos: {
        _id: true,
        photo: {
          _id: true,
          name: true,
          contentType: true,
          size: true,
          useType: true,
          url: true,
        }
      }
    };

    try {
      const response: any = await client.mutation({
        editAlbum: {
          __args: {
            input: dto
          },
          ...fields
        },
      });

      console.log('editAlbum Response:');
      console.log(JSON.stringify(response, null, 2));


      retValue = buildResponse<Album>(response, 'editAlbum',
        (r: any) => {
          const isResponseOk: boolean = response?.editAlbum?.label;
          return isResponseOk
        }
      );

    } catch (err1) {
      console.error('editAlbum err1:');
      console.error(err1);

      retValue = buildErrorResponse<Album>(err1);
    }

    console.log('retValue:');
    console.log(JSON.stringify(retValue, null, 2));
    return retValue;
  }


  public async createAthleteAlbum(
    dto: UploadAlbumsPicturesDto
  ): Promise<ITypedBackendResponse<Album>> {

    console.log('HEADERS:');
    console.log(JSON.stringify(this.headers, null, 2));

    const client = createClient({
      url: this.backendUrl + '/graphql',
      headers: this.headers,
    });

    let retValue: ITypedBackendResponse<Album> = {};

    const fields: AlbumGenqlSelection = {
      label: true,
      description: true,
      photos: {
        _id: true,
        photo: {
          _id: true,
          name: true,
          contentType: true,
          size: true,
          useType: true,
          url: true,
        }
      }
    };

    try {
      const response: any = await client.mutation({
        createAthleteAlbum: {
          __args: {
            input: dto
          },
          ...fields
        },
      });

      console.log('createAthleteAlbum Response:');
      console.log(JSON.stringify(response, null, 2));


      retValue = buildResponse<Album>(response, 'createAthleteAlbum',
        (r: any) => {
          const isResponseOk: boolean = response?.createAthleteAlbum?.label;
          return isResponseOk
        }
      );

    } catch (err1) {
      console.error('createAthleteAlbum err1:');
      console.error(err1);

      retValue = buildErrorResponse<Album>(err1);
    }

    console.log('retValue:');
    console.log(JSON.stringify(retValue, null, 2));
    return retValue;
  }

  public async deleteAthleteAlbum(
    dto: DeleteSingleValueDto
  ): Promise<ITypedBackendResponse<DeleteSingleValueResponse>> {

    console.log('HEADERS:');
    console.log(JSON.stringify(this.headers, null, 2));

    const client = createClient({
      url: this.backendUrl + '/graphql',
      headers: this.headers,
    });

    let retValue: ITypedBackendResponse<DeleteSingleValueResponse> = {};

    const fields: DeleteSingleValueResponseGenqlSelection = {
      idToDelete: true,
      deleted: true,
      failureReason: {
        code: true,
        message: true
      }
    };

    try {
      const response: any = await client.mutation({
        deleteAthleteAlbum: {
          __args: {
            input: dto
          },
          ...fields
        },
      });

      console.log('deleteAthleteAlbum Response:');
      console.log(JSON.stringify(response, null, 2));


      retValue = buildResponse<DeleteSingleValueResponse>(response, 'deleteAthleteAlbum',
        (r: any) => {
          const isResponseOk: boolean = response?.deleteAthleteAlbum?.deleted;
          return isResponseOk
        }
      );

    } catch (err1) {
      console.error('createAthleteAlbum err1:');
      console.error(err1);

      retValue = buildErrorResponse<DeleteSingleValueResponse>(err1);
    }

    console.log('retValue:');
    console.log(JSON.stringify(retValue, null, 2));
    return retValue;
  }

  public async getAthleteAlbums(
  ): Promise<ITypedBackendResponse<Album[]>> {

    console.log('HEADERS:');
    console.log(JSON.stringify(this.headers, null, 2));

    const client = createClient({
      url: this.backendUrl + '/graphql',
      headers: this.headers,
    });

    let retValue: ITypedBackendResponse<Album[]>;

    const fields: AlbumGenqlSelection = {
      _id: true,
      label: true,
      description: true,
      photos: {
        _id: true,
        photo: {
          _id: true,
          name: true,
          contentType: true,
          size: true,
          useType: true,
          url: true,
        }
      }
    };

    try {
      const response: any = await client.query({
        getAthleteAlbums: {
          __args: {
          },
          ...fields
        },
      });

      console.log('getAthleteAlbums Response:');
      console.log(JSON.stringify(response, null, 2));


      retValue = buildResponse<Album[]>(response, 'getAthleteAlbums',
        (r: any) => {
          const isResponseOk: boolean = response?.getAthleteAlbums.length > 0;
          return isResponseOk
        }
      );

    } catch (err1) {
      console.error('getAthleteAlbums err1:');
      console.error(err1);

      retValue = buildErrorResponse<Album[]>(err1);
    }

    console.log('retValue:');
    console.log(JSON.stringify(retValue, null, 2));
    return retValue;
  }

  public async getPublicAthleteAlbums(athleteId: string
  ): Promise<ITypedBackendResponse<Album[]>> {

    console.log('HEADERS:');
    console.log(JSON.stringify(this.headers, null, 2));

    const client = createClient({
      url: this.backendUrl + '/graphql',
      headers: this.headers,
    });

    let retValue: ITypedBackendResponse<Album[]>;

    const fields: AlbumGenqlSelection = {
      _id: true,
      label: true,
      description: true,
      photos: {
        _id: true,
        photo: {
          _id: true,
          name: true,
          contentType: true,
          size: true,
          useType: true,
          url: true,
        }
      }
    };

    try {
      const response: any = await client.query({
        getPublicAthleteAlbums: {
          __args: {
            athleteId: athleteId
          },
          ...fields
        },
      });

      console.log('getPublicAthleteAlbums Response:');
      console.log(JSON.stringify(response, null, 2));


      retValue = buildResponse<Album[]>(response, 'getPublicAthleteAlbums',
        (r: any) => {
          const isResponseOk: boolean = response?.getPublicAthleteAlbums.length > 0;
          return isResponseOk
        }
      );

    } catch (err1) {
      console.error('getPublicAthleteAlbums err1:');
      console.error(err1);

      retValue = buildErrorResponse<Album[]>(err1);
    }

    console.log('retValue:');
    console.log(JSON.stringify(retValue, null, 2));
    return retValue;
  }

  public async getAthleteAlbumsById(albumId: string): Promise<ITypedBackendResponse<Album>> {
  
    console.log('HEADERS:');
    console.log(JSON.stringify(this.headers, null, 2));

    const client = createClient({
      url: this.backendUrl + '/graphql',
      headers: this.headers,
    });

    let retValue: ITypedBackendResponse<Album> = {};

    const fields: AlbumGenqlSelection = {
      label: true,
      description: true,
      photos: {
        _id: true,
        photo: {
          _id: true,
          name: true,
          contentType: true,
          size: true,
          useType: true,
          url: true,
        }
      }
    };

    try {
      const response: any = await client.query({
        getAthleteAlbumId: {
          __args: {
            input: albumId
          },
          ...fields
        },
      });
  
      console.log('getAthleteAlbumId Response:');
      console.log(JSON.stringify(response, null, 2)); 
  
    
      retValue = buildResponse<Album>(response, 'getAthleteAlbumId',
        (r: any) => {
          const isResponseOk: boolean =response?.getAthleteAlbumId?._id;
          return isResponseOk
        }
      );

    } catch (err1) {
      console.error('getAthleteAlbumId err1:');
      console.error(err1);

      retValue = buildErrorResponse<Album>(err1);
    }

    console.log('retValue:');
    console.log(JSON.stringify(retValue, null, 2));
    return retValue;
  }

  public async getAndSetAlbumById(albumId: string): Promise<ITypedBackendResponse<Album>> {
  
    console.log('HEADERS:');
    console.log(JSON.stringify(this.headers, null, 2));
  
    const client = createClient({
      url: this.backendUrl + '/graphql',
      headers: this.headers,
    });
  
    let retValue: ITypedBackendResponse<Album> = {};
  
    const fields: AlbumGenqlSelection = {
      _id: true,
      label: true,
      description: true,
      photos : {
        _id: true,
        photo: {
          _id: true,
          name: true,
          contentType: true,
          size: true,
          useType: true,
          url: true,
      }
    }
  };
  
    try {
      const response: any = await client.query({
        getAndSetAlbumById: {
          __args: {
            input: albumId
          },
          ...fields
        },
      });
  
      console.log('getAndSetAlbumById Response:');
      console.log(JSON.stringify(response, null, 2)); 
  
    
      retValue = buildResponse<Album>(response, 'getAndSetAlbumById',
        (r: any) => {
          const isResponseOk: boolean =response?.getAndSetAlbumById?._id;
          return isResponseOk
        }
      );
  
    } catch (err1) {
      console.error('getAndSetAlbumById err1:');
      console.error(err1);
  
      retValue = buildErrorResponse<Album>(err1);
    }
  
    console.log('retValue:');
    console.log(JSON.stringify(retValue, null, 2));
    return retValue;
  }



  public async queryAthletesWithFilters(dto: AthleteQueryDto): Promise<ITypedBackendResponse<AthleteQueryResponse>> {

    const client = createClient({
      url: this.backendUrl + "/graphql",
      headers: this.headers,
    });

    //VTXBaseAPI.Logger.debug('HEADERS:');
    //VTXBaseAPI.Logger.debug(JSON.stringify(this.headers, null, 2));

    const fieldsAthlete: AthleteGenqlSelection = {
      //_id: true,
      firstName: true,
      lastName: true,
      screenName: true,
      dob: true,
      //lgbt: true,
      competitionGender: true,
      country: {
        _id: true,
        //name: true
      },
      location: {
        /*userProvidedLatitude: true,
        userProvidedLongitude: true,
        cityNameGeocode: true,
        stateNameGeocode: true,
        countryIso2CodeGeocode: true,
        timeZoneGeocode: true,
        latitudeGeocode: true,
        longitudeGeocode: true,*/
        city: {
          //_id: true,
          name: true,
          //localizedName: true,
          state: {
            //_id: true,
            name: true,
            country: {
              _id: true,
              //name: true
            }
          },
          //latitude: true,
          //longitude: true,
          //timezone: true,
        }
      },
      //trainer: true,
      //trainerUrl: true,
      aboutMe: true,
      mainSport: {
        //_id: true,
        name: true
      },
      mainSportLevel: {
        //_id: true,
        label: true,
        //index: true
      },
      scores: {
        vtxScore: true,
        //socialScore: true,
        //trainingScore: true,
        //competitionScore: true
      },
      competitions: {
        //_id: true,
        event: {
          //_id: true,
          name: true,
          /*mainSport: {
            _id: true,
            name: true
          },
          eventWebSite: true,
          startDate: true,
          endDate: true,
          verified: true,
          banner: {
            _id: true,
            name: true,
            contentType: true,
            size: true,
            useType: true,
            url: true,
            key: true
          },
          location: {
            _id: true,
            userProvidedLatitude: true,
            userProvidedLongitude: true,
            cityNameGeocode: true,
            stateNameGeocode: true,
            countryIso2CodeGeocode: true,
            timeZoneGeocode: true,
            latitudeGeocode: true,
            longitudeGeocode: true,
            city: {
              _id: true,
              name: true,
              localizedName: true,
              state: {
                _id: true,
                name: true,
                country: {
                  _id: true,
                  name: true
                }
              },
              latitude: true,
              longitude: true,
              timezone: true,
            }
          },*/
        },
        participationDate: true,
        /*result: {
          _id: true,
          resultType: true,
          position: true,
          score: true,
          finishTimeMS: true,
          resultWebLink: true
        }*/
      },
      /*totalUpcomingCompetitions: true,
      totalPastCompetitions: true,
      profilePicture: {
        _id: true,
        name: true,
        contentType: true,
        size: true,
        useType: true,
        url: true,
        key: true
      },*/
      cardPicture: {
        //_id: true,
        //name: true,
        //contentType: true,
        //size: true,
        //useType: true,
        url: true,
        //key: true
      },
      /*currentCampaign: {
        _id: true,
        budgetMode: true,
        status: true,
        title: true,
        motivation: true,
        website: true,
        fundsRequired: true,
        initialFundsObtained: true,
        fundsObtained: true,
        location: {
          _id: true,
          userProvidedLatitude: true,
          userProvidedLongitude: true,
          cityNameGeocode: true,
          stateNameGeocode: true,
          countryIso2CodeGeocode: true,
          timeZoneGeocode: true,
          latitudeGeocode: true,
          longitudeGeocode: true,
          city: {
            _id: true,
            name: true,
            localizedName: true,
            state: {
              _id: true,
              name: true,
              country: {
                _id: true,
                name: true
              }
            },
            latitude: true,
            longitude: true,
            timezone: true,
          }
        },
        endingDate: true,
        budget: {
          _id: true,
          initialFunds: true,
          totalRequired: true,
          items: {
            _id: true,
            quantity: true,
            concept: true,
            itemCost: true
          }
        },
        competitions: {
          _id: true,
          event: {
            _id: true,
            name: true,
            mainSport: {
              _id: true,
              name: true
            },
            eventWebSite: true,
            startDate: true,
            endDate: true,
            verified: true,
            banner: {
              _id: true,
              name: true,
              contentType: true,
              size: true,
              useType: true,
              url: true,
              key: true
            },
            location: {
              _id: true,
              userProvidedLatitude: true,
              userProvidedLongitude: true,
              cityNameGeocode: true,
              stateNameGeocode: true,
              countryIso2CodeGeocode: true,
              timeZoneGeocode: true,
              latitudeGeocode: true,
              longitudeGeocode: true,
              city: {
                _id: true,
                name: true,
                localizedName: true,
                state: {
                  _id: true,
                  name: true,
                  country: {
                    _id: true,
                    name: true
                  }
                },
                latitude: true,
                longitude: true,
                timezone: true,
              }
            },
          },
          participationDate: true,
          result: {
            _id: true,
            resultType: true,
            position: true,
            score: true,
            finishTimeMS: true,
            resultWebLink: true
          }
        }
      }*/
    };

    const fields: AthleteQueryResponseGenqlSelection = {
      athletes: fieldsAthlete,
      cursor: {
        sort: {
          sortField: true,
          order: true
        },
        initialCursorId: true,
        nextCursorId: true,
        initialCursorValue: true,
        nextCursorValue: true,
        limit: true,
        retrieved: true,
        isLastPage: true
      }
    }


    let retValue: ITypedBackendResponse<AthleteQueryResponse>;

    try {
      const response: any = await client.query({
        queryAthleteWithFilter: {
          __args: { input: dto },
          ...fields
        }
      });

      VTXBaseAPI.Logger.debug('queryAthleteWithFilter Response:');
      VTXBaseAPI.Logger.debug(JSON.stringify(response, null, 2));

      retValue = buildResponse<AthleteQueryResponse>(response, 'queryAthleteWithFilter',
        (r: any) => {
          VTXBaseAPI.Logger.debug(JSON.stringify(response, null, 2));
          const isResponseOk: boolean = true && Array.isArray(response?.queryAthleteWithFilter?.athletes);
          return isResponseOk
        }
      );

    } catch (err1) {
      VTXBaseAPI.Logger.error('queryAthleteFundingCampaigns err1:');
      VTXBaseAPI.Logger.error(err1);

      retValue = buildErrorResponse<AthleteQueryResponse>(err1);
    }

    return retValue;


  }

  public async getAthleteIntegrationsByAthlete(): Promise<ITypedBackendResponse<AthleteIntegrationReference>> {

    const client = createClient({
      url: this.backendUrl + '/graphql',
      headers: this.headers,
    });

    let retValue: ITypedBackendResponse<AthleteIntegrationReference> = {};

    const fields = {
      _id: true,
      athlete: {
        _id: true,
      },
      hasInstagramIntegration: true,
      instagramTokenExpires: true,
      instagramUserData: {
        user_id: true,
        username: true,
        name: true,
        account_type: true,
        followers_count: true,
        media_count: true
      },
      instagramMediaData: {
        data: {
          id: true,
          caption: true,
          media_type: true,
          media_url: true,
          permalink: true,
          thumbnail_url: true,
          timestamp: true,
          username: true,
          like_count: true,
          comments_count: true,
          insights: {
            data: {
              name: true,
              period: true,
              values: true
            }
          }
        },
        paging: {
          cursors: {
            before: true,
            after: true
          },
          next: true
        }
      }
    };
    
    try {
      const response: any = await client.query({
        getAthleteInstagramIntegration: {
          ...fields
        },
      });
      
      retValue = buildResponse(response, 'getAthleteInstagramIntegration',
        (r: any) => {
          const isResponseOk: boolean = !!response?.getAthleteInstagramIntegration?._id;
          return isResponseOk;
        }
      );
      
    } catch (err) {    
      retValue = buildErrorResponse(err);
    }
    return retValue;
  }


  /*
  public async deleteAthleteIntegration(): Promise<ITypedBackendResponse<boolean>> {
    const client = createClient({
      url: this.backendUrl + '/graphql',
      headers: this.headers,
    })

    let retValue: ITypedBackendResponse<boolean> = {}

    try {
      const response: any = await client.mutation({
        updateAthleteIntegration: {
          __args: {
            type: type
          },
        }
      })
      retValue = buildResponse(response, 'deleteAthleteIntegration',
        (r: any) => {
          const isResponseOk: boolean = response?.updateAthleteIntegration === true
          return isResponseOk
        }
      )
    } catch (err) {
      retValue = buildErrorResponse(err)
    }

    return retValue
  }
  */

  // Get Strava integration specifically
  public async getAthleteStravaIntegration(): Promise<ITypedBackendResponse<AthleteIntegrationReference>> {
    const client = createClient({
      url: this.backendUrl + '/graphql',
      headers: this.headers,
    });
    
    let retValue: ITypedBackendResponse<AthleteIntegrationReference> = {};
    
    const fields = {
      _id: true,
      athlete: {
        _id: true,
      },
      hasStravaIntegration: true,
      stravaTokenExpires: true,
      stravaAthleteData: {
        id: true,
        username: true,
        firstname: true,
        lastname: true,
        bio: true,
        city: true,
        state: true,
        country: true,
        sex: true,
        premium: true,
        profile: true,
        created_at: true,
        updated_at: true,
        weight: true
      }
    };
    
    try {
      const response: any = await client.query({
        getAthleteStravaIntegration: {
          ...fields
        },
      });
      
      retValue = buildResponse(response, 'getAthleteStravaIntegration',
        (r: any) => {
          const isResponseOk: boolean = !!response?.getAthleteStravaIntegration?._id;
          return isResponseOk;
        }
      );
      
    } catch (err) {    
      retValue = buildErrorResponse(err);
    }
    return retValue;
  }

  // Get Instagram integration specifically
  public async getAthleteInstagramIntegration(): Promise<ITypedBackendResponse<AthleteIntegrationReference>> {
    const client = createClient({
      url: this.backendUrl + '/graphql',
      headers: this.headers,
    });
    
    let retValue: ITypedBackendResponse<AthleteIntegrationReference> = {};
    
    const fields = {
      _id: true,
      athlete: {
        _id: true,
      },
      hasInstagramIntegration: true,
      instagramTokenExpires: true,
      instagramUserData: {
        user_id: true,
        username: true,
        name: true,
        account_type: true,
        followers_count: true,
        media_count: true
      },
      instagramMediaData: {
        data: {
          id: true,
          caption: true,
          media_type: true,
          media_url: true,
          permalink: true,
          thumbnail_url: true,
          timestamp: true,
          username: true,
          like_count: true,
          comments_count: true,
          insights: {
            data: {
              name: true,
              period: true,
              values: true
            }
          }
        },
        paging: {
          cursors: {
            before: true,
            after: true
          },
          next: true
        }
      }
    };
    
    try {
      const response: any = await client.query({
        getAthleteInstagramIntegration: {
          ...fields
        },
      });
      
      retValue = buildResponse(response, 'getAthleteInstagramIntegration',
        (r: any) => {
          const isResponseOk: boolean = !!response?.getAthleteInstagramIntegration?._id;
          return isResponseOk;
        }
      );
      
    } catch (err) {    
      retValue = buildErrorResponse(err);
    }
    return retValue;
  }

  public async getReceipt(
    dto: GetReceiptDto
  ): Promise<ITypedBackendResponse<Receipt>> {
    const client = createClient({
      url: this.backendUrl + '/graphql',
      headers: this.headers,
    });
    let retValue: ITypedBackendResponse<Receipt> = {};
    const fields: ReceiptGenqlSelection = {
      receiptId: true,
      athleteName: true,
      campaignName: true,
      donorName: true,
      amount: true,
      currency: true,
      dateIssued: true,
      message: true,
      confirmed: true,
    };
    try {
      const response: any = await client.query({
        getReceipt: {
          __args: {
            input: dto
          },
          ...fields
        },
      });

      //console.log('getReceipt response:', JSON.stringify(response, null, 2));
      retValue = buildResponse(response, 'getReceipt',
        (r: any) => {
          const isResponseOk: boolean = !!response?.getReceipt?.receiptId;
          return isResponseOk;
        }
      );
    } catch (err) {
      retValue = buildErrorResponse(err);
    }
    console.log('GetReceipt retValue:', JSON.stringify(retValue, null, 2));
    return retValue;
  }

  // Get all integrations in one call (both Strava and Instagram)
  public async getAthleteIntegrations(): Promise<ITypedBackendResponse<AthleteIntegrationReference>> {
    const client = createClient({
      url: this.backendUrl + '/graphql',
      headers: this.headers,
    });
    
    let retValue: ITypedBackendResponse<AthleteIntegrationReference> = {};
    
    const fields = {
      _id: true,
      athlete: {
        _id: true,
      },
      // Strava fields
      hasStravaIntegration: true,
      stravaTokenExpires: true,
      stravaAthleteData: {
        id: true,
        username: true,
        firstname: true,
        lastname: true,
        bio: true,
        city: true,
        state: true,
        country: true,
        sex: true,
        premium: true,
        profile: true,
        created_at: true,
        updated_at: true,
        weight: true
      },
      // Instagram fields
      hasInstagramIntegration: true,
      instagramTokenExpires: true,
      instagramUserData: {
        user_id: true,
        username: true,
        name: true,
        account_type: true,
        followers_count: true,
        media_count: true
      },
      instagramMediaData: {
        data: {
          id: true,
          caption: true,
          media_type: true,
          media_url: true,
          permalink: true,
          thumbnail_url: true,
          timestamp: true,
          username: true,
          like_count: true,
          comments_count: true,
          insights: {
            data: {
              name: true,
              period: true,
              values: true
            }
          }
        },
        paging: {
          cursors: {
            before: true,
            after: true
          },
          next: true
        }
      }
    };
    
    try {
      const response: any = await client.query({
        getAthleteIntegrations: {
          ...fields
        },
      });
      
      retValue = buildResponse(response, 'getAthleteIntegrations',
        (r: any) => {
          const isResponseOk: boolean = !!response?.getAthleteIntegrations?._id;
          return isResponseOk;
        }
      );
      
    } catch (err) {    
      retValue = buildErrorResponse(err);
    }
    return retValue;
  }

  public async updateAthleteIntegration(type: string) : Promise<ITypedBackendResponse<boolean>> {
    const client = createClient({
      url: this.backendUrl + '/graphql',
      headers: this.headers,
    })

    let retValue: ITypedBackendResponse<boolean> = {}

    try {
      const response: any = await client.mutation({
        updateAthleteIntegration: {
          __args: {
            type: type
          },
        }
      })
      retValue = buildResponse(response, 'updateAthleteIntegration', 
        (r: any) => {
          const isResponseOk: boolean = response?.updateAthleteIntegration === true
          return isResponseOk
        }
      )
    } catch (err){
      retValue = buildErrorResponse(err)
    }
    
    return retValue
  }


  public async deleteUploadedTypeKeyFile(
    dto: AWSS3DeleteUseTypeKeyDto
  ): Promise<ITypedBackendResponse<AWSS3CallResult>> {

    console.log('HEADERS:');
    console.log(JSON.stringify(this.headers, null, 2));

    const client = createClient({
      url: this.backendUrl + '/graphql',
      headers: this.headers,
    });

    let retValue: ITypedBackendResponse<AWSS3CallResult> = {};

    const fields: AWSS3CallResultGenqlSelection = {
      httpStatus: true,
      result: true,
      message: true,
      errors: true
    };

    try {
      const response: any = await client.mutation({
        deleteUploadedTypeKeyFile: {
          __args: {
            input: dto
          },
          ...fields
        },
      });

      console.log('deleteUploadedTypeKeyFile Response:');
      console.log(JSON.stringify(response, null, 2));


      retValue = buildResponse<AWSS3CallResult>(response, 'deleteUploadedTypeKeyFile',
        (r: any) => {
          const isResponseOk: boolean = response?.deleteUploadedTypeKeyFile?.httpStatus;
          return isResponseOk
        }
      );

    } catch (err1) {
      console.error('deleteUploadedTypeKeyFile err1:');
      console.error(err1);

      retValue = buildErrorResponse<AWSS3CallResult>(err1);
    }

    console.log('retValue:');
    console.log(JSON.stringify(retValue, null, 2));
    return retValue;
  }

  public async saveAthleteCompetitionResult(
    dto: SetCompetitionResultDto
  ): Promise<ITypedBackendResponse<AthleteCompetitionResult>> {

    const client = createClient({
      url: this.backendUrl + '/graphql',
      headers: this.headers,
    });


    let retValue: ITypedBackendResponse<AthleteCompetitionResult> = {};

    const fields = {
      _id: true,
      resultType: true,
      position: true,
      score: true,
      finishTimeMS: true,
      resultWebLink: true,
      totalParticipants: true,
      outcome: true,
      adversary: true
    };

    try {
      const response: any = await client.mutation({
        saveAthleteCompetitionResult: {
          __args: {
            input: dto
          },
          ...fields
        },
      });

      VTXBaseAPI.Logger.debug('saveAthleteCompetitionResult Response:');
      VTXBaseAPI.Logger.debug(JSON.stringify(response, null, 2));

      retValue = buildResponse<AthleteCompetitionResult>(response, 'saveAthleteCompetitionResult',
        (r: any) => {
          const isResponseOk: boolean = true && response?.saveAthleteCompetitionResult?._id;
          return isResponseOk
        }
      );

    } catch (err1) {
      VTXBaseAPI.Logger.error('saveAthleteCompetitionResult err1:');
      VTXBaseAPI.Logger.error(err1);

      retValue = buildErrorResponse<AthleteCompetitionResult>(err1);
    }

    return retValue;
  }

  public async updateAthleteScores(): Promise<ITypedBackendResponse<Athlete>> {
    const client = createClient({
      url: this.backendUrl + '/graphql',
      headers: this.headers,
    });
  
    let retValue: ITypedBackendResponse<Athlete> = {};
  
    try {
      const response: any = await client.mutation({
        updateAthleteScores: {
          _id: true,
          firstName: true,
          lastName: true,
          scores: {
            vtxScore: true,
            socialScore: true,
            trainingScore: true,
            competitionScore: true,
          }
        },
      });
  
      retValue = buildResponse(response, 'updateAthleteScores',
        (r: any) => {
          const isResponseOk: boolean = !!response?.updateAthleteScores?._id;
          return isResponseOk;
        }
      );
      
    } catch (err) {    
      retValue = buildErrorResponse(err);
    }
    
    return retValue;
  }


  public async createResetPasswordCode(
    email: string
  ): Promise<ITypedBackendResponse<EditValueResponse>> {

    console.log('HEADERS:');
    console.log(JSON.stringify(this.headers, null, 2));

    const client = createClient({
      url: this.backendUrl + '/graphql',
      headers: this.headers,
    });

    let retValue: ITypedBackendResponse<EditValueResponse> = {};

    const fields: EditValueResponseGenqlSelection = {
      field: true,
      changed: true,
    };

    try {
      const response: any = await client.mutation({
        createResetPasswordCode: {
          __args: {
            input: email
          },
          ...fields
        },
      });

      console.log('createResetPasswordCode Response:');
      console.log(JSON.stringify(response, null, 2));


      retValue = buildResponse<EditValueResponse>(response, 'createResetPasswordCode',
        (r: any) => {
          const isResponseOk: boolean = response?.createResetPasswordCode?.field !== null
          return isResponseOk
        }
      );

    } catch (err1) {
      console.error('createResetPasswordCode err1:');
      console.error(err1);

      retValue = buildErrorResponse<EditValueResponse>(err1);
    }

    console.log('retValue:');
    console.log(JSON.stringify(retValue, null, 2));
    return retValue;
  }

  public async getResetVerificationCode(
    id: string
  ): Promise<ITypedBackendResponse<VerificationCodeType>> {

    console.log('HEADERS:');
    console.log(JSON.stringify(this.headers, null, 2));

    const client = createClient({
      url: this.backendUrl + '/graphql',
      headers: this.headers,
    });

    let retValue: ITypedBackendResponse<VerificationCodeType> = {};

    const fields: VerificationCodeGenqlSelection = {
      _id: true,
      type: true,
      recipient: true,
      expires: true,
      isExpired: true,
      createdDate: true,
    };

    try {
      const response: any = await client.query({
        getResetVerificationCode: {
          __args: {
            input: id
          },
          ...fields
        },
      });

      console.log('getResetVerificationCode Response:');
      console.log(JSON.stringify(response, null, 2));


      retValue = buildResponse<VerificationCodeType>(response, 'getResetVerificationCode',
        (r: any) => {
          const isResponseOk: boolean = response?.getResetVerificationCode?.changed;
          return isResponseOk
        }
      );

    } catch (err1) {
      console.error('getResetVerificationCode err1:');
      console.error(err1);

      retValue = buildErrorResponse<VerificationCodeType>(err1);
    }

    console.log('retValue:');
    console.log(JSON.stringify(retValue, null, 2));
    return retValue;
  }

  public async verifyCode(
    input: VerifyCodeDto
  ): Promise<ITypedBackendResponse<CodeVerificationResponse>> {

    console.log('HEADERS:');
    console.log(JSON.stringify(this.headers, null, 2));

    const client = createClient({
      url: this.backendUrl + '/graphql',
      headers: this.headers,
    });

    let retValue: ITypedBackendResponse<CodeVerificationResponse> = {};

    const fields: CodeVerificationResponseGenqlSelection = {
      result: true,
      code: {
        _id: true,
        type: true,
        recipient: true,
        expires: true,
        isExpired: true,
        createdDate: true,
      },
      error: {
        errorCode: true,
        errorMessage: true,
      }

    };

    try {
      const response: any = await client.query({
        verifyCode: {
          __args: {
            input: input
          },
          ...fields
        },
      });

      console.log('verifyCode Response:');
      console.log(JSON.stringify(response, null, 2));


      retValue = buildResponse<CodeVerificationResponse>(response, 'verifyCode',
        (r: any) => {
          const isResponseOk: boolean = response?.verifyCode?.result === 'success' || response?.verifyCode?.result === 'error';
          return isResponseOk
        }
      );

    } catch (err1) {
      console.error('verifyCode err1:');
      console.error(err1);

      retValue = buildErrorResponse<CodeVerificationResponse>(err1);
    }

    console.log('retValue:');
    console.log(JSON.stringify(retValue, null, 2));
    return retValue;
  }

  public async resetUserPassword(
    input: resetPasswordDto
  ): Promise<ITypedBackendResponse<EditValueResponse>> {

    console.log('HEADERS:');
    console.log(JSON.stringify(this.headers, null, 2));

    const client = createClient({
      url: this.backendUrl + '/graphql',
      headers: this.headers,
    });

    let retValue: ITypedBackendResponse<EditValueResponse> = {};

    const fields: EditValueResponseGenqlSelection = {
      field: true,
      changed: true,

    };

    try {
      const response: any = await client.mutation({
        resetUserPassword: {
          __args: {
            input: input
          },
          ...fields
        },
      });

      console.log('resetUserPassword Response:');
      console.log(JSON.stringify(response, null, 2));


      retValue = buildResponse<EditValueResponse>(response, 'resetUserPassword',
        (r: any) => {
          const isResponseOk: boolean = response?.resetUserPassword?.changed;;
          return isResponseOk
        }
      );

    } catch (err1) {
      console.error('resetUserPassword err1:');
      console.error(err1);

      retValue = buildErrorResponse<EditValueResponse>(err1);
    }

    console.log('retValue:');
    console.log(JSON.stringify(retValue, null, 2));
    return retValue;
  }

  public async deleteAlbumFotos( dto:DeleteValuesDto): Promise<ITypedBackendResponse<DeleteSingleValueResponse>> {

    console.log('HEADERS:');
    console.log(JSON.stringify(this.headers, null, 2));

    const client = createClient({
      url: this.backendUrl + '/graphql',
      headers: this.headers,
    });

    let retValue: ITypedBackendResponse<DeleteSingleValueResponse> = {};

    const fields: DeleteValuesResponseGenqlSelection = {
      deleted: true,
      failedToDelete: true,
      failureReason: {
        code: true,
        message: true
      },
      result: true,
    };

    try {
      const response: any = await client.mutation({
        deleteAthletePhotos: {
          __args: {
            input: dto
          },
          ...fields
        },
      });

      console.log('deleteAthletePhotos Response:');
      console.log(JSON.stringify(response, null, 2));


      retValue = buildResponse<DeleteSingleValueResponse>(response, 'deleteAthletePhotos',
        (r: any) => {
          const isResponseOk: boolean = response?.deleteAthletePhotos?.deleted.length > 0;
          return isResponseOk
        }
      );

    } catch (err1) {
      console.error('deleteAthletePhotos err1:');
      console.error(err1);

      retValue = buildErrorResponse<DeleteSingleValueResponse>(err1);
    }

    console.log('retValue:');
    console.log(JSON.stringify(retValue, null, 2));
    return retValue;
  }

  public async screenNameAviability(
    dto: existValueDto
  ): Promise<ITypedBackendResponse<ExistValueResponse>> {

    console.log('HEADERS:');
    console.log(JSON.stringify(this.headers, null, 2));

    const client = createClient({
      url: this.backendUrl + '/graphql',
      headers: this.headers,
    });

    let retValue: ITypedBackendResponse<ExistValueResponse> = {};

    const fields: ExistValueResponseGenqlSelection = {
      exist: true
    };

    try {
      const response: any = await client.query({
        screenNameAvailability: {
          __args: {
            input: dto
          },
          ...fields
        },
      });

      console.log('screenNameAvailability Response:');
      console.log(JSON.stringify(response, null, 2));


      retValue = buildResponse<ExistValueResponse>(response, 'screenNameAvailability',
        (r: any) => {
          const isResponseOk: boolean = response?.screenNameAvailability?.exist === false || response?.screenNameAvailability?.exist === true;
          return isResponseOk
        }
      );

    } catch (err1) {
      console.error('screenNameAvailability err1:');
      console.error(err1);

      retValue = buildErrorResponse<ExistValueResponse>(err1);
    }

    console.log('retValue:');
    console.log(JSON.stringify(retValue, null, 2));
    return retValue;
  }

}



