import { Component, OnInit, ViewChild } from '@angular/core';
import { DetailsComponentBase } from '@objects-view/details-component-base';
import { ICartItemsModel } from '@fleio-api/billing/cart/model/cart-item.model';
import { IAction } from '@objects-view/interfaces/actions/action';
import { CartItemsApiService } from '@fleio-api/billing/cart/cart-items-api.service';
import { RouterLinkAction } from '@objects-view/actions/router-link-action';
import { ActivatedRoute, Router } from '@angular/router';
import { ConfigService } from '@shared/config/config.service';
import { CallbackAction } from '@objects-view/actions/callback-action';
import { Observable, of } from 'rxjs';
import { NotificationService } from '@shared/ui-api/notification.service';
import { RefreshService } from '@shared/ui-api/refresh.service';
import { UntypedFormBuilder } from '@angular/forms';
import { CartUtilsService } from '@fleio-api/billing/cart/cart-utils.service';
import { CartApiService } from '@fleio-api/billing/cart/cart-api.service';
import { IActionResult } from '@objects-view/interfaces/actions/action-result';
import { MenuService } from '@shared/ui/menu/menu.service';
import { ICartItemModel } from '@fleio-api/billing/cart/model/cart-items.model';

@Component({
  selector: 'app-cart-details-overview',
  templateUrl: './cart-details-overview.component.html',
  styleUrls: ['./cart-details-overview.component.scss']
})
export class CartDetailsOverviewComponent extends DetailsComponentBase<ICartItemsModel> implements OnInit {
  @ViewChild('formErrors') formErrors;
  orderForm = this.formBuilder.group({});
  cartItems: ICartItemsModel;
  cartItemActions: { [key: number]: IAction[] };
  displayedColumns = ['product', 'cycle', 'actions'];

  acceptOrder = true;
  generateInvoice = true;
  sendEmail = true;

  constructor(
    private cartItemsApi: CartItemsApiService,
    private cartApiService: CartApiService,
    private router: Router,
    private notificationService: NotificationService,
    private refreshService: RefreshService,
    private activatedRoute: ActivatedRoute,
    public config: ConfigService,
    private formBuilder: UntypedFormBuilder,
    private cartUtilsService: CartUtilsService,
    private menuService: MenuService,
  ) {
    super();
  }

  ngOnInit() {
    super.ngOnInit();
    if (this.objectController) {
      this.objectController.actionCallback = () => this.placeOrder();
    }
    this.init();
  }

  startOrderForAnotherClient() {
    if (this.cartItems && this.cartItems.client) {
      this.cartItemsApi.dropCart().subscribe(() => {
        this.router.navigateByUrl(this.config.getPanelUrl('orders/create'))
      });
    } else {
      this.cartItemsApi.dropCart().subscribe(() => {
        this.router.navigateByUrl(this.config.getPanelUrl('orders/create'))
      });
    }
  }

  checkAndProcessDomains() {
    const cart = this.activatedRoute.snapshot.data.cartItems;
    const domainsToProcess = [];
    for (const cartItem of cart.items) {
      if (cartItem.domain_name && (cartItem.domain_action === 'order_new' || cartItem.domain_action === 'transfer')) {
        domainsToProcess.push(cartItem.domain_name);
      }
    }

    for (const cartItem of cart.items) {
      if (cartItem.plugin_label === 'domains') {
        const domainsToCheckIndex = domainsToProcess.indexOf(cartItem.name);
        if (-1 !== domainsToCheckIndex) {
          domainsToProcess.splice(domainsToCheckIndex, 1);
        }
      }
    }

    for (const cartItem of cart.items) {
      if (cartItem.domain_name && (cartItem.domain_action === 'order_new' || cartItem.domain_action === 'transfer')) {
        if (-1 !== domainsToProcess.indexOf(cartItem.domain_name)) {
          if (this.authSvc.feature('ui.staff')) {
            this.router.navigateByUrl(
              this.config.getPanelUrl(`orders/domain-options/${cartItem.id}/${cartItem.domain_action}/${cartItem.domain_name}`)
            ).then(() => {
            });
          } else {
            this.router.navigateByUrl(
              this.config.getPanelUrl(`billing/order/domain-options/${cartItem.id}/${cartItem.domain_action}/${cartItem.domain_name}`)
            ).then(() => {
            });
          }
          return false;
        }
      }
    }
    return true;
  };

  placeOrder() {
    this.objectController.loading = this.primaryAction.disabled = true;

    if (!this.checkAndProcessDomains()) {
      // domains still need to be processed, aborting order
      this.objectController.loading = this.primaryAction.disabled = false;
      return of(null);
    }

    return new Observable<IActionResult>(subscriber => {
      this.cartApiService.order(
        {
          'accept_order': this.acceptOrder,
          'generate_invoice': this.generateInvoice,
          'send_email': this.sendEmail,
        }
      ).pipe().subscribe({
        next: (response) => {
          this.notificationService.showMessage($localize`Order placed.`);
          if (response.order_status && response.order_status === 'fraud') {
            this.router.navigateByUrl(this.config.getPanelUrl('billing/order/under-review')).then(() => {
            });
          } else {
            this.router.navigateByUrl(this.config.getPanelUrl('billing/invoices')).then(() => {
            });
          }
          subscriber.next({success: true, message: $localize`Order placed.`});
        },
        error: (error) => {
          this.objectController.loading = this.primaryAction.disabled = false;
          if (error.error) {
            if (this.formErrors) {
              this.formErrors.setBackendErrors(error.error);
            }
          }
          subscriber.next({success: false, message: $localize`Failed to place order.`});
        }
      }).add(() => {
        subscriber.complete();
      });
    });
  }

  private init() {
    if (this.objectController?.additionalObjects?.cartItems) {
      this.cartItems = this.objectController.additionalObjects.cartItems;
      const disableActions = !this.cartItems?.items?.length; // disable main actions if no item in cart
      this.cartItemActions = {};
      if (this.cartItems?.items?.length) {
        for (const cartItem of this.cartItems.items) {
          this.cartItemActions[cartItem.id] = this.getCartItemActions(cartItem);
        }
        if (!this.authSvc.userData?.user?.id) {
          // remember that we need to redirect to cart after login/register
          this.cartUtilsService.redirectToCart = true;
        }
      }
      if (disableActions) {
        this.detailsActions[1].disabled = true;
        if (this.detailsActions.length === 3) {
          // one more button for unregistered user
          this.detailsActions[2].disabled = true;
        }
      }
    }
  }

  private getCartItemActions(cartItem: ICartItemModel): IAction[] {
    let editUrl: string;
    if (this.authSvc.feature('ui.staff')) {
      editUrl = this.config.getPanelUrl('orders/cart', cartItem.id);
    } else {
      editUrl = this.config.getPanelUrl('billing/cart', cartItem.id);
    }
    return [
      new RouterLinkAction({
          icon: {name: 'edit', class: 'fl-icons'},
          name: $localize`Edit`,
          tooltip: $localize`Edit`,
          routerUrl: editUrl,
          router: this.router,
          noPermissions: !this.cartItems.item_permissions['cartitems.update'],
        }
      ),
      new CallbackAction(
        {
          object: cartItem,
          icon: {name: 'delete'},
          name: $localize`Delete`,
          tooltip: $localize`Delete cart item`,
          callback: () => {
            this.refreshService.resetPageChanged();
            this.cartItemsApi.delete(cartItem.id).subscribe(() => {
              this.notificationService.showMessage($localize`Cart item deleted`);
              this.refreshService.refresh(() => {
                this.objectController.additionalObjects.cartItems = this.activatedRoute.snapshot.data.cartItems;
                this.init();
              }, true);
              this.menuService.menuItemsCount.next(true);
            });
            return of(null);
          },
          noPermissions: !this.cartItems.item_permissions['cartitems.destroy'],
        }
      )
    ];
  }
  getRecurringPrices() {
    const recurringPrices : { [key: string]: { price: number; has_dynamic_usage: boolean }} = {};
    for (const orderItem of this.cartItems.items) {
      if (orderItem.recurring_price) {
        var prices: { price: any; has_dynamic_usage: any; };
        if (recurringPrices[orderItem.cycle_display]) {
          prices = recurringPrices[orderItem.cycle_display];
        } else {
          prices = {
            price: 0,
            has_dynamic_usage: false,
          };
          recurringPrices[orderItem.cycle_display] = prices;
        }

        prices.price += orderItem.recurring_price
        prices.has_dynamic_usage = prices.has_dynamic_usage || orderItem.postpaid_product;
      }
    }

    return recurringPrices;
  }
}
