import { RemissionModuleOptions } from './remission-module.options';
import { CatsearchApiRequestOptions } from '@isa/catsearch-api';
import { RemiApiRequestOptions } from '@isa/remi-api';
import { PrintApiRequestOptions } from '@isa/print-api';
import { NgModule, ModuleWithProviders } from '@angular/core';
import { RestRemissionService } from './services/rest-remission.service';
import { MockRemissionService } from './mock/mock-remission.service';
import { Mapper } from './mappings/mapper';
import { ReturnSuggestionDtoToRemissionProductMapping } from './mappings/return-suggestion-dto-to-remission-product.mapping';
import { ItemDtoToProductMapping } from './mappings/item-dto-to-product.mapping';
import { ProductToPriceDTOMapping } from './mappings/product-to-price-dto';
import { ProductToProductDTOMapping } from './mappings/product-to-product-dto';
import { ReturnItemDtoToRemissionProductMapping } from './mappings/return-item-dto-to-remission-product.mapping';
import { ReceiptItemDtoToRemissionProductMapping } from './mappings/receipt-item-dto-to-remission-product.mapping';
import { ReceiptDTOToShippingDocumentMapping } from './mappings/receipt-dto-to-shipping-document.mapping';
import { RemissionService } from './services/remission.service';
import { BaseUrlInterceptor, CatchResponseArgsErrorInterceptor, LogErrorInterceptor } from '@cmf/core';
import { HTTP_INTERCEPTORS } from '@angular/common/http';
import { FeaturesToAssortmentMapping } from './mappings/features-to-assortment.mapping';
import { SupplierDtoToRemissionSupplier } from './mappings/supplier-dto-to-remssion-supplier.mapping';

export function catsearchApiRequestOptionsFactory(options: RemissionModuleOptions): CatsearchApiRequestOptions {
  return {
    baseUrl: (options.endpoints && options.endpoints.catsearch) || '',
    catchResponseArgsError: true,
  };
}
export function remiApiRequestOptionsFactory(options: RemissionModuleOptions): RemiApiRequestOptions {
  return {
    baseUrl: (options.endpoints && options.endpoints.remi) || '',
    catchResponseArgsError: true,
  };
}
export function printApiRequestOptionsFactory(options: RemissionModuleOptions): PrintApiRequestOptions {
  return {
    baseUrl: (options.endpoints && options.endpoints.print) || '',
    catchResponseArgsError: true,
  };
}

export function remissionServiceFactory(options: RemissionModuleOptions, rest: RestRemissionService, mock: MockRemissionService) {
  return options.useMock ? mock : rest;
}

@NgModule({
  declarations: [],
  imports: [],
  exports: [],
})
export class RemissionModule {
  static forRoot(options: RemissionModuleOptions): ModuleWithProviders<RemissionModule> {
    return {
      ngModule: RemissionModule,
      providers: [
        {
          provide: RemissionModuleOptions,
          useValue: options,
        },
        {
          provide: CatsearchApiRequestOptions,
          useFactory: catsearchApiRequestOptionsFactory,
          deps: [RemissionModuleOptions],
        },
        {
          provide: RemiApiRequestOptions,
          useFactory: remiApiRequestOptionsFactory,
          deps: [RemissionModuleOptions],
        },
        {
          provide: PrintApiRequestOptions,
          useFactory: printApiRequestOptionsFactory,
          deps: [RemissionModuleOptions],
        },
        {
          provide: Mapper,
          useClass: ReturnSuggestionDtoToRemissionProductMapping,
          multi: true,
        },
        {
          provide: Mapper,
          useClass: ItemDtoToProductMapping,
          multi: true,
        },
        {
          provide: Mapper,
          useClass: ProductToPriceDTOMapping,
          multi: true,
        },
        {
          provide: Mapper,
          useClass: ProductToProductDTOMapping,
          multi: true,
        },
        {
          provide: Mapper,
          useClass: ReturnItemDtoToRemissionProductMapping,
          multi: true,
        },
        {
          provide: Mapper,
          useClass: ReceiptItemDtoToRemissionProductMapping,
          multi: true,
        },
        {
          provide: Mapper,
          useClass: ReceiptDTOToShippingDocumentMapping,
          multi: true,
        },
        {
          provide: Mapper,
          useClass: FeaturesToAssortmentMapping,
          multi: true,
        },
        {
          provide: Mapper,
          useClass: SupplierDtoToRemissionSupplier,
          multi: true,
        },
        {
          provide: RemissionService,
          useFactory: remissionServiceFactory,
          deps: [RemissionModuleOptions, RestRemissionService, MockRemissionService],
        },
        {
          provide: HTTP_INTERCEPTORS,
          useClass: BaseUrlInterceptor,
          multi: true,
        },
        {
          provide: HTTP_INTERCEPTORS,
          useClass: CatchResponseArgsErrorInterceptor,
          multi: true,
        },
        {
          provide: HTTP_INTERCEPTORS,
          useClass: LogErrorInterceptor,
          multi: true,
        },
      ],
    };
  }
}
