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

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

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

  ngOnInit(): void {
    if (this.activatedRoute.snapshot.data?.orderOptions) {
      this.orderOptions = this.activatedRoute.snapshot.data.orderOptions;
      this.selectedCycle = this.orderOptions.cycles[0].id;
      for (const option of this.orderOptions.configurable_options) {
        if (option.default_value) {
          this.configOptionValues[option.id] = option.default_value;
        } else if (option.widget === 'yesno') {
          this.configOptionValues[option.id] = 'no';
        } else {
          this.configOptionValues[option.id] = null;
        }
      }
      if (this.activatedRoute.snapshot.params?.cycle) {
        const preselectedCycleId = this.activatedRoute.snapshot.params.cycle;
        if (preselectedCycleId && this.orderOptions.cycles && this.orderOptions.cycles.length &&
          this.orderOptions.cycles.find(x => x.id.toString() === preselectedCycleId.toString())) {
          this.selectedCycle = Number.parseInt(preselectedCycleId, 10);
        }
      }
    }
  }

  saveToCart() {
    const pluginData = JSON.parse(JSON.stringify(this.pluginData));
    if (typeof pluginData.valid !== 'undefined' && !pluginData.valid) {
      return;
    } else {
      delete pluginData.valid;  // remove flag used for validation only
    }
    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],
        });
      }
    }

    let domainName = null;
    let domainAction = null;
    if (this.activatedRoute.snapshot.params.domain_action) {
      domainAction = this.activatedRoute.snapshot.params.domain_action;
    }
    if (this.activatedRoute.snapshot.params.domain_name) {
      domainName = this.activatedRoute.snapshot.params.domain_name;
    }

    this.loading = true;
    this.cartItemsApi.orderProduct(
      this.orderOptions.id,
      this.selectedCycle,
      configurableOptions,
      domainAction,
      domainName,
      pluginData,
    ).subscribe({
      next: (response) => {
        if (this.orderOptions.requires_domain && (domainAction === 'order_new' || domainAction === 'transfer')) {
          this.router.navigateByUrl(
            this.config.getPanelUrl(`billing/order/domain-options/${response.id}/${domainAction}/${domainName}`)
          ).then(() => {
          });
        } else {
          this.router.navigateByUrl(this.config.getPanelUrl('billing/cart')).then(() => {
          });
        }
      }, error: (error) => {
        this.loading = false;
        if (error.status === 403) {
          this.notificationService.showMessage(
            error.error?.detail || $localize`You do not have permissions to order products`,
          );
        } else {
          if (error.error) {
            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;
                }
              }
            }
          }
          this.notificationService.showMessage($localize`Order product failed, please contact support`);
        }
      }
    });
  }

  productCycleChanged(newCycle) {
    this.cartItemsApi.createOptions({
      product_code: this.orderOptions.code,
      cycle: newCycle,
    }).subscribe(orderOptions => {
      this.orderOptions = orderOptions as IOrderOptionsModel;
    });
  }
}
