// modules/invoice/infrastructure/invoice-dependencies.factory.ts

import type { IMapperRegistry, IPresenterRegistry, ModuleParams } from "@erp/core/api";

import {
  InMemoryMapperRegistry,
  InMemoryPresenterRegistry,
  SequelizeTransactionManager,
} from "@erp/core/api";
import { SendInvoiceUseCase } from "../application";
import { VerifactuRecordFullPresenter } from "../application/presenters/domain/verifactu-record.full.presenter";
import { VerifactuRecordService } from "../domain";
//import { VerifactuRecordItemsReportPersenter } from "../application/presenters/queries/verifactu-record-items.report.presenter";
import { VerifactuRecordDomainMapper } from "./mappers";
import { VerifactuRecordRepository } from "./sequelize";

export type VerifactuRecordDeps = {
  transactionManager: SequelizeTransactionManager;
  mapperRegistry: IMapperRegistry;
  presenterRegistry: IPresenterRegistry;
  repo: VerifactuRecordRepository;
  service: VerifactuRecordService;
  build: {
    send: () => SendInvoiceUseCase;
  };
  getService: (name: string) => any;
  listServices: () => string[];
};

export function buildVerifactuDependencies(params: ModuleParams): VerifactuRecordDeps {
  const { database, listServices, getService } = params;
  const transactionManager = new SequelizeTransactionManager(database);

  // Mapper Registry
  const mapperRegistry = new InMemoryMapperRegistry();
  mapperRegistry.registerDomainMapper(
    { resource: "verifactu-record" },
    new VerifactuRecordDomainMapper({})
  );
  /*    .registerQueryMappers([
      {
        key: { resource: "verifactu-record", query: "LIST" },
        mapper: new VerifactuRecordListMapper(),
      },
    ]);
*/

  // Repository & Services
  const repo = new VerifactuRecordRepository({ mapperRegistry, database });
  const service = new VerifactuRecordService(repo);

  // Presenter Registry
  const presenterRegistry = new InMemoryPresenterRegistry();
  presenterRegistry.registerPresenters([
    {
      key: {
        resource: "verifactu-record",
        projection: "FULL",
      },
      presenter: new VerifactuRecordFullPresenter(presenterRegistry),
    },
  ]);

  return {
    transactionManager,
    repo,
    mapperRegistry,
    presenterRegistry,
    service,
    build: {
      send: () => new SendInvoiceUseCase(service, transactionManager, presenterRegistry),
      //      get: () => new GetVerifactuRecordUseCase(service, transactionManager, presenterRegistry),
      /*      create: () =>
        new CreateVerifactuRecordUseCase(
          service,
          transactionManager,
          presenterRegistry,
        ),
*/
      // update: () => new UpdateVerifactuRecordUseCase(service, transactionManager),
      // delete: () => new DeleteVerifactuRecordUseCase(service, transactionManager),
    },
    listServices,
    getService,
  };
}
