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

export interface CreateJournalLineTypeParams<F extends Record<string, TailorAnyDBField>> {
  fields?: F;
  journalEntryType?: TailorAnyDBType;
  accountType?: TailorAnyDBType;
}

export function createJournalLineType<const F extends Record<string, TailorAnyDBField>>(
  params: CreateJournalLineTypeParams<F>,
) {
  return db
    .type("JournalLine", {
      journalEntryId: db
        .uuid()
        .relation({
          type: "n-1",
          toward: { type: params.journalEntryType ?? journalEntry },
          backward: "lines",
        })
        .description("Foreign key to JournalEntry"),
      accountId: db
        .uuid()
        .relation({
          type: "n-1",
          toward: { type: params.accountType ?? accountStub },
          backward: "journalLines",
        })
        .description("Foreign key to Account (coa-management)"),
      debitAmount: db
        .float({ optional: true })
        .description("Debit amount (mutually exclusive with creditAmount)"),
      creditAmount: db
        .float({ optional: true })
        .description("Credit amount (mutually exclusive with debitAmount)"),
      description: db.string({ optional: true }).description("Optional line-level description"),
      currencyCode: db
        .string({ optional: true })
        .description("Optional foreign currency code referencing Currency in primitives module"),
      exchangeRate: db
        .float({ optional: true })
        .description("Exchange rate to functional currency (defaults to 1.0)"),
      functionalDebitAmount: db
        .float({ optional: true })
        .description("Computed: debitAmount * exchangeRate"),
      functionalCreditAmount: db
        .float({ optional: true })
        .description("Computed: creditAmount * exchangeRate"),
      ...((params.fields ?? {}) as F),
      ...db.fields.timestamps(),
    })
    .permission(unsafeAllowAllTypePermission)
    .gqlPermission(unsafeAllowAllGqlPermission);
}

export const journalLine = createJournalLineType({});
