import {
  db,
  type TailorAnyDBField,
  type TailorAnyDBType,
  unsafeAllowAllGqlPermission,
  unsafeAllowAllTypePermission,
} from "@tailor-platform/sdk";
import { account as accountStub, accountGroup as accountGroupStub } from "../lib/_db_deps";
import { trialBalance } from "./trialBalance";

export interface CreateTrialBalanceLineTypeParams<F extends Record<string, TailorAnyDBField>> {
  fields?: F;
  trialBalanceType?: TailorAnyDBType;
  accountType?: TailorAnyDBType;
  accountGroupType?: TailorAnyDBType;
}

export function createTrialBalanceLineType<const F extends Record<string, TailorAnyDBField>>(
  params: CreateTrialBalanceLineTypeParams<F>,
) {
  return db
    .type("TrialBalanceLine", {
      trialBalanceId: db
        .uuid()
        .relation({
          type: "n-1",
          toward: { type: params.trialBalanceType ?? trialBalance },
          backward: "trialBalanceLines",
        })
        .description("Foreign key to TrialBalance"),
      accountId: db
        .uuid()
        .relation({
          type: "n-1",
          toward: { type: params.accountType ?? accountStub },
          backward: "trialBalanceLines",
        })
        .description("Foreign key to Account"),
      accountGroupId: db
        .uuid({ optional: true })
        .relation({
          type: "n-1",
          toward: { type: params.accountGroupType ?? accountGroupStub },
          backward: "trialBalanceLines",
        })
        .description("Optional foreign key to AccountGroup for hierarchical aggregation"),
      accountCode: db.string().description("Denormalized account code for display and ordering"),
      accountName: db.string().description("Denormalized account name for display"),
      openingBalance: db.float().description("Opening balance for the period"),
      periodDebits: db.float().description("Total debits for the period"),
      periodCredits: db.float().description("Total credits for the period"),
      closingBalance: db
        .float()
        .description("Closing balance (computed: openingBalance + periodDebits - periodCredits)"),
      sortOrder: db.int().description("Sort order within the trial balance"),
      ...((params.fields ?? {}) as F),
      ...db.fields.timestamps(),
    })
    .permission(unsafeAllowAllTypePermission)
    .gqlPermission(unsafeAllowAllGqlPermission);
}

export const trialBalanceLine = createTrialBalanceLineType({});
