import { ChangeDetectionStrategy, Component, OnDestroy, OnInit } from '@angular/core';
import { UntypedFormBuilder, UntypedFormGroup, Validators } from '@angular/forms';
import { ApplicationService } from '@core/application';
import { ItemDTO } from '@generated/swagger/cat-search-api';
import { DateAdapter } from '@ui/common';
import { UiErrorModalComponent, UiModalRef, UiModalService } from '@ui/modal';
import { Subject } from 'rxjs';
import { first, shareReplay, takeUntil } from 'rxjs/operators';
import { CheckoutDummyData } from './checkout-dummy-data';
import { CheckoutDummyStore } from './checkout-dummy.store';
import { CheckoutNavigationService, CustomerSearchNavigation } from '@shared/services/navigation';
import { Router } from '@angular/router';

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

  // 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 _fb: UntypedFormBuilder,
    private _dateAdapter: DateAdapter,
    private _modal: UiModalService,
    private _store: CheckoutDummyStore,
    private _ref: UiModalRef<any, CheckoutDummyData>,
    private readonly _applicationService: ApplicationService,
    private readonly _checkoutNavigationService: CheckoutNavigationService,
    private readonly _customerNavigationService: CustomerSearchNavigation,
    private _router: Router,
  ) {}

  ngOnInit() {
    this.initForm();

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

    if (this.hasShoppingCartItemToUpdate()) {
      const data = this._ref?.data;
      this._store.patchState({ shoppingCartItem: data });
      this.populateFormFromModalData(data);
    }
  }

  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: CheckoutDummyData) {
    let price = item?.availability?.price?.value?.value ?? '';
    price = String(price).replace('.', ',');

    let estimatedShippingDate = item?.estimatedShippingDate ?? this._dateAdapter.today().toISOString();

    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(price);
    this.control.get('vat').setValue(Number(item?.availability?.price?.vat?.vatType));
    this.control.get('quantity').setValue(item.quantity);
    this.control.get('ean').setValue(item?.product?.ean);
    this.control.get('supplier').setValue(Number(item?.availability?.supplier?.id));
    this.control.get('estimatedShippingDate').setValue(estimatedShippingDate);
    this.changeEstimatedShippingDate(new Date(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();
  }

  hasShoppingCartItemToUpdate(): boolean {
    const hasShoppingCartItem = !!this._ref.data?.id;
    if (!!this._ref?.data && hasShoppingCartItem) {
      return true;
    }
    return false;
  }

  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.hasShoppingCartItemToUpdate()) {
        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.hasShoppingCartItemToUpdate()) {
        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 && !this._ref?.data?.changeDataFromCart) {
            filter = customerFilter;
            const path = this._customerNavigationService.defaultRoute({
              processId: this._applicationService.activatedProcessId,
            }).path;
            await this._router.navigate(path, {
              queryParams: { customertype: filter.customertype },
            });
          } else {
            await this._checkoutNavigationService
              .getCheckoutReviewPath(this._applicationService.activatedProcessId)
              .navigate();
          }
          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 && !this._ref?.data?.changeDataFromCart) {
            filter = customerFilter;
            const path = this._customerNavigationService.defaultRoute({
              processId: this._applicationService.activatedProcessId,
            }).path;
            await this._router.navigate(path, {
              queryParams: { customertype: filter.customertype },
            });
          } else {
            await this._checkoutNavigationService
              .getCheckoutReviewPath(this._applicationService.activatedProcessId)
              .navigate();
          }
          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();
  }
}
