import { Component, OnInit, Optional, ViewChild } from '@angular/core';
import { ActivatedRoute, Router } from '@angular/router';
import { ConfigService } from '@shared/config/config.service';
import { IOrderOptionsModel } from '@fleio-api/billing/cart/model/order-options.model';
import { FleioId } from '@fleio-api/base-model/base-fleio-object.model';
import { CartItemsApiService } from '@fleio-api/billing/cart/cart-items-api.service';
import { NotificationService } from '@shared/ui-api/notification.service';
import { ICartItemModel } from '@fleio-api/billing/cart/model/cart-items.model';
import { UntypedFormBuilder } from '@angular/forms';
import { PanelLayoutComponent } from '@shared/layout/panel-layout/panel-layout.component';

@Component({
  selector: 'app-cart-item',
  templateUrl: './cart-item.component.html',
  styleUrls: ['./cart-item.component.scss']
})
export class CartItemComponent implements OnInit {
  @ViewChild('formErrors') formErrors;
  @ViewChild('pluginComponent') pluginComponent;
  orderForm = this.formBuilder.group({});
  orderOptions: IOrderOptionsModel;
  cartItem: ICartItemModel;
  selectedCycle: FleioId;
  optionsChanged: boolean;
  configOptionValues: { [key: number]: string } = {};
  backendErrors = {};
  loading = false;

  constructor(
    private activatedRoute: ActivatedRoute,
    private cartItemsApi: CartItemsApiService,
    private router: Router,
    public config: ConfigService,
    private notificationService: NotificationService,
    private formBuilder: UntypedFormBuilder,
    @Optional() public panelLayout?: PanelLayoutComponent,
  ) {
  }

  ngOnInit(): void {
    if (this.activatedRoute.snapshot.data?.orderOptions) {
      this.orderOptions = this.activatedRoute.snapshot.data.orderOptions;
      this.cartItem = this.activatedRoute.snapshot.data.cartItem;
      this.selectedCycle = this.cartItem.cycle;
      for (const option of this.orderOptions.configurable_options) {
        this.configOptionValues[option.id] = null;
      }

      for (const option of this.cartItem.configurable_options) {
        this.configOptionValues[option.option] = option.option_value;
      }
    }
  }

  saveToCart() {
    const configurableOptions = [];
    for (const option of this.orderOptions.configurable_options) {
      if (this.configOptionValues[option.id] !== null) {
        configurableOptions.push({
          option: option.id,
          option_value: this.configOptionValues[option.id],
        });
      }
    }
    this.cartItem.configurable_options = configurableOptions;
    this.cartItem.cycle = this.selectedCycle;
    this.loading = true;
    this.cartItemsApi.update(this.cartItem.id, this.cartItem).subscribe(() => {
      this.notificationService.showMessage($localize`Cart item updated`);
      if (this.config.authService.feature('ui.staff')) {
        this.router.navigateByUrl(this.config.getPanelUrl('orders/cart')).then(() => {});
      } else {
        this.router.navigateByUrl(this.config.getPanelUrl('billing/cart')).then(() => {});
      }
    }, (error) => {
      this.loading = false;
      if (error.status === 403) {
        this.notificationService.showMessage(
          error.error?.detail || $localize`You do not have permissions to edit products`,
        );
      } else {
        if (Array.isArray(error.error.configurable_options) && error.error.configurable_options.length) {
          // treat configurable options errors coming as a list separately
          this.backendErrors = {};
          for (const respError of error.error.configurable_options) {
            Object.assign(this.backendErrors, respError);
          }
          return;
        } else {
          if (error.error) {
            if (error.error.plugin_data) {
              if (this.pluginComponent) {
                this.pluginComponent.setErrors(error.error.plugin_data);
              }
              delete error.error.plugin_data;
            }
            if (this.formErrors.setBackendErrors(error.error, this.configOptionValues)) {
              this.backendErrors = error.error;
              return;
            }
          }
        }
      }
    });
  }

  productCycleChanged(newCycle) {
    this.cartItemsApi.getEditOptions(this.cartItem.id).subscribe(orderOptions => {
      this.orderOptions = orderOptions as IOrderOptionsModel;
    });
  }
}
