import { Component, OnDestroy, OnInit } from '@angular/core';
import { ActivatedRoute } from '@angular/router';
import { Subscription } from 'rxjs';
import { EnduserBillingSummaryModel } from '@fleio-api/billing/model/enduser-billing-summary.model';
import { ICreditAndInvoicingInfoModel } from '@fleio-api/openstack/billing/model/credit-and-invoicing-info.model';
import { AuthService } from '@shared/auth/auth.service';
import { ConfigService } from '@shared/config/config.service';
import { IEnduserOpenstackSummaryModel } from '@fleio-api/openstack/model/enduser-openstack-summary.model';
import { PluginsApiService } from '@fleio-api/core/plugins-api.service';
import { IPluginModel } from '@fleio-api/core/model/plugin.model';
import { InvoicesApiService } from '@fleio-api/billing/invoices/invoices-api.service';
import { IInvoicePaymentOptionsModel } from '@fleio-api/billing/model/invoice-payment-options.model';
import { IGatewayModel } from '@fleio-api/billing/model/gateway.model';
import { NotificationService } from '@shared/ui-api/notification.service';
import * as _moment from 'moment';
import { BillingApiService } from '@fleio-api/billing/billing-api.service';
import { OpenstackApiService } from '@fleio-api/openstack/openstack-api.service';
import { OpenstackBillingApiService } from '@fleio-api/openstack/billing/openstack-billing-api.service';
import { IIcon } from '@shared/ui/common/interfaces/icon';

@Component({
  selector: 'app-dashboard',
  templateUrl: './dashboard.component.html',
  styleUrls: ['./dashboard.component.scss']
})
export class DashboardComponent implements OnInit, OnDestroy {
  routeDataSubscription: Subscription;
  billingSummary: EnduserBillingSummaryModel;
  creditAndInvoicingInfo: ICreditAndInvoicingInfoModel;
  openstackSummary: IEnduserOpenstackSummaryModel;
  externalBillingUrl: string;
  plugins: Array<IPluginModel> = [];
  paymentOpts: IInvoicePaymentOptionsModel;
  loadingAddPayment = false;
  showUnpaidInvoicesWidget = false;
  upToDateCreditInfo = {
    name: 'info',
    verticalAlign: 'middle',
    fontSize: '20px',
    marginLeft: '5px',
  } as IIcon;

  constructor(
    private activatedRoute: ActivatedRoute,
    public auth: AuthService,
    public config: ConfigService,
    private invoicesApiService: InvoicesApiService,
    private pluginsApiService: PluginsApiService,
    private notificationService: NotificationService,
    private billingApiService: BillingApiService,
    private openstackApiService: OpenstackApiService,
    private openstackBillingApiService: OpenstackBillingApiService,
  ) {
  }

  addPaymentDetails() {
    this.loadingAddPayment = true;
    if (this.paymentOpts) {
      this.redirectToAddPayment();
    } else {
      this.invoicesApiService.validate_credit_card_payment_opts().subscribe({
        next: response => {
          this.paymentOpts = response;
          this.redirectToAddPayment();
        }, error: error => {
          this.loadingAddPayment = false;
        }
      });
    }
  }

  private redirectToAddPayment() {
    if (this.paymentOpts.gateways.length) {
      const gatewayDetails = this.paymentOpts.gateways[0] as IGatewayModel;
      if (gatewayDetails?.name) {
        this.config.authService.generateOtpToken().subscribe(token => {
          const params = `fleio-token=${token}&invoice=${encodeURIComponent(this.paymentOpts.invoice_id)}&recurring=True&cardValidation=True`;
          window.location.href = this.config.getPanelApiUrl(
            'billing/gateway/' + gatewayDetails.name + '/pay_invoice?' + params,
          );
        }).add(() => {
          this.loadingAddPayment = false;
        });
      }
    } else {
      this.loadingAddPayment = false;
      this.notificationService.showMessage($localize`No gateway available! Please contact support.`);
    }
  }

  processBillingSummary() {
    this.showUnpaidInvoicesWidget = this.auth.feature('billing.invoices') && this.billingSummary &&
      this.billingSummary.invoices_details.invoices_count >= 1;
    if (this.billingSummary?.latest_data_from) {
      const currentTime = new Date();
      const humanizedTimeDiff = _moment.duration(
        // @ts-ignore
        currentTime - new Date(this.billingSummary.latest_data_from)
      ).locale(this.config.locale).humanize();
      this.upToDateCreditInfo.tooltip = $localize`Based on data from ${humanizedTimeDiff} ago`;
    }
  }

  ngOnInit() {
    let osSummaryInitiated = false; // used to track if OS related summaries are initiated after billing
    if (this.auth.feature('billing')) {
      // if billing enabled, first load billing summary then OpenStack related summaries
      // in order to avoid waiting too long for all of them
      osSummaryInitiated = true;
      this.billingApiService.getSummary().subscribe(value => {
        this.billingSummary = value;
        this.processBillingSummary();
        if (this.auth && this.auth.feature('openstack')) {
          this.openstackApiService.getSummary().subscribe(osSummaryValue => {
            this.openstackSummary = osSummaryValue;
            if (this.auth.feature('billing.credit_estimate')) {
              this.openstackBillingApiService.getCreditAndInvoicingInfo().subscribe(invValue => {
                this.creditAndInvoicingInfo = invValue;
              });
            }
          });
        }
      });
    }

    if (!osSummaryInitiated && this.auth && this.auth.feature('openstack')) {
      // load OpenStack summary here if billing disabled
      this.openstackApiService.getSummary().subscribe(value => {
        this.openstackSummary = value;
      });
    }

    this.routeDataSubscription = this.activatedRoute.data.subscribe(data => {
      this.externalBillingUrl = data.externalBillingUrlResponse.external_billing_url;
    });

    if (this.auth.feature('plugins')) {
      this.pluginsApiService.pluginsWithComponent(
        'DashboardServicesRows'
      ).subscribe(response => {
        this.plugins = response.plugins;
      });
    }
  }

  ngOnDestroy() {
    if (this.routeDataSubscription) {
      this.routeDataSubscription.unsubscribe();
      this.routeDataSubscription = null;
    }
  }
}
