import { Component, ChangeDetectionStrategy, OnInit, ChangeDetectorRef, OnDestroy, ElementRef, ViewChild } from '@angular/core';
import { AbstractControl, FormBuilder, FormGroup, Validators } from '@angular/forms';
import { ActivatedRoute, Router } from '@angular/router';
import { ApplicationService } from '@core/application';
import { BreadcrumbService } from '@core/breadcrumb';
import { CrmCustomerService } from '@domain/crm';
import { CustomerDTO } from '@swagger/crm';
import { UiValidators } from '@ui/validators';
import { UiModalService } from '@ui/modal';
import { AddressSelectionModalService } from '../modals/address-selection-modal/address-selection-modal.service';
import { CustomerCreateComponentBase } from './customer-create.component';
import { validateEmail } from '../validators/email-validator';
import { Subscription } from 'rxjs';
import { DomainCheckoutService } from '@domain/checkout';
import { map } from 'rxjs/operators';
import { HttpErrorResponse } from '@angular/common/http';

@Component({
  selector: 'page-customer-create-guest',
  templateUrl: 'customer-create-guest.component.html',
  styleUrls: ['customer-create.component.scss'],
  changeDetection: ChangeDetectionStrategy.OnPush,
})
export class CustomerCreateGuestComponent extends CustomerCreateComponentBase implements OnInit, OnDestroy {
  @ViewChild('formControl')
  formControlRef: ElementRef;

  shippingAddressSubscription: Subscription;
  organisationSubscription: Subscription;

  get shippingAddressGroup(): AbstractControl {
    return this.control?.get('shippingAddress');
  }

  constructor(
    public activatedRoute: ActivatedRoute,
    public router: Router,
    private fb: FormBuilder,
    public modal: UiModalService,
    public customerService: CrmCustomerService,
    public breadcrumb: BreadcrumbService,
    public application: ApplicationService,
    public addressSelectionModal: AddressSelectionModalService,
    public checkoutService: DomainCheckoutService,
    public cdr: ChangeDetectorRef
  ) {
    super();
  }

  ngOnInit(): void {
    this.init();
    this.countries$ = this.countries$.pipe(map((countries) => countries.filter((country) => country.name === 'Deutschland')));

    this.shippingAddressGroup.disable();
    this.shippingAddressSubscription = this.control.get('differentShippingAddress').valueChanges.subscribe((isChecked) => {
      if (isChecked) {
        this.shippingAddressGroup.enable();
        this.setShippingAddressValidators(this.shippingAddressGroup);
      } else {
        this.shippingAddressGroup.disable();
        this.clearShippingAddressValidators(this.shippingAddressGroup);
        this.control.updateValueAndValidity();
      }
    });

    this.organisationSubscription = this.organisationGroup.get('name').valueChanges.subscribe((value: string) => {
      if (!value) {
        this.organisationGroup.get('department').reset('', { onlySelf: true });
        this.organisationGroup.get('vatId').reset('', { onlySelf: true });
      }
    });
  }

  ngOnDestroy(): void {
    if (this.shippingAddressSubscription) {
      this.shippingAddressSubscription.unsubscribe();
    }

    if (this.organisationSubscription) {
      this.organisationSubscription.unsubscribe();
    }
  }

  createControl(customer?: CustomerDTO): FormGroup {
    const { fb } = this;

    return fb.group({
      organisation: fb.group({
        name: fb.control(customer?.organisation?.name),
        department: fb.control(customer?.organisation?.department),
        vatId: fb.control(customer?.organisation?.vatId),
      }),
      gender: fb.control(customer?.gender, [Validators.required, Validators.min(1)]),
      title: fb.control(customer?.title),
      lastName: fb.control(customer?.lastName, [Validators.required]),
      firstName: fb.control(customer?.firstName, [Validators.required]),
      dateOfBirth: fb.control(customer?.dateOfBirth, [UiValidators.date]),
      communicationDetails: fb.group({
        email: fb.control(customer?.communicationDetails?.email, [Validators.required, validateEmail]),
        phone: fb.control(customer?.communicationDetails?.phone, [UiValidators.phone]),
        mobile: fb.control(customer?.communicationDetails?.mobile, [UiValidators.phone]),
      }),
      address: fb.group({
        street: fb.control(customer?.address?.street, [Validators.required]),
        streetNumber: fb.control(customer?.address?.streetNumber, [Validators.required]),
        zipCode: fb.control(customer?.address?.zipCode, [Validators.required]),
        city: fb.control(customer?.address?.city, [Validators.required]),
        country: fb.control(customer?.address?.country || 'DEU', [Validators.required]),
        info: fb.control(customer?.address?.info),
      }),
      differentShippingAddress: fb.control(false),
      shippingAddress: fb.group({
        organisation: fb.group({
          name: fb.control(''),
          department: fb.control(''),
          vatId: fb.control(''),
        }),
        gender: fb.control(undefined),
        title: fb.control(''),
        firstName: fb.control(''),
        lastName: fb.control(''),
        address: fb.group({
          street: fb.control(''),
          streetNumber: fb.control(''),
          zipCode: fb.control(''),
          city: fb.control(''),
          info: fb.control(''),
          country: fb.control('DEU'),
        }),
      }),
    });
  }

  async submit(): Promise<void> {
    if (this.control.disabled) {
      return;
    }

    if (this.control.invalid) {
      this.control.disable({ emitEvent: false });
      setTimeout(() => {
        this.enableControl();
        this.focusFirstInvalidFormControl(this.formControlRef);
      }, 200);
      return;
    }

    this.control.disable({ emitEvent: false });

    try {
      const address = await this.addressSelectionModal.validateAddress(this.control.value.address);
      if (address) {
        if (typeof address === 'string') {
          if (address === 'close') {
            this.enableControl();
            return;
          }
        } else {
          this.control.patchValue({ address });
        }
      }
    } catch (error) {
      this.enableControl();
      if (error instanceof HttpErrorResponse) {
        if (error.error.invalidProperties) {
          this.setValidateAddressError(error.error?.invalidProperties, this.control.get('address'));
        }
      }
      return;
    }

    try {
      if (this.control.value.differentShippingAddress) {
        const shippingAddress = await this.addressSelectionModal.validateAddress(this.control.value.shippingAddress.address);
        if (shippingAddress) {
          if (typeof shippingAddress === 'string') {
            if (shippingAddress === 'close') {
              this.enableControl();
              return;
            }
          } else {
            this.control.patchValue({ shippingAddress });
          }
        }
      }
    } catch (error) {
      this.enableControl();
      if (error instanceof HttpErrorResponse) {
        if (error.error.invalidProperties) {
          this.setValidateAddressError(error.error?.invalidProperties, this.control.get('shippingAddress').get('address'));
        }
      }
      return;
    }

    try {
      let newCustomer: CustomerDTO = this.control.value;
      if (this.control.value.differentShippingAddress) {
        newCustomer.shippingAddresses = [
          {
            data: {
              ...this.control.value.shippingAddress,
            },
          },
        ];
      }

      const response = await this.customerService.createGuestCustomer(newCustomer).toPromise();

      if (this.control.value.differentShippingAddress) {
        try {
          const shippingResponse = await this.customerService
            .createShippingAddress(response.result.id, this.control.value.shippingAddress, true)
            .toPromise();
          if (shippingResponse.error) {
            throw new Error(shippingResponse.message);
          }
        } catch (error) {
          console.error(error);
        }
      }

      if (response.error) {
        this.enableControl();
        throw new Error(response.message);
      } else {
        this.removeBreadcrumb();
        this.router.navigate(['/kunde', this.application.activatedProcessId, 'customer', response.result.id]);
      }
    } catch (error) {
      this.setValidationError(error.error?.invalidProperties, this.control);
    }
  }

  enableControl() {
    this.control.enable();

    if (!this.control.get('differentShippingAddress').value) {
      this.control.get('differentShippingAddress').disable();
    }

    this.control.markAllAsTouched();
    this.control.updateValueAndValidity();
  }
}
