import {
  db,
  type TailorAnyDBField,
  type TailorAnyDBType,
  unsafeAllowAllGqlPermission,
  unsafeAllowAllTypePermission,
} from "@tailor-platform/sdk";
import { chartOfAccounts as chartOfAccountsStub, company as companyStub } from "../lib/_db_deps";
import { accountingPeriod } from "./accountingPeriod";

export const TRIAL_BALANCE_VARIANTS: [string, string] = ["PRE_CLOSE", "POST_CLOSE"];

export interface CreateTrialBalanceTypeParams<F extends Record<string, TailorAnyDBField>> {
  fields?: F;
  companyType?: TailorAnyDBType;
  accountingPeriodType?: TailorAnyDBType;
  chartOfAccountsType?: TailorAnyDBType;
}

export function createTrialBalanceType<const F extends Record<string, TailorAnyDBField>>(
  params: CreateTrialBalanceTypeParams<F>,
) {
  return db
    .type("TrialBalance", {
      companyId: db
        .uuid()
        .relation({
          type: "n-1",
          toward: { type: params.companyType ?? companyStub },
          backward: "trialBalances",
        })
        .description("Foreign key to Company"),
      accountingPeriodId: db
        .uuid()
        .relation({
          type: "n-1",
          toward: { type: params.accountingPeriodType ?? accountingPeriod },
          backward: "trialBalances",
        })
        .description("Foreign key to AccountingPeriod"),
      chartOfAccountsId: db
        .uuid()
        .relation({
          type: "n-1",
          toward: { type: params.chartOfAccountsType ?? chartOfAccountsStub },
          backward: "trialBalances",
        })
        .description("Foreign key to ChartOfAccounts"),
      variant: db
        .enum(TRIAL_BALANCE_VARIANTS)
        .description("Trial balance variant (PRE_CLOSE or POST_CLOSE)"),
      generatedAt: db.datetime().description("Timestamp when the trial balance was generated"),
      totalDebits: db.float().description("Sum of all debit balances across accounts"),
      totalCredits: db.float().description("Sum of all credit balances across accounts"),
      isBalanced: db.bool().description("Whether totalDebits equals totalCredits"),
      ...((params.fields ?? {}) as F),
      ...db.fields.timestamps(),
    })
    .permission(unsafeAllowAllTypePermission)
    .gqlPermission(unsafeAllowAllGqlPermission);
}

export const trialBalance = createTrialBalanceType({});
