import { Prisma } from "@prisma/client";

export const AGENT_BALANCE_TYPES = {
  PROFIT_SHARE: "PROFIT_SHARE",
  CAPITAL: "CAPITAL"
} as const;

export const AGENT_BALANCE_DIRECTIONS = {
  IN: "IN",
  OUT: "OUT"
} as const;

export const AGENT_BALANCE_SOURCES = {
  OPENING_BALANCE: "OPENING_BALANCE",
  MANUAL_ADJUSTMENT: "MANUAL_ADJUSTMENT",
  CONSIGNMENT_COMMISSION: "CONSIGNMENT_COMMISSION",
  REGULAR_SALE_COMMISSION: "REGULAR_SALE_COMMISSION",
  JIT_SALE_COMMISSION: "JIT_SALE_COMMISSION",
  OFFICE_BUYOUT_COMMISSION: "OFFICE_BUYOUT_COMMISSION",
  FUND_REQUEST_PROFIT_SHARE: "FUND_REQUEST_PROFIT_SHARE",
  FUND_REQUEST_CAPITAL: "FUND_REQUEST_CAPITAL"
} as const;

export type AgentBalanceType =
  (typeof AGENT_BALANCE_TYPES)[keyof typeof AGENT_BALANCE_TYPES];

export type AgentBalanceDirection =
  (typeof AGENT_BALANCE_DIRECTIONS)[keyof typeof AGENT_BALANCE_DIRECTIONS];

export type AgentBalanceSource =
  (typeof AGENT_BALANCE_SOURCES)[keyof typeof AGENT_BALANCE_SOURCES];

export function roundBalanceAmount(value: number) {
  return Number(value.toFixed(2));
}

export async function createAgentBalanceMutation(
  tx: Prisma.TransactionClient,
  input: {
    agentId: bigint;
    balanceType: AgentBalanceType;
    direction: AgentBalanceDirection;
    source: AgentBalanceSource;
    amount: number;
    balanceAfter: number;
    effectiveDate?: Date | null;
    referenceType?: string | null;
    referenceId?: string | null;
    referenceNo?: string | null;
    notes?: string | null;
    metadata?: Prisma.InputJsonValue | null;
  }
) {
  await tx.agentBalanceMutation.create({
    data: {
      agentId: input.agentId,
      balanceType: input.balanceType,
      direction: input.direction,
      source: input.source,
      amount: new Prisma.Decimal(roundBalanceAmount(input.amount)),
      balanceAfter: new Prisma.Decimal(roundBalanceAmount(input.balanceAfter)),
      effectiveDate: input.effectiveDate ?? null,
      referenceType: input.referenceType ?? null,
      referenceId: input.referenceId ?? null,
      referenceNo: input.referenceNo ?? null,
      notes: input.notes ?? null,
      metadata: input.metadata ?? Prisma.JsonNull
    }
  });
}
