import services from '../../../../constants/endpoints.json';
import { trimXML } from '../../helpers/createXMLS';
import { getParam, request } from '../../helpers/request';
import {
  CampPlaceAllResponse,
  CampTypeAllResponse,
  CandidateAllResponse,
  CandidateContactAllResponse,
  CandidateDetailPersonResponse,
  CandidateDetailResponse,
  CandidateEducationSeminaryAllResponse,
  CandidateFunctionAllResponse,
  CandidateQualificationAllResponse,
  CandidateRecommendationAllResponse,
  EventCampAllResponse,
  EventCampDetailResponse,
  EventCampInsertPayload,
  EventCampStateAllResponse,
  EventCampStatisticDetailResponse,
  EventCongressAllResponse,
  EventCongressDecisionAllResponse,
  EventCongressDetailResponse,
  EventCongressFunctionAllMaxResponse,
  EventEducationAllResponse,
  EventEducationCourseAllResponse,
  EventEducationCourseDetailEnrollResponse,
  EventEducationCourseTermAllResponse,
  EventEducationDetailResponse,
  EventEducationGroupAllResponse,
  EventEducationLocationDetailResponse,
  EventEducationOtherDetailResponse,
  EventEducationOtherIllustrativePhotoAllResponse,
  EventEducationTypeAllResponse,
  EventFunctionAllCampPayload,
  EventFunctionAllCampResponse,
  EventFunctionAllGeneralPayload,
  EventFunctionAllGeneralResponse,
  EventGeneralAllResponse,
  EventGeneralDetailResponse,
  EventGeneralInsertPayload,
  EventGeneralScopeAllResponse,
  EventGeneralStateAllResponse,
  EventGeneralTypeAllResponse,
  EventGeneralUpdateReportPayload,
  EventStatisticAllEventGeneralResponse,
  ParticipantCampAllResponse,
  ParticipantCampInsertNewPayload,
  ParticipantCampUpdatePayload,
  ParticipantGeneralAllResponse,
  ParticipantGeneralInsertNewPayload,
  ParticipantGeneralUpdatePayload,
  RegionAllResponse,
} from './types';

const parseString = require('react-native-xml2js').parseString;

export class EventsAPI {
  private config = services.events;

  async eventEducationAllGet(
    token: string,
    name: string,
    year: string,
    groupId: string,
    typeId: string,
  ) {
    const attributes = [
      { name: 'ID_Login', value: token },
      ...(year.length ? [{ name: 'Year', value: year }] : []),
      ...(name.length ? [{ name: 'DisplayName', value: name }] : []),
      ...(groupId.length ? [{ name: 'ID_EventEducationGroup', value: groupId }] : []),
      ...(typeId.length ? [{ name: 'ID_EventEducationType', value: typeId }] : []),
    ];
    return request(this.config.name, this.config.entities.eventEducationAll, attributes).then(
      data => {
        let res: EventEducationAllResponse[] = [];
        parseString(trimXML(data), (_err: any, result: any) => {
          if (result.EventEducationAllResponse.EventEducationAllResult[0] === '') return [];
          res =
            result.EventEducationAllResponse.EventEducationAllResult[0].EventEducationAllOutput?.map(
              (item: any) => {
                const output: EventEducationAllResponse = {
                  id: getParam(item, 'ID'),
                  displayName: getParam(item, 'DisplayName'),
                  type: getParam(item, 'EventEducationType'),
                  relation: getParam(item, 'RelationType'),
                  organization: getParam(item, 'UnitFullName'),
                  capacity: getParam(item, 'CapacityCourse'),
                  logoId: getParam(item, 'ID_DocumentLogo'),
                  loginFrom: getParam(item, 'LoginFrom'),
                  loginTo: getParam(item, 'LoginTo'),
                  loginSkautis: getParam(item, 'LoginSkautis'),
                  loginLocation: getParam(item, 'LoginLocation'),
                  participantEducation: getParam(item, 'ID_ParticipantEducation'),
                  unitId: getParam(item, 'ID_Unit'),
                  enrollId: getParam(item, 'ID_EventEducationCourseEnrollReminder'),
                  educationCourseId: getParam(item, 'ID_EventEducationCourse'),
                  registrationDeadline: getParam(item, 'RegistrationDeadline'),
                  startDate: getParam(item, 'StartDate'),
                  endDate: getParam(item, 'EndDate'),
                };
                return output;
              },
            );
        });
        return res;
      },
    );
  }

  async eventEducationAllMyActionsGet(
    token: string,
    educationType: string,
    isFuture: string,
    year: string,
    relationType: string,
  ) {
    const attributes = [
      { name: 'ID_Login', value: token },
      ...(educationType.length ? [{ name: 'ID_EventEducationType', value: educationType }] : []),
      ...(isFuture.length ? [{ name: 'IsFuture', value: isFuture }] : []),
      ...(year.length ? [{ name: 'Year', value: year }] : []),
      ...(relationType.length ? [{ name: 'ID_RelationType', value: relationType }] : []),
    ];
    return request(
      this.config.name,
      this.config.entities.eventEducationAllMyActions,
      attributes,
    ).then(data => {
      let res: EventEducationAllResponse[] = [];
      parseString(trimXML(data), (_err: any, result: any) => {
        if (result.EventEducationAllMyActionsResponse.EventEducationAllMyActionsResult[0] === '')
          return [];
        res =
          result.EventEducationAllMyActionsResponse.EventEducationAllMyActionsResult[0].EventEducationAllMyActionsOutput?.map(
            (item: any) => {
              const output: EventEducationAllResponse = {
                id: getParam(item, 'ID'),
                displayName: getParam(item, 'DisplayName'),
                type: getParam(item, 'EventEducationType'),
                relation: getParam(item, 'RelationType'),
                organization: getParam(item, 'UnitFullName'),
                capacity: getParam(item, 'CapacityCourse'),
                logoId: getParam(item, 'ID_DocumentLogo'),
                loginFrom: getParam(item, 'LoginFrom'),
                loginTo: getParam(item, 'LoginTo'),
                loginSkautis: getParam(item, 'LoginSkautis'),
                loginLocation: getParam(item, 'LoginLocation'),
                participantEducation: getParam(item, 'ID_ParticipantEducation'),
                unitId: getParam(item, 'ID_Unit'),
                enrollId: getParam(item, 'ID_EventEducationCourseEnrollReminder'),
                educationCourseId: getParam(item, 'ID_EventEducationCourse'),
                registrationDeadline: getParam(item, 'RegistrationDeadline'),
                startDate: getParam(item, 'StartDate'),
                endDate: getParam(item, 'EndDate'),
              };
              return output;
            },
          );
      });
      return res;
    });
  }

  async eventEducationTypeAllGet(token: string) {
    const attributes = [{ name: 'ID_Login', value: token }];
    return request(this.config.name, this.config.entities.eventEducationTypeAll, attributes).then(
      data => {
        let res: EventEducationTypeAllResponse[] = [];
        parseString(trimXML(data), (_err: any, result: any) => {
          if (result.EventEducationTypeAllResponse.EventEducationTypeAllResult[0] === '') return [];
          res =
            result.EventEducationTypeAllResponse.EventEducationTypeAllResult[0].EventEducationTypeAllOutput?.map(
              (item: any) => {
                const output: EventEducationTypeAllResponse = {
                  id: getParam(item, 'ID'),
                  displayName: getParam(item, 'DisplayName'),
                };
                return output;
              },
            );
        });
        return res;
      },
    );
  }

  async eventEducationGroupAllGet(token: string) {
    const attributes = [{ name: 'ID_Login', value: token }];
    return request(this.config.name, this.config.entities.eventEducationGroupAll, attributes).then(
      data => {
        let res: EventEducationGroupAllResponse[] = [];
        parseString(trimXML(data), (_err: any, result: any) => {
          if (result.EventEducationGroupAllResponse.EventEducationGroupAllResult[0] === '')
            return [];
          res =
            result.EventEducationGroupAllResponse.EventEducationGroupAllResult[0].EventEducationGroupAllOutput?.map(
              (item: any) => {
                const output: EventEducationTypeAllResponse = {
                  id: getParam(item, 'ID'),
                  displayName: getParam(item, 'DisplayName'),
                };
                return output;
              },
            );
        });
        return res;
      },
    );
  }

  async eventEducationCourseDetailEnrollGet(token: string, personId: string, educationId: string) {
    const attributes = [
      { name: 'ID_Login', value: token },
      { name: 'ID_Person', value: personId },
      { name: 'ID', value: educationId },
    ];
    return request(
      this.config.name,
      this.config.entities.eventEducationCourseDetailEnroll,
      attributes,
    )
      .then(data => {
        let res: EventEducationCourseDetailEnrollResponse | undefined;
        parseString(trimXML(data), (_err: any, result: any) => {
          const item =
            result.EventEducationCourseDetailEnrollResponse
              .EventEducationCourseDetailEnrollResult[0];

          res = {
            id: getParam(item, 'ID'),
            displayName: getParam(item, 'EventEducation'),
            type: getParam(item, 'EventEducationType'),
            organization: getParam(item, 'UnitNameWithRegistrationNumber'),
            loginFrom: getParam(item, 'LoginFrom'),
            loginTo: getParam(item, 'LoginTo'),
            person: getParam(item, 'Person'),
            personIdentificationCode: getParam(item, 'IdentificationCode'),
            personUnit: getParam(item, 'UnitMembershipWithRegistrationNumber'),
            personAddress: getParam(item, 'Address'),
            personEmail: getParam(item, 'PersonEmail'),
            personPhone: getParam(item, 'PersonPhone'),
            isVerdictGroupRequired: getParam(item, 'IsVerdictGroupRequired') === 'true',
            isVerdictDistrictRequired: getParam(item, 'IsVerdictDistrictRequired') === 'true',
            isVerdictAreaRequired: getParam(item, 'IsVerdictAreaRequired') === 'true',
            isVerdictHealthRequired: getParam(item, 'IsVerdictHealthRequired') === 'true',
            personVerdictGroup: getParam(item, 'PersonVerdictGroup'),
            dateVerdictGroup: getParam(item, 'DateVerdictGroup'),
            verdictGroup: getParam(item, 'VerdictGroup'),
            personVerdictDistrict: getParam(item, 'PersonVerdictDistrict'),
            dateVerdictDistrict: getParam(item, 'DateVerdictDistrict'),
            verdictDistrict: getParam(item, 'VerdictDistrict'),
            personVerdictArea: getParam(item, 'PersonVerdictArea'),
            dateVerdictArea: getParam(item, 'DateVerdictArea'),
            verdictArea: getParam(item, 'VerdictArea'),
            personVerdictHealth: getParam(item, 'PersonVerdictHealth'),
            dateVerdictHealth: getParam(item, 'DateVerdictHealth'),
            verdictHealthDocumentId: getParam(item, 'ID_DocumentVerdictHealth'),
          };
        });
        return res;
      })
      .catch(err => {
        return err;
      });
  }

  async eventEducationDetailGet(token: string, educationId: string) {
    const attributes = [
      { name: 'ID_Login', value: token },
      { name: 'ID', value: educationId },
    ];
    return request(this.config.name, this.config.entities.eventEducationDetail, attributes).then(
      data => {
        let res: EventEducationDetailResponse | undefined;
        parseString(trimXML(data), (_err: any, result: any) => {
          const item = result.EventEducationDetailResponse.EventEducationDetailResult[0];
          res = {
            id: getParam(item, 'ID'),
            displayName: getParam(item, 'EventEducation'),
            loginSkautis: getParam(item, 'LoginSkautis'),
            loginLocation: getParam(item, 'LoginLocation'),
            loginFrom: getParam(item, 'LoginFrom'),
            loginTo: getParam(item, 'LoginTo'),
            web: getParam(item, 'Web'),
            registrationNumber: getParam(item, 'RegistrationNumber'),
            location: getParam(item, 'Location'),
            unitId: getParam(item, 'ID_Unit'),
            unit: getParam(item, 'Unit'),
            contactEmail: getParam(item, 'EmailContact'),
            contactPhone: getParam(item, 'PhoneContact'),
            note: getParam(item, 'Note'),
            startDate: getParam(item, 'StartDate'),
            endDate: getParam(item, 'EndDate'),
            dateUnitApproved: getParam(item, 'DateUnitApproved'),
            publicized: getParam(item, 'Publicized'),
            approved: getParam(item, 'Approved'),
            grant: getParam(item, 'GrantNew'),
            grantDecision: getParam(item, 'GrantDecisionNew'),
            grantDecisionConfirmed: getParam(item, 'GrantDecisionConfirmed'),
            advanceSent: getParam(item, 'AdvanceSent'),
            isForester: getParam(item, 'IsForester') === 'true',
            isQualifyingExam: getParam(item, 'IsQualifyingExam') === 'true',
            hasGrantRequest: getParam(item, 'HasGrantRequest') === 'true',
          };
        });
        return res;
      },
    );
  }

  async eventEducationCourseAllGet(token: string, educationId: string) {
    const attributes = [
      { name: 'ID_Login', value: token },
      { name: 'ID_EventEducation', value: educationId },
    ];
    return request(this.config.name, this.config.entities.eventEducationCourseAll, attributes).then(
      data => {
        let res: EventEducationCourseAllResponse[] = [];
        parseString(trimXML(data), (_err: any, result: any) => {
          if (result.EventEducationCourseAllResponse.EventEducationCourseAllResult[0] === '')
            return [];
          res =
            result.EventEducationCourseAllResponse.EventEducationCourseAllResult[0].EventEducationCourseAllOutput?.map(
              (item: any) => {
                const output: EventEducationCourseAllResponse = {
                  id: getParam(item, 'ID'),
                  type: getParam(item, 'EventEducationType'),
                  capacity: getParam(item, 'Occupation'),
                  courseCapacity: getParam(item, 'CapacityCourse'),
                  substituteCapacity: getParam(item, 'CapacitySubstitute'),
                  deadline: getParam(item, 'RegistrationDeadline'),
                  estimateCapacity: getParam(item, 'EstimatedParticipantCount'),
                  personDays: getParam(item, 'PersonDays'),
                  note: getParam(item, 'Note'),
                };
                return output;
              },
            );
        });
        return res;
      },
    );
  }

  async eventEducationCourseTermAllGet(token: string, educationId: string) {
    const attributes = [
      { name: 'ID_Login', value: token },
      { name: 'ID_EventEducation', value: educationId },
    ];
    return request(
      this.config.name,
      this.config.entities.eventEducationCourseTermAll,
      attributes,
    ).then(data => {
      let res: EventEducationCourseTermAllResponse[] = [];
      parseString(trimXML(data), (_err: any, result: any) => {
        if (result.EventEducationCourseTermAllResponse.EventEducationCourseTermAllResult[0] === '')
          return [];
        res =
          result.EventEducationCourseTermAllResponse.EventEducationCourseTermAllResult[0].EventEducationCourseTermAllOutput?.map(
            (item: any) => {
              const output: EventEducationCourseTermAllResponse = {
                locationId: getParam(item, 'ID_EventEducationLocation'),
                location: getParam(item, 'EventEducationLocation'),
                course: getParam(item, 'EventEducationCourse'),
                date: getParam(item, 'EventEducationTerm'),
              };
              return output;
            },
          );
      });
      return res;
    });
  }

  async eventEducationLocationDetailGet(token: string, locationId: string) {
    const attributes = [
      { name: 'ID_Login', value: token },
      { name: 'ID', value: locationId },
    ];
    return request(
      this.config.name,
      this.config.entities.eventEducationLocationDetail,
      attributes,
    ).then(data => {
      let res: EventEducationLocationDetailResponse | undefined;
      parseString(trimXML(data), (_err: any, result: any) => {
        const item =
          result.EventEducationLocationDetailResponse.EventEducationLocationDetailResult[0];
        res = {
          id: locationId,
          firstLine: getParam(item, 'FirstLine'),
          street: getParam(item, 'Street'),
          postcode: getParam(item, 'Postcode'),
          city: getParam(item, 'City'),
          region: getParam(item, 'Region'),
          latitude: getParam(item, 'Latitude'),
          longitude: getParam(item, 'Longitude'),
          note: getParam(item, 'Note'),
        };
      });
      return res;
    });
  }

  async eventEducationCourseEnrollReminderAdd(
    token: string,
    personId: string,
    id: string,
    educationId: string,
    hours: string,
  ) {
    const attributes = [
      { name: 'ID_Login', value: token },
      { name: 'ID_Person', value: personId },
      { name: 'ID', value: id },
      { name: 'ID_EventEducationCourse', value: educationId },
      { name: 'Hours', value: hours },
    ];

    return request(
      this.config.name,
      this.config.entities.eventEducationCourseEnrollReminderInsert,
      attributes,
    ).then(data => {
      let res: string | undefined;
      parseString(trimXML(data), (_err: any, result: any) => {
        const item =
          result.EventEducationCourseEnrollReminderInsertResponse
            .EventEducationCourseEnrollReminderInsertResult[0];
        res = getParam(item, 'ID');
      });
      return res;
    });
  }

  async eventEducationCourseEnrollReminderDelete(token: string, reminderId: string) {
    const attributes = [
      { name: 'ID_Login', value: token },
      { name: 'ID', value: reminderId },
    ];
    return request(
      this.config.name,
      this.config.entities.eventEducationCourseEnrollReminderDelete,
      attributes,
    ).then(() => {});
  }

  async eventEducationCourseEnrollReminderDetailGet(token: string, reminderId: string) {
    const attributes = [
      { name: 'ID_Login', value: token },
      { name: 'ID', value: reminderId },
    ];

    return request(
      this.config.name,
      this.config.entities.eventEducationCourseEnrollReminderDetail,
      attributes,
    ).then(data => {
      let res: string | undefined;
      parseString(trimXML(data), (_err: any, result: any) => {
        const item =
          result.EventEducationCourseEnrollReminderDetailResponse
            .EventEducationCourseEnrollReminderDetailResult[0];
        res = getParam(item, 'Hours');
      });
      return res;
    });
  }

  async eventEducationOtherDetailGet(token: string, educationId: string, courseId: string) {
    const attributes = [
      { name: 'ID_Login', value: token },
      { name: 'ID_EventEducation', value: educationId },
      ...(courseId.length ? [{ name: 'ID_EventEducationCourse', value: courseId }] : []),
    ];
    return request(
      this.config.name,
      this.config.entities.eventEducationOtherDetail,
      attributes,
    ).then(data => {
      let res: EventEducationOtherDetailResponse | undefined;
      parseString(trimXML(data), (_err: any, result: any) => {
        const item = result.EventEducationOtherDetailResponse.EventEducationOtherDetailResult[0];
        res = {
          education: getParam(item, 'EventEducation'),
          description: getParam(item, 'ShortDescription'),
          annotation: getParam(item, 'Annotation'),
          targetGroup: getParam(item, 'TargetGroup'),
          focus: getParam(item, 'EventFocus'),
          entryConditions: getParam(item, 'EntryConditions'),
          graduateConditions: getParam(item, 'GraduateConditions'),
          authenticationForm: getParam(item, 'AuthenticationForm'),
          fee: getParam(item, 'ParticipantFee'),
          nextOccurrenceYear: getParam(item, 'NextOccurrenceYear'),
          frequency: getParam(item, 'CourseFrequency'),
          graduates: getParam(item, 'Graduates'),
          isChildFriendly: getParam(item, 'IsChildFriendly') === 'true',
          isAgeRestricted: getParam(item, 'IsAgeRestricted') === 'true',
          history: getParam(item, 'EventHistory'),
          photoGallery: getParam(item, 'PhotoGallery'),
        };
      });
      return res;
    });
  }

  async eventEducationOtherIllustrativePhotoAllGet(
    token: string,
    educationId: string,
    courseId: string,
  ) {
    const attributes = [
      { name: 'ID_Login', value: token },
      { name: 'ID_EventEducation', value: educationId },
      ...(courseId.length ? [{ name: 'ID_EventEducationCourse', value: courseId }] : []),
    ];
    return request(
      this.config.name,
      this.config.entities.eventEducationOtherIllustrativePhotoAll,
      attributes,
    ).then(data => {
      let res: EventEducationOtherIllustrativePhotoAllResponse[] = [];
      parseString(trimXML(data), (_err: any, result: any) => {
        if (
          result.EventEducationOtherIllustrativePhotoAllResponse
            .EventEducationOtherIllustrativePhotoAllResult[0] === ''
        )
          return [];
        res =
          result.EventEducationOtherIllustrativePhotoAllResponse.EventEducationOtherIllustrativePhotoAllResult[0].EventEducationOtherIllustrativePhotoAllOutput?.map(
            (item: any) => {
              const output: EventEducationOtherIllustrativePhotoAllResponse = {
                displayName: getParam(item, 'DisplayName'),
                documentId: getParam(item, 'ID_Document'),
                documentIdSmall: getParam(item, 'ID_DocumentSmall'),
              };
              return output;
            },
          );
      });
      return res;
    });
  }

  async eventCongressAllGet(
    token: string,
    isFuture: string,
    isUnit: string,
    isChildDirect: string,
    isChildUnit: string,
    isParticipant: string,
  ) {
    const attributes = [
      { name: 'ID_Login', value: token },
      ...(isFuture.length ? [{ name: 'IsFuture', value: isFuture }] : []),
      ...(isUnit.length ? [{ name: 'IsUnit', value: isUnit }] : []),
      ...(isChildDirect.length ? [{ name: 'IsChildDirect', value: isChildDirect }] : []),
      ...(isChildUnit.length ? [{ name: 'IsChildUnit', value: isChildUnit }] : []),
      ...(isParticipant.length ? [{ name: 'IsParticipant', value: isParticipant }] : []),
    ];
    return request(this.config.name, this.config.entities.eventCongressAll, attributes).then(
      data => {
        let res: EventCongressAllResponse[] = [];
        parseString(trimXML(data), (_err: any, result: any) => {
          if (result.EventCongressAllResponse.EventCongressAllResult[0] === '') return [];
          res =
            result.EventCongressAllResponse.EventCongressAllResult[0].EventCongressAllOutput?.map(
              (item: any) => {
                const output: EventCongressAllResponse = {
                  id: getParam(item, 'ID'),
                  eventName: getParam(item, 'Event'),
                  type: getParam(item, 'EventCongressType'),
                  location: getParam(item, 'Location'),
                  unitId: getParam(item, 'ID_Unit'),
                  unit: getParam(item, 'Unit'),
                  startDate: getParam(item, 'StartDate'),
                  endDate: getParam(item, 'EndDate'),
                };
                return output;
              },
            );
        });
        return res;
      },
    );
  }

  async eventCongressDetailGet(token: string, congressId: string) {
    const attributes = [
      { name: 'ID_Login', value: token },
      { name: 'ID', value: congressId },
    ];
    return request(this.config.name, this.config.entities.eventCongressDetail, attributes).then(
      data => {
        let res: EventCongressDetailResponse | undefined;
        parseString(trimXML(data), (_err: any, result: any) => {
          const item = result.EventCongressDetailResponse.EventCongressDetailResult[0];
          res = {
            id: getParam(item, 'ID'),
            type: getParam(item, 'EventCongressType'),
            state: getParam(item, 'EventCongressState'),
            unitId: getParam(item, 'ID_Unit'),
            unit: getParam(item, 'Unit'),
            registrationNumber: getParam(item, 'RegistrationNumber'),
            unitRegistration: getParam(item, 'UnitRegistration'),
            unitRegistrationId: getParam(item, 'ID_UnitRegistration'),
            promulgationDeadline: getParam(item, 'PromulgationDeadline'),
            startDate: getParam(item, 'StartDate'),
            endDate: getParam(item, 'EndDate'),
            commissionDeadline: getParam(item, 'CommissionDeadline'),
            candidateDeadline: getParam(item, 'CandidateDeadline'),
            location: getParam(item, 'Location'),
            latitude: getParam(item, 'GpsLatitude'),
            longitude: getParam(item, 'GpsLongitude'),
            note: getParam(item, 'Note'),
            alternativeLocation: getParam(item, 'AlternativeLocation'),
            alternativeStartDate: getParam(item, 'AlternativeStartDate'),
            alternativeEndDate: getParam(item, 'AlternativeEndDate'),
            alternativeLatitude: getParam(item, 'AlternateGpsLatitude'),
            alternativeLongitude: getParam(item, 'AlternateGpsLongitude'),
            arriveDeadline: getParam(item, 'ArriveDeadline'),
            departureDeadline: getParam(item, 'DepartureDeadline'),
            transportDeadline: getParam(item, 'TransportDeadline'),
            accommodationDeadline: getParam(item, 'AccommodationDeadline'),
            foodDeadline: getParam(item, 'FoodDeadline'),
            participantFee: getParam(item, 'ParticipantFee'),
          };
        });
        return res;
      },
    );
  }

  async candidateAllGet(token: string, congressId: string) {
    const attributes = [
      { name: 'ID_Login', value: token },
      { name: 'ID_EventCongress', value: congressId },
    ];
    return request(this.config.name, this.config.entities.candidateAll, attributes)
      .then(data => {
        let res: CandidateAllResponse[] = [];
        parseString(trimXML(data), (_err: any, result: any) => {
          if (result.CandidateAllResponse.CandidateAllResult[0] === '') return [];
          res = result.CandidateAllResponse.CandidateAllResult[0].CandidateAllOutput?.map(
            (item: any) => {
              const output: CandidateAllResponse = {
                id: getParam(item, 'ID'),
                state: getParam(item, 'ID_CandidateState'),
                personId: getParam(item, 'ID_Person'),
                person: getParam(item, 'Person'),
                personWith: getParam(item, 'PersonWith'),
                congressFunction: getParam(item, 'EventCongressFunction'),
                function: getParam(item, 'EventCongressFunction'),
                order: getParam(item, 'Order'),
                votesCount: getParam(item, 'VotesCount'),
                isElected: getParam(item, 'IsElected') === 'true',
              };
              return output;
            },
          );
        });
        return res;
      })
      .catch(err => {
        return [err];
      });
  }

  async candidateContactAllGet(token: string, candidateId: string) {
    const attributes = [
      { name: 'ID_Login', value: token },
      { name: 'ID_Candidate', value: candidateId },
    ];
    return request(this.config.name, this.config.entities.candidateContactAll, attributes).then(
      data => {
        let res: CandidateContactAllResponse[] = [];
        parseString(trimXML(data), (_err: any, result: any) => {
          if (result.CandidateContactAllResponse.CandidateContactAllResult[0] === '') return [];
          res =
            result.CandidateContactAllResponse.CandidateContactAllResult[0].CandidateContactAllOutput?.map(
              (item: any) => {
                const output: CandidateContactAllResponse = {
                  contactType: getParam(item, 'ContactType'),
                  value: getParam(item, 'Value'),
                  note: getParam(item, 'Note'),
                };
                return output;
              },
            );
        });
        return res;
      },
    );
  }

  async candidateDetailGet(token: string, candidateId: string) {
    const attributes = [
      { name: 'ID_Login', value: token },
      { name: 'ID', value: candidateId },
    ];
    return request(this.config.name, this.config.entities.candidateDetail, attributes).then(
      data => {
        let res: CandidateDetailResponse | undefined;
        parseString(trimXML(data), (_err: any, result: any) => {
          const item = result.CandidateDetailResponse.CandidateDetailResult[0];
          res = {
            congress: getParam(item, 'EventCongress'),
            function: getParam(item, 'EventCongressFunction'),
            personCreate: getParam(item, 'PersonCreate'),
            dateCreate: getParam(item, 'DateCreate'),
            displayName: getParam(item, 'DisplayName'),
            personWith: getParam(item, 'PersonWith'),
            career: getParam(item, 'Career'),
            presentation: getParam(item, 'Presentation'),
            suggesterName: getParam(item, 'SuggesterName'),
            suggesterFunction: getParam(item, 'SuggesterFunction'),
            suggesterDescription: getParam(item, 'SuggesterDescription'),
          };
        });
        return res;
      },
    );
  }

  async candidateDetailPersonGet(token: string, candidateId: string) {
    const attributes = [
      { name: 'ID_Login', value: token },
      { name: 'ID', value: candidateId },
    ];
    return request(this.config.name, this.config.entities.candidateDetailPerson, attributes).then(
      data => {
        let res: CandidateDetailPersonResponse | undefined;
        parseString(trimXML(data), (_err: any, result: any) => {
          const item = result.CandidateDetailPersonResponse.CandidateDetailPersonResult[0];
          const person = item.Person[0];
          res = {
            degreeInFront: getParam(person, 'DegreeInFrontOf'),
            degreeBehind: getParam(person, 'DegreeBehind'),
            firstName: getParam(person, 'FirstName'),
            lastName: getParam(person, 'LastName'),
            nickName: getParam(person, 'NickName'),
            birthday: getParam(person, 'Birthday'),
            city: getParam(person, 'City'),
            yearFrom: getParam(person, 'YearFrom'),
            unit: item.Registration ? getParam(item.Registration[0], 'Unit') : '',
          };
        });
        return res;
      },
    );
  }

  async candidateEducationSeminaryAllGet(token: string, candidateId: string) {
    const attributes = [
      { name: 'ID_Login', value: token },
      { name: 'ID_Candidate', value: candidateId },
    ];
    return request(
      this.config.name,
      this.config.entities.candidateEducationSeminaryAll,
      attributes,
    ).then(data => {
      let res: CandidateEducationSeminaryAllResponse[] = [];
      parseString(trimXML(data), (_err: any, result: any) => {
        if (
          result.CandidateEducationSeminaryAllResponse.CandidateEducationSeminaryAllResult[0] === ''
        )
          return [];
        res =
          result.CandidateEducationSeminaryAllResponse.CandidateEducationSeminaryAllResult[0].CandidateEducationSeminaryAllOutput?.map(
            (item: any) => {
              const output: CandidateEducationSeminaryAllResponse = {
                seminary: getParam(item, 'EducationSeminary'),
                yearFrom: getParam(item, 'YearFrom'),
              };
              return output;
            },
          );
      });
      return res;
    });
  }

  async candidateFunctionAllGet(token: string, candidateId: string) {
    const attributes = [
      { name: 'ID_Login', value: token },
      { name: 'ID_Candidate', value: candidateId },
    ];
    return request(this.config.name, this.config.entities.candidateFunctionAll, attributes).then(
      data => {
        let res: CandidateFunctionAllResponse[] = [];
        parseString(trimXML(data), (_err: any, result: any) => {
          if (result.CandidateFunctionAllResponse.CandidateFunctionAllResult[0] === '') return [];
          res =
            result.CandidateFunctionAllResponse.CandidateFunctionAllResult[0].CandidateFunctionAllOutput?.map(
              (item: any) => {
                const output: CandidateFunctionAllResponse = {
                  type: getParam(item, 'FunctionType'),
                  unit: getParam(item, 'Unit'),
                  validFrom: getParam(item, 'ValidFrom'),
                  validTo: getParam(item, 'ValidTo'),
                };
                return output;
              },
            );
        });
        return res;
      },
    );
  }

  async candidateQualificationAllGet(token: string, candidateId: string) {
    const attributes = [
      { name: 'ID_Login', value: token },
      { name: 'ID_Candidate', value: candidateId },
    ];
    return request(
      this.config.name,
      this.config.entities.candidateQualificationAll,
      attributes,
    ).then(data => {
      let res: CandidateQualificationAllResponse[] = [];
      parseString(trimXML(data), (_err: any, result: any) => {
        if (result.CandidateQualificationAllResponse.CandidateQualificationAllResult[0] === '')
          return [];
        res =
          result.CandidateQualificationAllResponse.CandidateQualificationAllResult[0].CandidateQualificationAllOutput?.map(
            (item: any) => {
              const output: CandidateQualificationAllResponse = {
                type: getParam(item, 'QualificationType'),
                validFrom: getParam(item, 'ValidFrom'),
                note: getParam(item, 'Note'),
              };
              return output;
            },
          );
      });
      return res;
    });
  }

  async candidateRecommendationAllGet(token: string, candidateId: string) {
    const attributes = [
      { name: 'ID_Login', value: token },
      { name: 'ID_Candidate', value: candidateId },
    ];
    return request(
      this.config.name,
      this.config.entities.candidateRecommendationAll,
      attributes,
    ).then(data => {
      let res: CandidateRecommendationAllResponse[] = [];
      parseString(trimXML(data), (_err: any, result: any) => {
        if (result.CandidateRecommendationAllResponse.CandidateRecommendationAllResult[0] === '')
          return [];
        res =
          result.CandidateRecommendationAllResponse.CandidateRecommendationAllResult[0].CandidateRecommendationAllOutput?.map(
            (item: any) => {
              const output: CandidateRecommendationAllResponse = {
                displayName: getParam(item, 'DisplayName'),
                relation: getParam(item, 'Relation'),
                description: getParam(item, 'Description'),
              };
              return output;
            },
          );
      });
      return res;
    });
  }

  async eventCongressFunctionAllMaxGet(token: string, congressId: string) {
    const attributes = [
      { name: 'ID_Login', value: token },
      { name: 'ID_EventCongress', value: congressId },
    ];
    return request(
      this.config.name,
      this.config.entities.eventCongressFunctionAllMax,
      attributes,
    ).then(data => {
      let res: EventCongressFunctionAllMaxResponse[] = [];
      parseString(trimXML(data), (_err: any, result: any) => {
        if (result.EventCongressFunctionAllMaxResponse.EventCongressFunctionAllMaxResult[0] === '')
          return [];
        res =
          result.EventCongressFunctionAllMaxResponse.EventCongressFunctionAllMaxResult[0].EventCongressFunctionAllMaxOutput?.map(
            (item: any) => {
              const output: EventCongressFunctionAllMaxResponse = {
                type: getParam(item, 'FunctionType'),
                count: getParam(item, 'MaxCount'),
              };
              return output;
            },
          );
      });
      return res;
    });
  }

  async eventCongressDecisionAllGet(token: string, congressId: string) {
    const attributes = [
      { name: 'ID_Login', value: token },
      { name: 'ID_EventCongress', value: congressId },
    ];
    return request(this.config.name, this.config.entities.eventCongressDecisionAll, attributes)
      .then(data => {
        let res: EventCongressDecisionAllResponse[] = [];
        parseString(trimXML(data), (_err: any, result: any) => {
          if (result.EventCongressDecisionAllResponse.EventCongressDecisionAllResult[0] === '')
            return [];
          res =
            result.EventCongressDecisionAllResponse.EventCongressDecisionAllResult[0].EventCongressDecisionAllOutput?.map(
              (item: any) => {
                const output: EventCongressDecisionAllResponse = {
                  type: getParam(item, 'UnitType'),
                  decisionType: getParam(item, 'EventCongressDecisionType'),
                  text: getParam(item, 'Text'),
                  decision: getParam(item, 'Decision'),
                  suggester: getParam(item, 'Suggester'),
                };
                return output;
              },
            );
        });
        return res;
      })
      .catch(err => {
        return [err];
      });
  }

  async eventCampStatesAllGet(token: string) {
    const attributes = [{ name: 'ID_Login', value: token }];
    return request(this.config.name, this.config.entities.eventCampStateAll, attributes).then(
      data => {
        let res: EventCampStateAllResponse[] = [];
        parseString(trimXML(data), (_err: any, result: any) => {
          if (result.EventCampStateAllResponse.EventCampStateAllResult[0] === '') return [];
          res =
            result.EventCampStateAllResponse.EventCampStateAllResult[0].EventCampStateAllOutput?.map(
              (item: any) => {
                const output: EventCampStateAllResponse = {
                  id: getParam(item, 'ID'),
                  displayName: getParam(item, 'DisplayName'),
                };
                return output;
              },
            );
        });
        return res;
      },
    );
  }

  async eventCampAllGet(
    token: string,
    name: string,
    isFuture: string,
    year: string,
    isRelation: string,
    isChildDirect: string,
    isChildUnit: string,
    regNumber: string,
    location: string,
  ) {
    const attributes = [
      { name: 'ID_Login', value: token },
      ...(name.length ? [{ name: 'DisplayName', value: name }] : []),
      ...(isFuture.length ? [{ name: 'IsFuture', value: isFuture }] : []),
      ...(year.length ? [{ name: 'Year', value: year }] : []),
      ...(isRelation.length ? [{ name: 'IsRelation', value: isRelation }] : []),
      ...(isChildDirect.length ? [{ name: 'IsChildDirect', value: isChildDirect }] : []),
      ...(isChildUnit.length ? [{ name: 'IsChildUnit', value: isChildUnit }] : []),
      ...(regNumber.length ? [{ name: 'RegistrationNumber', value: regNumber }] : []),
      ...(location.length ? [{ name: 'Location', value: location }] : []),
    ];
    return request(this.config.name, this.config.entities.eventCampAll, attributes).then(data => {
      let res: EventCampAllResponse[] = [];
      parseString(trimXML(data), (_err: any, result: any) => {
        if (result.EventCampAllResponse.EventCampAllResult[0] === '') return [];
        res = result.EventCampAllResponse.EventCampAllResult[0].EventCampAllOutput?.map(
          (item: any) => {
            const output: EventCampAllResponse = {
              id: getParam(item, 'ID'),
              displayName: getParam(item, 'DisplayName'),
              state: getParam(item, 'EventCampState'),
              startDate: getParam(item, 'StartDate'),
              endDate: getParam(item, 'EndDate'),
              regNumber: getParam(item, 'RegistrationNumber'),
              unit: getParam(item, 'Unit'),
              unitId: getParam(item, 'ID_Unit'),
              location: getParam(item, 'Location'),
              personLeader: getParam(item, 'PersonLeader'),
              mobile: getParam(item, 'MobileContactDisplay'),
              dateReal: getParam(item, 'DateReal'),
            };
            return output;
          },
        );
      });
      return res;
    });
  }

  async eventCampDetailGet(token: string, campId: string) {
    const attributes = [
      { name: 'ID_Login', value: token },
      { name: 'ID', value: campId },
    ];
    return request(this.config.name, this.config.entities.eventCampDetail, attributes).then(
      data => {
        let res: EventCampDetailResponse | undefined;
        parseString(trimXML(data), (_err: any, result: any) => {
          const item = result.EventCampDetailResponse.EventCampDetailResult[0];
          res = {
            id: getParam(item, 'ID'),
            displayName: getParam(item, 'DisplayName'),
            unit: getParam(item, 'Unit'),
            unitId: getParam(item, 'ID_Unit'),
            regNumber: getParam(item, 'RegistrationNumber'),
            state: getParam(item, 'EventCampState'),
            stateId: getParam(item, 'ID_EventCampState'),
            type: getParam(item, 'CampType'),
            startDate: getParam(item, 'StartDate'),
            endDate: getParam(item, 'EndDate'),
            totalDays: getParam(item, 'TotalDays'),
            isRecovering: getParam(item, 'IsRecovering') === 'true',
            mobile: getParam(item, 'MobileContactDisplay'),
            campPlace: getParam(item, 'CampPlace'),
            campPlaceId: getParam(item, 'ID_CampPlace'),
            region: getParam(item, 'Region'),
            location: getParam(item, 'Location'),
            postcode: getParam(item, 'Postcode'),
            isFloodArea: getParam(item, 'IsFloodArea') === 'true',
            note: getParam(item, 'Note'),
            latitude: getParam(item, 'GpsLatitude'),
            longitude: getParam(item, 'GpsLongitude'),
            unitIds: item?.ID_UnitArray[0]?.string,
            estimateAdult: getParam(item, 'EstimateAdult'),
            realAdult: getParam(item, 'RealAdult'),
            estimateCount: getParam(item, 'EstimateCount'),
            realCount: getParam(item, 'RealCount'),
            estimateChildDays: getParam(item, 'EstimateChildDays'),
            realChildDays: getParam(item, 'RealChildDays'),
            estimatePersonDays: getParam(item, 'EstimatePersonDays'),
            realPersonDays: getParam(item, 'RealPersonDays'),
            personApproved: getParam(item, 'PersonApproved'),
            dateApproved: getParam(item, 'DateApproved'),
            personApprovedParent: getParam(item, 'PersonApprovedParent'),
            dateApprovedParent: getParam(item, 'DateApprovedParent'),
            dateApprovedExecutive: getParam(item, 'DateApprovedExecutive'),
            personReal: getParam(item, 'PersonReal'),
            dateReal: getParam(item, 'DateReal'),
          };
        });
        return res;
      },
    );
  }

  async eventFunctionAllCampGet(token: string, campId: string) {
    const attributes = [
      { name: 'ID_Login', value: token },
      { name: 'ID_EventCamp', value: campId },
    ];
    return request(this.config.name, this.config.entities.eventFunctionAllCamp, attributes).then(
      data => {
        let res: EventFunctionAllCampResponse[] = [];
        parseString(trimXML(data), (_err: any, result: any) => {
          if (result.EventFunctionAllCampResponse.EventFunctionAllCampResult[0] === '') return [];
          res =
            result.EventFunctionAllCampResponse.EventFunctionAllCampResult[0].EventFunctionAllCampOutput?.map(
              (item: any) => {
                const output: EventFunctionAllCampResponse = {
                  id: getParam(item, 'ID'),
                  name: getParam(item, 'Person'),
                  personId: getParam(item, 'ID_Person'),
                  role: getParam(item, 'EventFunctionType'),
                  note: getParam(item, 'Note'),
                };
                return output;
              },
            );
        });
        return res;
      },
    );
  }

  async eventCampUpdateFunctionPost(
    token: string,
    campId: string,
    payload: EventFunctionAllCampPayload[],
  ) {
    const attributes = [
      { name: 'ID_Login', value: token },
      { name: 'ID', value: campId },
    ];

    payload.forEach(item => {
      if (!item.id) return;
      attributes.push({ name: `ID_Person${item.role}`, value: item.id });
      if (!item.note) return;
      attributes.push({ name: `${item.role}Note`, value: item.note });
    });
    return request(this.config.name, this.config.entities.eventCampUpdateFunction, attributes).then(
      () => {},
    );
  }

  async eventCampStatisticDetailGet(token: string, campId: string, IsEstimate: boolean) {
    const attributes = [
      { name: 'ID_Login', value: token },
      { name: 'ID_EventCamp', value: campId },
      { name: 'IsEstimate', value: `${IsEstimate}` },
    ];
    return request(
      this.config.name,
      this.config.entities.eventCampStatisticDetail,
      attributes,
    ).then(data => {
      let res: EventCampStatisticDetailResponse | undefined;
      parseString(trimXML(data), (_err: any, result: any) => {
        const item = result.EventCampStatisticDetailResponse.EventCampStatisticDetailResult[0];
        res = {
          benjaminci: getParam(item, 'Benjaminci'),
          vlce: getParam(item, 'Vlce'),
          svetluska: getParam(item, 'Svetluska'),
          skaut: getParam(item, 'Skaut'),
          skautka: getParam(item, 'Skautka'),
          rover: getParam(item, 'Rover'),
          ranger: getParam(item, 'Ranger'),
          adultFemale: getParam(item, 'AdultFemale'),
          adultMale: getParam(item, 'AdultMale'),
        };
      });
      return res;
    });
  }

  async participantCampAllGet(token: string, campId: string) {
    const attributes = [
      { name: 'ID_Login', value: token },
      { name: 'ID_EventCamp', value: campId },
    ];
    return request(this.config.name, this.config.entities.participantCampAll, attributes).then(
      data => {
        let res: ParticipantCampAllResponse[] = [];
        parseString(trimXML(data), (_err: any, result: any) => {
          if (result.ParticipantCampAllResponse.ParticipantCampAllResult[0] === '') return [];
          res =
            result.ParticipantCampAllResponse.ParticipantCampAllResult[0].ParticipantCampAllOutput?.map(
              (item: any) => {
                const output: ParticipantCampAllResponse = {
                  id: getParam(item, 'ID'),
                  personId: getParam(item, 'ID_Person'),
                  name: getParam(item, 'Person'),
                  category: getParam(item, 'Category'),
                  birthday: getParam(item, 'Birthday'),
                  address: getParam(item, 'Address'),
                  unitNumber: getParam(item, 'UnitNumber'),
                  age: getParam(item, 'Age'),
                  days: getParam(item, 'Days'),
                  isEstimate: getParam(item, 'Estimate') === 'true',
                  isReal: getParam(item, 'Real') === 'true',
                  note: getParam(item, 'Note'),
                };
                return output;
              },
            );
        });
        return res;
      },
    );
  }

  async participantCampDeletePost(token: string, participantId: string) {
    const attributes = [
      { name: 'ID_Login', value: token },
      { name: 'ID', value: participantId },
    ];

    return request(this.config.name, this.config.entities.participantCampDelete, attributes).then(
      () => {},
    );
  }

  async participantCampUpdatePost(
    token: string,
    participantId: string,
    payload: ParticipantCampUpdatePayload,
  ) {
    const attributes = [
      { name: 'ID_Login', value: token },
      { name: 'ID', value: participantId },
      { name: 'Estimate', value: `${payload.isEstimate}` },
      { name: 'Real', value: `${payload.isReal}` },
      { name: 'IsAccepted', value: `true` },
      ...(payload.note.length ? [{ name: 'Note', value: payload.note }] : []),
      ...(payload.days.length ? [{ name: 'Days', value: payload.days }] : []),
    ];

    return request(this.config.name, this.config.entities.participantCampUpdate, attributes).then(
      () => {},
    );
  }

  async participantCampInsertPost(token: string, campId: string, personId: string) {
    const attributes = [
      { name: 'ID_Login', value: token },
      { name: 'ID_EventCamp', value: campId },
      { name: 'ID_Person', value: personId },
    ];

    return request(this.config.name, this.config.entities.participantCampInsert, attributes).then(
      () => {},
    );
  }

  async participantCampInsertNewPost(
    token: string,
    campId: string,
    payload: ParticipantCampInsertNewPayload,
  ) {
    const attributes = [
      { name: 'ID_Login', value: token },
      { name: 'ID_EventCamp', value: campId },
    ];

    const personAttributes = {
      Person: [
        { name: 'FirstName', value: payload.firstName },
        { name: 'LastName', value: payload.lastName },
        { name: 'IdentificationCode', value: payload.regNumber },
        { name: 'NickName', value: payload.nickName },
        { name: 'Note', value: payload.note },
        { name: 'IsForeign', value: `${payload.isForeign}` },
      ],
    };

    return request(this.config.name, this.config.entities.participantCampInsert, attributes, [
      personAttributes,
    ]).then(() => {});
  }

  async campTypeAllGet(token: string) {
    const attributes = [{ name: 'ID_Login', value: token }];
    return request(this.config.name, this.config.entities.campTypeAll, attributes).then(data => {
      let res: CampTypeAllResponse[] = [];
      parseString(trimXML(data), (_err: any, result: any) => {
        if (result.CampTypeAllResponse.CampTypeAllResult[0] === '') return [];
        res = result.CampTypeAllResponse.CampTypeAllResult[0].CampTypeAllOutput?.map(
          (item: any) => {
            const output: CampTypeAllResponse = {
              id: getParam(item, 'ID'),
              displayName: getParam(item, 'DisplayName'),
            };
            return output;
          },
        );
      });
      return res;
    });
  }

  async regionAllGet(token: string) {
    const attributes = [{ name: 'ID_Login', value: token }];
    return request(this.config.name, this.config.entities.regionAll, attributes).then(data => {
      let res: RegionAllResponse[] = [];
      parseString(trimXML(data), (_err: any, result: any) => {
        if (result.RegionAllResponse.RegionAllResult[0] === '') return [];
        res = result.RegionAllResponse.RegionAllResult[0].RegionAllOutput?.map((item: any) => {
          const output: RegionAllResponse = {
            id: getParam(item, 'ID'),
            displayName: getParam(item, 'DisplayName'),
          };
          return output;
        });
      });
      return res;
    });
  }

  async campPlaceAllGet(token: string) {
    const attributes = [{ name: 'ID_Login', value: token }];
    return request(this.config.name, this.config.entities.campPlaceAll, attributes).then(data => {
      let res: CampPlaceAllResponse[] = [];
      parseString(trimXML(data), (_err: any, result: any) => {
        if (result.CampPlaceAllResponse.CampPlaceAllResult[0] === '') return [];
        res = result.CampPlaceAllResponse.CampPlaceAllResult[0].CampPlaceAllOutput?.map(
          (item: any) => {
            const output: CampPlaceAllResponse = {
              id: getParam(item, 'ID'),
              displayName: getParam(item, 'DisplayName'),
            };
            return output;
          },
        );
      });
      return res;
    });
  }

  async eventCampAdd(token: string, payload: EventCampInsertPayload, campId?: string) {
    const attributes = [
      { name: 'ID_Login', value: token },
      { name: 'DisplayName', value: payload.displayName },
      { name: 'ID_Unit', value: payload.unitId },
      { name: 'Region', value: payload.region },
      { name: 'ID_Region', value: payload.regionId },
      { name: 'StartDate', value: payload.startDate },
      { name: 'EndDate', value: payload.endDate },
      { name: 'Location', value: payload.location },
      { name: 'Note', value: payload.note },
      { name: 'MobileContact', value: payload.mobile },
      { name: 'Postcode', value: payload.postcode },
      { name: 'IsFloodArea', value: `${payload.isFloodArea}` },
      { name: 'ID_CampPlace', value: payload.campPlaceId },
      { name: 'GpsLatitude', value: '0' },
      { name: 'GpsLongitude', value: '0' },
    ];

    const campTypes = {
      ID_CampTypeArray: payload.campTypeIds.map((id: string) => {
        return { name: 'string', value: id };
      }),
    };

    const units = {
      ID_UnitArray: payload.subUnitIds.map((id: string) => {
        return { name: 'string', value: id };
      }),
    };

    const arrays = [
      ...(payload.campTypeIds.length ? [campTypes] : []),
      ...(payload.subUnitIds.length ? [units] : []),
    ];

    if (campId) {
      attributes.push({ name: 'ID', value: campId });
    }

    return request(
      this.config.name,
      campId ? this.config.entities.eventCampUpdate : this.config.entities.eventCampInsert,
      attributes,
      arrays,
    ).then(() => {});
  }

  async eventCampDelete(token: string, campId: string) {
    const attributes = [
      { name: 'ID_Login', value: token },
      { name: 'ID', value: campId },
    ];

    return request(this.config.name, this.config.entities.eventCampDelete, attributes).then(
      () => {},
    );
  }

  async eventGeneralStatesAllGet(token: string) {
    const attributes = [{ name: 'ID_Login', value: token }];
    return request(this.config.name, this.config.entities.eventGeneralStateAll, attributes).then(
      data => {
        let res: EventGeneralStateAllResponse[] = [];
        parseString(trimXML(data), (_err: any, result: any) => {
          if (result.EventGeneralStateAllResponse.EventGeneralStateAllResult[0] === '') return [];
          res =
            result.EventGeneralStateAllResponse.EventGeneralStateAllResult[0].EventGeneralStateAllOutput?.map(
              (item: any) => {
                const output: EventGeneralStateAllResponse = {
                  id: getParam(item, 'ID'),
                  displayName: getParam(item, 'DisplayName'),
                };
                return output;
              },
            );
        });
        return res;
      },
    );
  }

  async eventGeneralTypeAllGet(token: string) {
    const attributes = [{ name: 'ID_Login', value: token }];
    return request(this.config.name, this.config.entities.eventGeneralTypeAll, attributes).then(
      data => {
        let res: EventGeneralTypeAllResponse[] = [];
        parseString(trimXML(data), (_err: any, result: any) => {
          if (result.EventGeneralTypeAllResponse.EventGeneralTypeAllResult[0] === '') return [];
          res =
            result.EventGeneralTypeAllResponse.EventGeneralTypeAllResult[0].EventGeneralTypeAllOutput?.map(
              (item: any) => {
                const output: EventGeneralTypeAllResponse = {
                  id: getParam(item, 'ID'),
                  displayName: getParam(item, 'DisplayName'),
                };
                return output;
              },
            );
        });
        return res;
      },
    );
  }

  async eventGeneralScopeAllGet(token: string) {
    const attributes = [{ name: 'ID_Login', value: token }];
    return request(this.config.name, this.config.entities.eventGeneralScopeAll, attributes).then(
      data => {
        let res: EventGeneralScopeAllResponse[] = [];
        parseString(trimXML(data), (_err: any, result: any) => {
          if (result.EventGeneralScopeAllResponse.EventGeneralScopeAllResult[0] === '') return [];
          res =
            result.EventGeneralScopeAllResponse.EventGeneralScopeAllResult[0].EventGeneralScopeAllOutput?.map(
              (item: any) => {
                const output: EventGeneralScopeAllResponse = {
                  id: getParam(item, 'ID'),
                  displayName: getParam(item, 'DisplayName'),
                };
                return output;
              },
            );
        });
        return res;
      },
    );
  }

  async eventGeneralAllGet(
    token: string,
    isFuture: string,
    year: string,
    isRelation: string,
    isChildDirect: string,
    isChildUnit: string,
    typeId: string,
    stateId: string,
    scopeId: string,
  ) {
    const attributes = [
      { name: 'ID_Login', value: token },
      ...(isFuture.length ? [{ name: 'IsFuture', value: isFuture }] : []),
      ...(year.length ? [{ name: 'Year', value: year }] : []),
      ...(isRelation.length ? [{ name: 'IsRelation', value: isRelation }] : []),
      ...(isChildDirect.length ? [{ name: 'IsChildDirect', value: isChildDirect }] : []),
      ...(isChildUnit.length ? [{ name: 'IsChildUnit', value: isChildUnit }] : []),
      ...(typeId.length ? [{ name: 'ID_EventGeneralType', value: typeId }] : []),
      ...(stateId.length ? [{ name: 'ID_EventGeneralState', value: stateId }] : []),
      ...(scopeId.length ? [{ name: 'ID_EventGeneralScope', value: scopeId }] : []),
    ];
    return request(this.config.name, this.config.entities.eventGeneralAll, attributes).then(
      data => {
        let res: EventGeneralAllResponse[] = [];
        parseString(trimXML(data), (_err: any, result: any) => {
          if (result.EventGeneralAllResponse.EventGeneralAllResult[0] === '') return [];
          res = result.EventGeneralAllResponse.EventGeneralAllResult[0].EventGeneralAllOutput?.map(
            (item: any) => {
              const output: EventGeneralAllResponse = {
                id: getParam(item, 'ID'),
                displayName: getParam(item, 'DisplayName'),
                startDate: getParam(item, 'StartDate'),
                endDate: getParam(item, 'EndDate'),
                type: getParam(item, 'EventGeneralType'),
                state: getParam(item, 'EventGeneralState'),
                scope: getParam(item, 'EventGeneralScope'),
                stateId: getParam(item, 'ID_EventGeneralState'),
                unitId: getParam(item, 'ID_Unit'),
                unit: getParam(item, 'Unit'),
              };
              return output;
            },
          );
        });
        return res;
      },
    );
  }

  async eventGeneralDetailGet(token: string, eventId: string) {
    const attributes = [
      { name: 'ID_Login', value: token },
      { name: 'ID', value: eventId },
    ];
    return request(this.config.name, this.config.entities.eventGeneralDetail, attributes).then(
      data => {
        let res: EventGeneralDetailResponse | undefined;
        parseString(trimXML(data), (_err: any, result: any) => {
          const item = result.EventGeneralDetailResponse.EventGeneralDetailResult[0];
          res = {
            id: getParam(item, 'ID'),
            displayName: getParam(item, 'DisplayName'),
            stateId: getParam(item, 'ID_EventGeneralState'),
            state: getParam(item, 'EventGeneralState'),
            type: getParam(item, 'EventGeneralType'),
            scope: getParam(item, 'EventGeneralScope'),
            startDate: getParam(item, 'StartDate'),
            endDate: getParam(item, 'EndDate'),
            unit: getParam(item, 'Unit'),
            unitId: getParam(item, 'ID_Unit'),
            regNumber: getParam(item, 'RegistrationNumber'),
            eduUnit: getParam(item, 'UnitEducative'),
            eduUnitId: getParam(item, 'ID_UnitEducative'),
            eduUnitRegNumber: getParam(item, 'UnitEducativeRegistrationNumber'),
            personClosed: getParam(item, 'PersonClosed'),
            dateClosed: getParam(item, 'DateClosed'),
            note: getParam(item, 'Note'),
            location: getParam(item, 'Location'),
            postcode: getParam(item, 'Postcode'),
            region: getParam(item, 'Region'),
            latitude: getParam(item, 'GpsLatitude'),
            longitude: getParam(item, 'GpsLongitude'),
            totalParticipants: getParam(item, 'TotalParticipants'),
            foreignParticipants: getParam(item, 'ForeignParticipants'),
            leaderParticipants: getParam(item, 'LeaderParticipants'),
            assistantParticipants: getParam(item, 'AssistantParticipants'),
            isAutoComputedDays: getParam(item, 'IsAutoComputedDays') === 'true',
            childDays: getParam(item, 'ChildDays'),
            personDays: getParam(item, 'PersonDays'),
            isStatisticAutoComputed: getParam(item, 'IsStatisticAutoComputed') === 'true',
            target: getParam(item, 'Target'),
            program: getParam(item, 'Program'),
          };
        });
        return res;
      },
    );
  }

  async eventFunctionAllGeneralGet(token: string, eventId: string) {
    const attributes = [
      { name: 'ID_Login', value: token },
      { name: 'ID_EventGeneral', value: eventId },
    ];
    return request(this.config.name, this.config.entities.eventFunctionAllGeneral, attributes).then(
      data => {
        let res: EventFunctionAllGeneralResponse[] = [];
        parseString(trimXML(data), (_err: any, result: any) => {
          if (result.EventFunctionAllGeneralResponse.EventFunctionAllGeneralResult[0] === '')
            return [];
          res =
            result.EventFunctionAllGeneralResponse.EventFunctionAllGeneralResult[0].EventFunctionAllGeneralOutput?.map(
              (item: any) => {
                const output: EventFunctionAllGeneralResponse = {
                  id: getParam(item, 'ID'),
                  name: getParam(item, 'Person'),
                  personId: getParam(item, 'ID_Person'),
                  role: getParam(item, 'EventFunctionType'),
                  note: getParam(item, 'Note'),
                };
                return output;
              },
            );
        });
        return res;
      },
    );
  }

  async eventGeneralUpdateFunctionPost(
    token: string,
    eventId: string,
    payload: EventFunctionAllGeneralPayload[],
  ) {
    const attributes = [
      { name: 'ID_Login', value: token },
      { name: 'ID', value: eventId },
    ];

    payload.forEach(item => {
      if (!item.id) return;
      attributes.push({ name: `ID_Person${item.role}`, value: item.id });
      if (!item.note) return;
      attributes.push({ name: `${item.role}Note`, value: item.note });
    });
    return request(
      this.config.name,
      this.config.entities.eventGeneralUpdateFunction,
      attributes,
    ).then(() => {});
  }

  async participantGeneralAllGet(token: string, eventId: string) {
    const attributes = [
      { name: 'ID_Login', value: token },
      { name: 'ID_EventGeneral', value: eventId },
    ];
    return request(this.config.name, this.config.entities.participantGeneralAll, attributes).then(
      data => {
        let res: ParticipantGeneralAllResponse[] = [];
        parseString(trimXML(data), (_err: any, result: any) => {
          if (result.ParticipantGeneralAllResponse.ParticipantGeneralAllResult[0] === '') return [];
          res =
            result.ParticipantGeneralAllResponse.ParticipantGeneralAllResult[0].ParticipantGeneralAllOutput?.map(
              (item: any) => {
                const output: ParticipantGeneralAllResponse = {
                  id: getParam(item, 'ID'),
                  personId: getParam(item, 'ID_Person'),
                  name: getParam(item, 'Person'),
                  category: getParam(item, 'Category'),
                  birthday: getParam(item, 'Birthday'),
                  address: getParam(item, 'Address'),
                  unitNumber: getParam(item, 'UnitNumber'),
                  age: getParam(item, 'Age'),
                  days: getParam(item, 'Days'),
                  note: getParam(item, 'Note'),
                  unit: getParam(item, 'Unit'),
                  unitId: getParam(item, 'ID_Unit'),
                };
                return output;
              },
            );
        });
        return res;
      },
    );
  }

  async participantGeneralDeletePost(token: string, participantId: string) {
    const attributes = [
      { name: 'ID_Login', value: token },
      { name: 'ID', value: participantId },
    ];

    return request(
      this.config.name,
      this.config.entities.participantGeneralDelete,
      attributes,
    ).then(() => {});
  }

  async participantGeneralUpdatePost(
    token: string,
    participantId: string,
    payload: ParticipantGeneralUpdatePayload,
  ) {
    const attributes = [
      { name: 'ID_Login', value: token },
      { name: 'ID', value: participantId },
      { name: 'IsAccepted', value: `true` },
      ...(payload.note.length ? [{ name: 'Note', value: payload.note }] : []),
      ...(payload.days.length ? [{ name: 'Days', value: payload.days }] : []),
    ];

    return request(
      this.config.name,
      this.config.entities.participantGeneralUpdate,
      attributes,
    ).then(() => {});
  }

  async participantGeneralInsertPost(token: string, eventId: string, personId: string) {
    const attributes = [
      { name: 'ID_Login', value: token },
      { name: 'ID_EventGeneral', value: eventId },
      { name: 'ID_Person', value: personId },
    ];

    return request(
      this.config.name,
      this.config.entities.participantGeneralInsert,
      attributes,
    ).then(() => {});
  }

  async participantGeneralInsertNewPost(
    token: string,
    campId: string,
    payload: ParticipantGeneralInsertNewPayload,
  ) {
    const attributes = [
      { name: 'ID_Login', value: token },
      { name: 'ID_EventGeneral', value: campId },
    ];

    const personAttributes = {
      Person: [
        { name: 'FirstName', value: payload.firstName },
        { name: 'LastName', value: payload.lastName },
        { name: 'IdentificationCode', value: payload.regNumber },
        { name: 'NickName', value: payload.nickName },
        { name: 'Note', value: payload.note },
        { name: 'IsForeign', value: `${payload.isForeign}` },
      ],
    };

    return request(this.config.name, this.config.entities.participantGeneralInsert, attributes, [
      personAttributes,
    ]).then(() => {});
  }

  async eventStatisticAllEventGeneralGet(token: string, eventId: string) {
    const attributes = [
      { name: 'ID_Login', value: token },
      { name: 'ID_EventGeneral', value: eventId },
    ];
    return request(
      this.config.name,
      this.config.entities.eventStatisticAllEventGeneral,
      attributes,
    ).then(data => {
      let res: EventStatisticAllEventGeneralResponse[] = [];
      parseString(trimXML(data), (_err: any, result: any) => {
        if (
          result.EventStatisticAllEventGeneralResponse.EventStatisticAllEventGeneralResult[0] === ''
        )
          return [];
        res =
          result.EventStatisticAllEventGeneralResponse.EventStatisticAllEventGeneralResult[0].EventStatisticAllEventGeneralOutput?.map(
            (item: any) => {
              const output: EventStatisticAllEventGeneralResponse = {
                category: getParam(item, 'ParticipantCategory'),
                count: getParam(item, 'Count'),
              };
              return output;
            },
          );
      });
      return res;
    });
  }

  async eventGeneralUpdateStatisticAutoComputedPost(
    token: string,
    eventId: string,
    value: boolean,
  ) {
    const attributes = [
      { name: 'ID_Login', value: token },
      { name: 'ID', value: eventId },
      { name: 'IsStatisticAutoComputed', value: `${value}` },
    ];

    return request(
      this.config.name,
      this.config.entities.eventGeneralUpdateStatisticAutoComputed,
      attributes,
    ).then(() => {});
  }

  async eventGeneralUpdateClosePost(token: string, eventId: string) {
    const attributes = [
      { name: 'ID_Login', value: token },
      { name: 'ID', value: eventId },
    ];

    return request(this.config.name, this.config.entities.eventGeneralUpdateClose, attributes).then(
      () => {},
    );
  }

  async eventGeneralUpdateOpenPost(token: string, eventId: string) {
    const attributes = [
      { name: 'ID_Login', value: token },
      { name: 'ID', value: eventId },
    ];

    return request(this.config.name, this.config.entities.eventGeneralUpdateOpen, attributes).then(
      () => {},
    );
  }

  async eventGeneralUpdateReportPost(
    token: string,
    eventId: string,
    payload: EventGeneralUpdateReportPayload,
  ) {
    const attributes = [
      { name: 'ID_Login', value: token },
      { name: 'ID', value: eventId },
      { name: 'Target', value: payload.target },
      { name: 'Program', value: payload.program },
    ];

    return request(
      this.config.name,
      this.config.entities.eventGeneralUpdateReport,
      attributes,
    ).then(() => {});
  }

  async eventCampUpdateClosePost(token: string, campId: string) {
    const attributes = [
      { name: 'ID_Login', value: token },
      { name: 'ID', value: campId },
    ];

    return request(this.config.name, this.config.entities.eventCampUpdateClose, attributes).then(
      () => {},
    );
  }

  async eventCampUpdateOpenPost(token: string, campId: string) {
    const attributes = [
      { name: 'ID_Login', value: token },
      { name: 'ID', value: campId },
    ];

    return request(this.config.name, this.config.entities.eventCampUpdateOpen, attributes).then(
      () => {},
    );
  }

  async eventGeneralAdd(token: string, payload: EventGeneralInsertPayload, eventId?: string) {
    const attributes = [
      { name: 'ID_Login', value: token },
      { name: 'DisplayName', value: payload.displayName },
      { name: 'StartDate', value: payload.startDate },
      { name: 'EndDate', value: payload.endDate },
      { name: 'ID_EventGeneralType', value: payload.typeId },
      { name: 'ID_EventGeneralScope', value: payload.scopeId },
      { name: 'ID_Unit', value: payload.unitId },
      { name: 'Note', value: payload.note },
      { name: 'Region', value: payload.region },
      { name: 'Location', value: payload.location },
      { name: 'Postcode', value: payload.postcode },
      { name: 'GpsLatitude', value: '0' },
      { name: 'GpsLongitude', value: '0' },
    ];

    if (eventId) {
      attributes.push({ name: 'ID', value: eventId });
    }

    return request(
      this.config.name,
      eventId ? this.config.entities.eventGeneralUpdate : this.config.entities.eventGeneralInsert,
      attributes,
    ).then(() => {});
  }

  async eventGeneralDelete(token: string, eventId: string) {
    const attributes = [
      { name: 'ID_Login', value: token },
      { name: 'ID', value: eventId },
    ];

    return request(this.config.name, this.config.entities.eventGeneralDelete, attributes).then(
      () => {},
    );
  }
}
