import { Injectable } from '@angular/core';
import { ConfigService } from '@shared/config/config.service';
import { FleioApiService } from '../../fleio-api.service';
import { HttpClient } from '@angular/common/http';
import { IServiceModel } from '../model/service.model';
import { FleioId } from '@fleio-api/base-model/base-fleio-object.model';
import { Observable } from 'rxjs';
import { IServiceUpgradeOptionsModel } from '@fleio-api/billing/model/service-upgrade-options.model';
import { IServiceUpgradeModel } from '@fleio-api/billing/model/service-upgrade-.model';
import { IServiceHostingAccountModel } from '@fleio-api/billing/services/model/service-hosting-account.model';
import { map } from 'rxjs/operators';

@Injectable({
  providedIn: 'root'
})
export class ServicesApiService extends FleioApiService<IServiceModel> {
  // noinspection JSUnusedGlobalSymbols
  constructor(protected httpClient: HttpClient, protected config: ConfigService) {
    super();
    this.setEndpoint(config.getPanelApiUrl('billing/services'));
  }

  upgradeOptions(serviceId: FleioId, newCycleId?: FleioId, newProductId?: FleioId): Observable<IServiceUpgradeOptionsModel> {
    const qp = {} as Record<any, any>;
    if (newCycleId) {
      qp.new_cycle_id = newCycleId;
    }
    if (newProductId) {
      qp.new_product_id = newProductId;
    }
    return this.objectGetAction(serviceId, 'upgrade_options', qp);
  }

  upgrade(serviceId: FleioId, upgradeRequest: IServiceUpgradeModel): Observable<any> {
    return this.objectPostAction(serviceId, 'upgrade', upgradeRequest);
  }

  updateHostingAccount(serviceId: FleioId, hostingAccount: IServiceHostingAccountModel): Observable<any> {
    return this.objectPutAction(serviceId, 'update_hosting_account', hostingAccount);
  }

  enableBilling(serviceId: FleioId, newCycleStart): Observable<any> {
    return this.objectPostAction(serviceId, 'enable_billing', {new_cycle_start: newCycleStart});
  }

  newCycle(serviceId: FleioId): Observable<any> {
    return this.objectPostAction(serviceId, 'new-cycle', {});
  }

  settleAllCycles(serviceId: FleioId): Observable<any> {
    return this.objectPostAction(serviceId, 'settle-all-cycles', {});
  }

  terminate(serviceId: FleioId): Observable<any> {
    return this.objectPostAction(serviceId, 'terminate', {id: serviceId});
  }

  updateBillingPlan(serviceId: FleioId, newPlan): Observable<any> {
    return this.objectPostAction(serviceId, 'update_billing_plan', {plan: newPlan});
  }

  hasAssociatedResource(serviceId: FleioId): Observable<{
    has_associated_resource: boolean;
    resource_details: {
      project_id: string;
    };
  }> {
    return this.objectGetAction(serviceId, 'has_associated_resource');
  }

  removeResourceAssociation(serviceId: FleioId) {
    return this.objectPostAction(serviceId, 'remove_service_associated_resource', {});
  }

  changeResourceAssociation(serviceId: FleioId, projectId: FleioId) {
    return this.objectPostAction(serviceId, 'change_service_associated_resource', {
      project_id: projectId
    });
  }

  getNewFixedPrice(
    serviceId: FleioId, newCycleId: FleioId, configurableOptions, priceOverride, priceOverrideModel,
    priceOverrideType, priceOverrideTiers, overrideValue, discountValue, discountPercent,
  ) {
    return this.objectPostAction(serviceId, 'get_new_fixed_price', {
      cycle_id: newCycleId,
      configurable_options: configurableOptions,
      price_override: priceOverride,
      price_override_model: priceOverrideModel,
      price_override_type: priceOverrideType,
      price_override_tiers: priceOverrideTiers,
      override_value: overrideValue,
      discount_value: discountValue,
      discount_percent: discountPercent,
    });
  }

  cancel(serviceId: FleioId, cancellationRequest: Record<string, any>): Observable<any> {
    return this.objectPostAction(serviceId, 'cancel', cancellationRequest);
  }

  suspend(serviceId: FleioId, suspendFlags: { [id: string]: boolean } = {}): Observable<any> {
    return this.objectPostAction(serviceId, 'suspend', {flags: suspendFlags});
  }

  pluginAction(serviceId: FleioId, actionName: string, args: Record<string, any>): Observable<any> {
    return this.objectPostAction(serviceId, 'plugin_action', {
      action_name: actionName, arguments: args,
    });
  }

  getCycleEndDT(serviceId: FleioId, innerDate: Date): Observable<Date> {
    return this.objectGetAction(
      serviceId, 'get_cycle_end_dt', {inner_date: innerDate.toISOString()},
    ).pipe(map(response => {
      const endDT = new Date(response['end_dt']);
      return endDT;
    }));
  }
  renewEarly(domainId: FleioId): Observable<any> {
    return this.objectPostAction(domainId, 'renew_early', {});
  }
}
