import { type TailorAnyDBField } from "@tailor-platform/sdk";
import { createCategory } from "./command/createCategory.generated";
import { createCurrency } from "./command/createCurrency.generated";
import { createUnit } from "./command/createUnit.generated";
import { createExchangeRate } from "./command/createExchangeRate.generated";
import { activateCategory } from "./command/activateCategory.generated";
import { deactivateCategory } from "./command/deactivateCategory.generated";
import { activateUnit } from "./command/activateUnit.generated";
import { deactivateUnit } from "./command/deactivateUnit.generated";
import { setReferenceUnit } from "./command/setReferenceUnit.generated";
import { convertQuantity } from "./query/convertQuantity.generated";
import { getUnit } from "./query/getUnit.generated";
import { getCurrency } from "./query/getCurrency.generated";
import { getUoMCategory } from "./query/getUoMCategory.generated";
import { getBaseCurrency } from "./query/getBaseCurrency.generated";
import { listUnitsByCategory } from "./query/listUnitsByCategory.generated";
import { activateCurrency } from "./command/activateCurrency.generated";
import { deactivateCurrency } from "./command/deactivateCurrency.generated";
import { setBaseCurrency } from "./command/setBaseCurrency.generated";
import { convertAmount } from "./query/convertAmount.generated";
import { createUoMCategoryType, CreateUoMCategoryTypeParams } from "./db/uomCategory";
import { createUnitType, CreateUnitTypeParams } from "./db/unit";
import { createCurrencyType, CreateCurrencyTypeParams } from "./db/currency";
import { createExchangeRateType, CreateExchangeRateTypeParams } from "./db/exchangeRate";
import { type EmptyFields, type FieldsToInsertable } from "@tailor-platform/erp-kit/module";

export interface DefineModuleParams<
  CatF extends Record<string, TailorAnyDBField>,
  UnitF extends Record<string, TailorAnyDBField>,
  CurF extends Record<string, TailorAnyDBField>,
  ERF extends Record<string, TailorAnyDBField>,
> {
  uomCategory?: CreateUoMCategoryTypeParams<CatF>;
  unit?: CreateUnitTypeParams<UnitF>;
  currency?: CreateCurrencyTypeParams<CurF>;
  exchangeRate?: CreateExchangeRateTypeParams<ERF>;
}

/* @__NO_SIDE_EFFECTS__ */
export const defineModule = <
  const CatF extends Record<string, TailorAnyDBField> = EmptyFields,
  const UnitF extends Record<string, TailorAnyDBField> = EmptyFields,
  const CurF extends Record<string, TailorAnyDBField> = EmptyFields,
  const ERF extends Record<string, TailorAnyDBField> = EmptyFields,
>(
  params: DefineModuleParams<CatF, UnitF, CurF, ERF>,
) => {
  const uomCategory = createUoMCategoryType(params.uomCategory ?? {});
  const unit = createUnitType({ ...params.unit, uomCategoryType: uomCategory });
  const currency = createCurrencyType(params.currency ?? {});
  const exchangeRate = createExchangeRateType(params.exchangeRate ?? {});

  return {
    db: { uomCategory, unit, currency, exchangeRate },
    commands: {
      createCategory: createCategory<FieldsToInsertable<CatF>, FieldsToInsertable<UnitF>>(),
      createCurrency: createCurrency<FieldsToInsertable<CurF>>(),
      createUnit: createUnit<FieldsToInsertable<UnitF>>(),
      createExchangeRate: createExchangeRate<FieldsToInsertable<ERF>>(),
      activateCategory: activateCategory(),
      deactivateCategory: deactivateCategory(),
      activateUnit: activateUnit(),
      deactivateUnit: deactivateUnit(),
      setReferenceUnit: setReferenceUnit(),
      activateCurrency: activateCurrency(),
      deactivateCurrency: deactivateCurrency(),
      setBaseCurrency: setBaseCurrency(),
    },
    queries: {
      getUnit,
      getCurrency,
      getUoMCategory,
      getBaseCurrency,
      listUnitsByCategory,
      convertQuantity,
      convertAmount,
    },
  };
};
