import { type EmptyFields, type FieldsToInsertable } from "@tailor-platform/erp-kit/core";
import { type TailorAnyDBField } from "@tailor-platform/sdk";
import type { defineModule as defineOrganizationModule } from "../organization";
import { createAccount } from "./command/createAccount.generated";
import { deactivateAccount } from "./command/deactivateAccount.generated";
import { reactivateAccount } from "./command/reactivateAccount.generated";
import { updateAccount } from "./command/updateAccount.generated";
import { createAccountType, type CreateAccountTypeParams } from "./db/account";
import { getAccount } from "./query/getAccount.generated";
import { listAccounts } from "./query/listAccounts.generated";

type OrganizationModule = ReturnType<typeof defineOrganizationModule>;
type OrganizationDB = OrganizationModule["db"];
export type OrganizationQueries = OrganizationModule["queries"];

export interface DefineModuleParams<AF extends Record<string, TailorAnyDBField>> {
  account?: CreateAccountTypeParams<AF>;
  organization: {
    db: { company: OrganizationDB["company"] };
    queries: Pick<OrganizationQueries, "getCompany">;
  };
}

/* @__NO_SIDE_EFFECTS__ */
export const defineModule = <const AF extends Record<string, TailorAnyDBField> = EmptyFields>(
  params: DefineModuleParams<AF>,
) => {
  const accountDb = createAccountType({
    ...params.account,
    companyType: params.organization.db.company,
  });

  return {
    db: {
      account: accountDb,
    },
    commands: {
      createAccount: createAccount<FieldsToInsertable<AF>>(params.organization.queries),
      updateAccount: updateAccount<FieldsToInsertable<AF>>(),
      deactivateAccount: deactivateAccount(),
      reactivateAccount: reactivateAccount(),
    },
    queries: {
      getAccount,
      listAccounts,
    },
  };
};
