import { ChangeDetectionStrategy, Component, OnDestroy, OnInit } from '@angular/core';
import { FormBuilder, FormGroup, Validators } from '@angular/forms';
import { Router } from '@angular/router';
import { ApplicationService } from '@core/application';
import { ItemDTO } from '@swagger/cat';
import { DateAdapter } from '@ui/common';
import { UiErrorModalComponent, UiModalRef, UiModalService } from '@ui/modal';
import { Subject } from 'rxjs';
import { first, shareReplay, takeUntil } from 'rxjs/operators';
import { CheckoutDummyStore } from './checkout-dummy.store';

@Component({
  selector: 'page-checkout-dummy',
  templateUrl: 'checkout-dummy.component.html',
  styleUrls: ['checkout-dummy.component.scss'],
  providers: [CheckoutDummyStore, FormBuilder],
  changeDetection: ChangeDetectionStrategy.OnPush,
})
export class CheckoutDummyComponent implements OnInit, OnDestroy {
  // Form
  control: FormGroup;

  // Searchbox
  query$ = this._store.query$;
  message$ = this._store.message$;
  loading$ = this._store.fetching$.pipe(shareReplay());

  // Datepicker
  minDate = this._dateAdapter.addCalendarDays(new Date(), -1);
  estimatedShippingDate$ = this._store.estimatedShippingDate$.pipe(shareReplay());

  // Dropdowns
  vats$ = this._store.vats$;
  suppliers$ = this._store.suppliers$;

  _onDestroy$ = new Subject<void>();

  constructor(
    private _router: Router,
    private _fb: FormBuilder,
    private _dateAdapter: DateAdapter,
    private _modal: UiModalService,
    private _store: CheckoutDummyStore,
    private _ref: UiModalRef<any, any>,
    private readonly _applicationService: ApplicationService
  ) {}

  ngOnInit() {
    this.initForm();

    this._store.item$.pipe(takeUntil(this._onDestroy$)).subscribe((item) => {
      if (item) {
        this.clearForm();
        this.populateForm(item);
      }
    });

    if (!!this._ref?.data && Object.keys(this._ref?.data).length !== 0) {
      const data = this._ref?.data;
      const item = {
        ean: data.ean || '',
        name: data.name || '',
        quantity: data.quantity || '',
        estimatedShippingDate: data.estimatedShippingDate || this._dateAdapter.today().toISOString(),
        contributors: data.contributors || '',
        manufacturer: data.manufacturer || '',
        supplier: data.supplier || 5,
        price: data.price || '',
        vat: data.vat || '',
      };
      this.populateFormFromModalData(item);
    }
  }

  ngOnDestroy() {
    this._onDestroy$.next();
    this._onDestroy$.complete();
  }

  async search(ean: string) {
    this._store.query = ean;
    this._store.search();
  }

  setQuery(query: string) {
    this._store.query = query;
  }

  changeEstimatedShippingDate(date: Date) {
    if (!date) {
      return;
    }
    this._store.estimatedShippingDate = date.toISOString();
  }

  initForm() {
    const fb = this._fb;
    this.control = fb.group({
      ean: fb.control('', Validators.pattern('^[0-9]{13}$')),
      name: fb.control('', Validators.required),
      quantity: fb.control('', [Validators.required, Validators.pattern('^[0-9]*$'), Validators.min(1)]),
      estimatedShippingDate: fb.control(this._dateAdapter.today().toISOString(), Validators.required),
      contributors: fb.control(''),
      manufacturer: fb.control(''),
      supplier: fb.control(5, Validators.required), // 5 === Dummy
      price: fb.control('', [Validators.required, Validators.pattern(/^\d+([\,]\d{1,2})?$/)]),
      vat: fb.control('', Validators.required),
    });
    this.changeEstimatedShippingDate(this._dateAdapter.today()); // Update View
  }

  populateForm(item: ItemDTO) {
    this.control.get('ean').setValue(item?.product?.ean);
    this.control.get('name').setValue(item?.product?.name);
    this.control.get('contributors').setValue(item?.product?.contributors);
    this.control.get('manufacturer').setValue(item?.product?.manufacturer);
    this.control
      .get('price')
      .setValue(
        item?.catalogAvailability?.price?.value?.value ? String(item?.catalogAvailability?.price?.value?.value).replace('.', ',') : ''
      );
    this.control.get('vat').setValue(item?.catalogAvailability?.price?.vat?.vatType);
  }

  populateFormFromModalData(item: any) {
    this.control.get('name').setValue(item.name);
    this.control.get('contributors').setValue(item.contributors);
    this.control.get('manufacturer').setValue(item.manufacturer);
    this.control.get('price').setValue(item.price ? String(item.price).replace('.', ',') : '');
    this.control.get('vat').setValue(Number(item.vat));
    this.control.get('quantity').setValue(item.quantity);
    this.control.get('ean').setValue(item.ean);
    this.control.get('supplier').setValue(Number(item.supplier));
    this.control.get('estimatedShippingDate').setValue(item.estimatedShippingDate);
    this.changeEstimatedShippingDate(new Date(item.estimatedShippingDate)); // Update View
  }

  clearForm(withEan?: boolean) {
    if (withEan) {
      this.control.reset();
    } else {
      Object.keys(this.control.controls).forEach((key) => {
        if (key !== 'ean') {
          this.control.get(key).reset();
        }
      });
    }
    this.control.get('supplier').setValue(5);
    this.control.get('estimatedShippingDate').setValue(this._dateAdapter.today().toISOString());
    this.changeEstimatedShippingDate(this._dateAdapter.today());
    this.control.markAsUntouched();
  }

  async nextItem() {
    if (this.control.invalid || this.control.disabled) {
      this.control.enable();
      return;
    }
    this.control.disable();

    try {
      const branch = await this._store.currentBranch$.pipe(first()).toPromise();
      if (!!this._ref?.data && Object.keys(this._ref?.data).length !== 0) {
        await this._store.createAddToCartItem(this.control, branch, true);
        this._store.updateCart(() => {});
      } else {
        await this._store.createAddToCartItem(this.control, branch);
        this._store.addToCart(() => {});
      }
    } catch (error) {
      this._modal.open({
        title: 'Bestellung konnte nicht angelegt werden',
        content: UiErrorModalComponent,
        data: error,
      });
      console.error(error);
    }

    this.clearForm(true);
    this.control.enable();
  }

  async submit() {
    if (this.control.invalid || this.control.disabled) {
      this.control.enable();
      return;
    }
    this.control.disable();

    try {
      const branch = await this._store.currentBranch$.pipe(first()).toPromise();
      if (!!this._ref?.data && Object.keys(this._ref?.data).length !== 0) {
        await this._store.createAddToCartItem(this.control, branch, true);
        this._store.updateCart(async () => {
          // Set filter for navigation to customer search if customer is not set
          const customer = await this._store.customer$.pipe(first()).toPromise();
          const customerFilter = await this._store.customerFilter$.pipe(first()).toPromise();
          let filter: { [key: string]: string };
          if (!customer) {
            filter = customerFilter;
            this._router.navigate(['/kunde', this._applicationService.activatedProcessId, 'customer', 'search'], {
              queryParams: { customertype: filter.customertype },
            });
          } else {
            this._router.navigate(['/kunde', this._applicationService.activatedProcessId, 'cart', 'review']);
          }
          this._ref?.close();
        });
      } else {
        await this._store.createAddToCartItem(this.control, branch);
        this._store.addToCart(async () => {
          // Set filter for navigation to customer search if customer is not set
          const customer = await this._store.customer$.pipe(first()).toPromise();
          const customerFilter = await this._store.customerFilter$.pipe(first()).toPromise();
          let filter: { [key: string]: string };
          if (!customer) {
            filter = customerFilter;
            this._router.navigate(['/kunde', this._applicationService.activatedProcessId, 'customer', 'search'], {
              queryParams: { customertype: filter.customertype },
            });
          } else {
            this._router.navigate(['/kunde', this._applicationService.activatedProcessId, 'cart', 'review']);
          }
          this._ref?.close();
        });
      }
    } catch (error) {
      this._modal.open({
        title: 'Bestellung konnte nicht angelegt werden',
        content: UiErrorModalComponent,
        data: error,
      });
      console.error(error);
    }

    this.clearForm();
    this.control.enable();
  }
}
