import { Component, ChangeDetectionStrategy, OnInit, ChangeDetectorRef, OnDestroy, ViewChild, ElementRef } 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 { 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 { DomainCheckoutService } from '@domain/checkout';
import { Subscription } from 'rxjs';
import { genderLastNameValidator } from '../validators/gender-b2b-validator';
import { UiValidators } from '@ui/validators';
import { organisationB2bDeliveryValidator } from '../validators/organisation-delivery-b2b-validator';
import { HttpErrorResponse } from '@angular/common/http';

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

  subscription: 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.shippingAddressGroup.disable();
    this.subscription = 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();
      }
    });
  }

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

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

    return fb.group(
      {
        organisation: fb.group({
          name: fb.control(customer?.organisation?.name, [Validators.required]),
          department: fb.control(customer?.organisation?.department),
          vatId: fb.control(customer?.organisation?.vatId),
        }),
        gender: fb.control(customer?.gender),
        title: fb.control(customer?.title),
        lastName: fb.control(customer?.lastName),
        firstName: fb.control(customer?.firstName),
        communicationDetails: fb.group({
          email: fb.control(customer?.communicationDetails?.email, [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]),
          info: fb.control(customer?.address?.info),
          country: fb.control(customer?.address?.country || 'DEU', [Validators.required]),
        }),
        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'),
          }),
          communicationDetails: fb.group({
            email: fb.control(''),
            phone: fb.control(''),
            mobile: fb.control(''),
          }),
        }),
      },
      { validators: [genderLastNameValidator(true), organisationB2bDeliveryValidator()] }
    );
  }

  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 {
      const response = await this.customerService.createB2BCustomer(this.control.value).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();
  }
}
