/********************************************************************************
 * Copyright (c) 2020 Contributors to the Eclipse Foundation
 *
 * See the NOTICE file(s) distributed with this work for additional
 * information regarding copyright ownership.
 *
 * This program and the accompanying materials are made available under the
 * terms of the Eclipse Public License v. 2.0 which is available at
 * http://www.eclipse.org/legal/epl-2.0.
 *
 * SPDX-License-Identifier: EPL-2.0
 ********************************************************************************/
import { BaseSandbox } from '@shared/sandbox/base.sandbox';
import { Injectable } from '@angular/core';
import * as externalPersonActions from '@shared/store/actions/persons/external-person.action';
import { FormGroupState, SetValueAction, ResetAction, MarkAsTouchedAction } from 'ngrx-forms';
import { ExternalPerson, CommunicationsData, Address, CommunicationType } from '@shared/models';
import { Observable } from 'rxjs';
import * as store from '@shared/store';
import { Store, ActionsSubject } from '@ngrx/store';
import * as externalPersonDetailsFormReducer from '@shared/store/reducers/persons/external-person/external-person-details-form.reducer';
import * as externalPersonAddressDetailsFormReducer from '@shared/store/reducers/persons/external-person/addresses-details-form.reducer';
import { ofType } from '@ngrx/effects';
import { UtilService } from '@shared/utility';
import { takeUntil, take, map } from 'rxjs/operators';
import { Router } from '@angular/router';
import { NgbModal } from '@ng-bootstrap/ng-bootstrap';
import { SafetyQueryDialogComponent } from '@shared/components/dialogs/safety-query-dialog/safety-query-dialog.component';
import * as externalCommunicationsDataDetailsFormReducer from '@shared/store/reducers/persons/external-person/communications-data-details-form.reducer';
import * as communicationTypesActions from '@shared/store/actions/admin/communication-types.action';

@Injectable()
export class ExternalPersonDetailsSandBox extends BaseSandbox {
  public externPersonDetailsFormState$: Observable<FormGroupState<ExternalPerson>> = this.appState$.select(store.getExternalPersonDetails);
  public externPersonDetailsCurrentFormState: FormGroupState<ExternalPerson>;
  public addressDetailsFormState$: Observable<FormGroupState<Address>> = this.appState$.select(store.getExternalPersonAddressesDetails);
  public addressDetailsCurrentFormState: FormGroupState<Address>;
  public addressList$: Observable<Array<Address>> = this.appState$.select(store.getExternalPersonAddressesData);
  public addressListLoading$: Observable<boolean> = this.appState$.select(store.getExternalPersonAddressesLoading);
  public communicationsDataDetailsFormState$: Observable<FormGroupState<CommunicationsData>> = this.appState$.select(
    store.getExternalPersonCommunicationsDataDetails
  );
  public communicationsDataDetailsCurrentFormState: FormGroupState<CommunicationsData>;
  public communicationsDataList$: Observable<Array<CommunicationsData>> = this.appState$.select(store.getExternalCommunicationsDataData);
  public communicationsDataListLoading$: Observable<boolean> = this.appState$.select(store.getExternalCommunicationsDataLoading);

  public isAddressDataDetailViewVisible: boolean = false;
  public existMainAddress = false;
  public isCurrentAddressMainAddress = false;
  public externalPersonContactId: string;
  public isCommunicationsDataDetailViewVisible: boolean = false;
  private _communicationTypes: Array<CommunicationType> = new Array<CommunicationType>();
  private _mainAddress: Address;

  public communicationsAgApi;
  public addressAgApi;

  /**
   *  ExternalPerson Sandbox constructor
   */
  constructor(
    public appState$: Store<store.State>,
    public utilService: UtilService,
    protected actionsSubject: ActionsSubject,
    protected router: Router,
    protected modalService: NgbModal
  ) {
    super(appState$);
    this.addressList$.subscribe(addresses => {
      this._checkIfMainAddressExist(addresses);
    });

    this.actionsSubject
      .pipe(
        ofType(externalPersonActions.loadExternalPersonDetailAddressDetailsSuccess),
        map((action: { payload: Address }) => action.payload),
        takeUntil(this._endSubscriptions$)
      )
      .subscribe((address: Address) => {
        this._checkIfCurrentAddressIsMainAddress(address);
      });
  }

  public loadExternalPerson(externalPersonId: string): void {
    this.externalPersonContactId = externalPersonId;
    this.appState$.dispatch(externalPersonActions.loadExternalPersonDetail({ payload: externalPersonId }));
  }

  public loadExternalPersonAddresses(externalPersonId: string): void {
    this.appState$.dispatch(externalPersonActions.loadExternalPersonDetailAddresses({ payload: externalPersonId }));
  }

  public loadExternalPersonDetailsAddressDetails(addressId: string): void {
    this.appState$.dispatch(
      externalPersonActions.loadExternalPersonDetailAddressDetails({ payload_contactId: this.externalPersonContactId, payload_addressId: addressId })
    );
  }

  public persistExternalPerson(): void {
    if (this.externPersonDetailsCurrentFormState.isValid) {
      const newExternalPerson = new ExternalPerson(this.externPersonDetailsCurrentFormState.value);

      this.appState$.dispatch(
        externalPersonActions.persistExternalPersonDetail({
          payload: newExternalPerson,
        })
      );
      this.actionsSubject.pipe(ofType(externalPersonActions.persistExternalPersonDetailSuccess), take(1), takeUntil(this._endSubscriptions$)).subscribe(() => {
        this.newExternalPerson();
        this.router.navigateByUrl(`/overview`);
      });
    } else {
      this.utilService.displayNotification('MandatoryFieldsNotFilled', 'alert');
    }
  }

  public persistAddress(): void {
    if (this.addressDetailsCurrentFormState.isValid) {
      const newAddress = new Address(this.addressDetailsCurrentFormState.value);
      newAddress.contactId = newAddress.contactId !== null ? newAddress.contactId : this.externalPersonContactId;

      this.appState$.dispatch(externalPersonActions.persistAddressDetail({ payload: newAddress }));
      this.actionsSubject.pipe(ofType(externalPersonActions.persistAddressDetailSuccess), take(1), takeUntil(this._endSubscriptions$)).subscribe(() => {
        this.closeAddressDataDetail();
      });
    } else {
      this.utilService.displayNotification('MandatoryFieldsNotFilled', 'alert');
    }
  }

  public deleteAddress(address: Address): void {
    const modalRef = this.modalService.open(SafetyQueryDialogComponent);
    modalRef.componentInstance.title = 'ConfirmDialog.Action.delete';
    modalRef.componentInstance.body = 'ConfirmDialog.Deletion';
    modalRef.result.then(
      () => {
        this.appState$.dispatch(externalPersonActions.deleteAddress({ payload: address }));
        if (address.isMainAddress) {
          this.existMainAddress = false;
        }
        this.closeAddressDataDetail();
      },
      () => {}
    );
  }

  public closeAddressDataDetail(): void {
    this.clearAddressData();
    this.isAddressDataDetailViewVisible = false;
    this.addressAgApi.setDomLayout('autoHeight');
  }

  public newExternalPerson(): void {
    this.clearExternalPerson();
    this.appState$.dispatch(new MarkAsTouchedAction(externalPersonDetailsFormReducer.FORM_ID));
  }

  public clearExternalPerson(): void {
    this.appState$.dispatch(new SetValueAction(externalPersonDetailsFormReducer.FORM_ID, externalPersonDetailsFormReducer.INITIAL_STATE.value));
    this.appState$.dispatch(new ResetAction(externalPersonDetailsFormReducer.FORM_ID));
  }

  public newAddressData(): void {
    this.clearAddressData();
    this.appState$.dispatch(new MarkAsTouchedAction(externalPersonAddressDetailsFormReducer.FORM_ID));
  }

  public clearAddressData(): void {
    this.isCurrentAddressMainAddress = false;
    this.appState$.dispatch(new SetValueAction(externalPersonAddressDetailsFormReducer.FORM_ID, externalPersonAddressDetailsFormReducer.INITIAL_STATE.value));
    this.appState$.dispatch(new ResetAction(externalPersonAddressDetailsFormReducer.FORM_ID));
  }

  public registerExternalPersonEvents(): void {
    this.externPersonDetailsFormState$
      .pipe(takeUntil(this._endSubscriptions$))
      .subscribe((formState: FormGroupState<ExternalPerson>) => (this.externPersonDetailsCurrentFormState = formState));
  }

  public registerAddressEvents(): void {
    this.addressDetailsFormState$
      .pipe(takeUntil(this._endSubscriptions$))
      .subscribe((formState: FormGroupState<Address>) => (this.addressDetailsCurrentFormState = formState));
  }

  public loadCommunicationsData(externalPersonId: string): void {
    this.actionsSubject
      .pipe(
        ofType(communicationTypesActions.loadCommunicationTypesSuccess),
        map((action: communicationTypesActions.ILoadCommunicationTypesSuccess) => action.payload),
        take(1),
        takeUntil(this._endSubscriptions$)
      )
      .subscribe((payload: Array<CommunicationType>) => {
        this._communicationTypes = payload;
        this.appState$.dispatch(externalPersonActions.loadExternalPersonDetailCommunicationsData({ payload: externalPersonId }));
      });

    this.actionsSubject
      .pipe(
        ofType(externalPersonActions.loadExternalPersonDetailCommunicationsDataSuccess),
        map((action: externalPersonActions.ILoadExternalPersonCommunicationsDataSuccess) => action.payload),
        take(1),
        takeUntil(this._endSubscriptions$)
      )
      .subscribe((communicationsData: Array<CommunicationsData>) => {
        if (this._communicationTypes) {
          for (let i = 0; i < this._communicationTypes.length; i++) {
            const ct = this._communicationTypes[i];
            const existingCommunicationsData: CommunicationsData = communicationsData.find(cd => cd.communicationTypeId == ct.id);
            ct.isDisabled = existingCommunicationsData ? true : false;
          }
        }
      });
  }

  public loadCommunicationsDataDetails(communicationsDataId: string): void {
    this.appState$.dispatch(
      externalPersonActions.loadExternalPersonDetailCommunicationsDataDetails({
        payload_contactId: this.externalPersonContactId,
        payload_communicationsId: communicationsDataId,
      })
    );
  }

  public persistCommunicationsData(): void {
    if (this.communicationsDataDetailsCurrentFormState.isValid) {
      const newCommunicationsData = new CommunicationsData(this.communicationsDataDetailsCurrentFormState.value);
      newCommunicationsData.contactId = newCommunicationsData.contactId !== null ? newCommunicationsData.contactId : this.externalPersonContactId;

      this.appState$.dispatch(externalPersonActions.persistCommunicationsDataDetail({ payload: newCommunicationsData }));
      this.actionsSubject
        .pipe(ofType(externalPersonActions.persistCommunicationsDataDetailSuccess), take(1), takeUntil(this._endSubscriptions$))
        .subscribe(() => {
          this.closeCommunicationsDataDetail();
        });
    } else {
      this.utilService.displayNotification('MandatoryFieldsNotFilled', 'alert');
    }
  }

  public deleteCommunicationsData(communicationsData: CommunicationsData): void {
    const modalRef = this.modalService.open(SafetyQueryDialogComponent);
    modalRef.componentInstance.title = 'ConfirmDialog.Action.delete';
    modalRef.componentInstance.body = 'ConfirmDialog.Deletion';
    modalRef.result.then(
      () => {
        this.appState$.dispatch(externalPersonActions.deleteCommunicationsData({ payload: communicationsData }));
        this.closeCommunicationsDataDetail();
      },
      () => {}
    );
  }

  public closeCommunicationsDataDetail(): void {
    this.loadCommunicationsData(this.externalPersonContactId);
    this.clearCommunicationsData();
    this.isCommunicationsDataDetailViewVisible = false;
    this.communicationsAgApi.setDomLayout('autoHeight');
  }

  public newCommunicationsData(): void {
    this.clearCommunicationsData();
    this.appState$.dispatch(new MarkAsTouchedAction(externalCommunicationsDataDetailsFormReducer.FORM_ID));
  }

  public clearCommunicationsData(): void {
    this.appState$.dispatch(
      new SetValueAction(externalCommunicationsDataDetailsFormReducer.FORM_ID, externalCommunicationsDataDetailsFormReducer.INITIAL_STATE.value)
    );
    this.appState$.dispatch(new ResetAction(externalCommunicationsDataDetailsFormReducer.FORM_ID));
  }

  public registerCommunicationsDataEvents(): void {
    this.communicationsDataDetailsFormState$
      .pipe(takeUntil(this._endSubscriptions$))
      .subscribe((formState: FormGroupState<CommunicationsData>) => (this.communicationsDataDetailsCurrentFormState = formState));
  }

  removeCurrentMainAddress(): void {
    this._mainAddress.isMainAddress = false;
    this.appState$.dispatch(externalPersonActions.persistAddressDetail({ payload: this._mainAddress }));
  }

  private _checkIfMainAddressExist(addresses: Array<Address>) {
    for (let i = 0; i < addresses.length; i++) {
      const address = addresses[i];
      if (address.isMainAddress) {
        this._mainAddress = address;
        this.existMainAddress = true;
        break;
      }
      this._mainAddress = address;
      this.existMainAddress = false;
    }
  }

  private _checkIfCurrentAddressIsMainAddress(address: Address): void {
    this.isCurrentAddressMainAddress = address.isMainAddress;
  }
}
