import { LedgerDirection, LedgerEntryType, Prisma, Role, WalletAccountType } from "@prisma/client";
import { z } from "zod";
import { prisma } from "@/server/db";
import { writeAuditLog } from "@/server/audit";
import { postLedgerEntry, ensureWallet } from "@/server/wallet/ledger";

export const walletAdjustmentSchema = z.object({
  userId: z.string().uuid(),
  currency: z.string().min(3).max(8),
  accountType: z.nativeEnum(WalletAccountType).default(WalletAccountType.AVAILABLE),
  direction: z.nativeEnum(LedgerDirection),
  amount: z.coerce.number().positive().max(1000000),
  reason: z.string().min(8).max(500),
  metadata: z.record(z.unknown()).optional()
});

export async function adjustWalletBalance(actor: { id: string; roles: Role[] }, input: z.infer<typeof walletAdjustmentSchema>) {
  return prisma.$transaction(async (tx) => {
    const wallet = await ensureWallet(input.userId, input.currency, tx);
    const entry = await postLedgerEntry(tx, {
      walletId: wallet.id,
      accountType: input.accountType,
      direction: input.direction,
      type: LedgerEntryType.ADJUSTMENT,
      amount: input.amount,
      currency: input.currency,
      referenceType: "admin_adjustment",
      idempotencyKey: `admin:${crypto.randomUUID()}`,
      reason: input.reason,
      metadata: input.metadata as Prisma.InputJsonValue
    });

    await writeAuditLog(
      {
        actorUserId: actor.id,
        action: "admin.wallet.adjust",
        entityType: "Wallet",
        entityId: wallet.id,
        after: {
          ledgerEntryId: entry.id,
          direction: input.direction,
          accountType: input.accountType,
          amount: String(input.amount),
          reason: input.reason
        }
      },
      tx
    );

    return entry;
  });
}
