import crypto from "node:crypto";
import { NextRequest } from "next/server";
import { Prisma } from "@prisma/client";
import { ForbiddenError } from "@/server/errors";
import { env, isProductionRuntime } from "@/server/env";
import { fail, ok, parseJson } from "@/server/http";
import { requireUser } from "@/server/security/auth";
import { ensureUserCryptoAddresses } from "@/server/crypto/custody";
import { creditCryptoDeposit, simulateCryptoDepositSchema } from "@/server/crypto/payments";
import { getCryptoEurRate } from "@/server/crypto/rates";

export const dynamic = "force-dynamic";

export async function POST(request: NextRequest) {
  try {
    const config = env();

    if (isProductionRuntime(config) || !config.CRYPTO_DEV_ALLOW_SIMULATION) {
      throw new ForbiddenError("Simulation is only available in dev/staging");
    }

    const { user } = await requireUser(request);
    const input = await parseJson(request, simulateCryptoDepositSchema);
    await ensureUserCryptoAddresses(user.id);
    const rate = await getCryptoEurRate(input.asset);
    const cryptoAmount = new Prisma.Decimal(input.eurAmount).div(rate.rate);
    const deposit = await creditCryptoDeposit({
      userId: user.id,
      asset: input.asset,
      cryptoAmount,
      txHash: `dev-${input.asset.toLowerCase()}-${crypto.randomUUID()}`,
      fromAddress: "dev-simulator"
    });

    return ok({
      depositId: deposit.id,
      asset: deposit.asset,
      cryptoAmount: deposit.cryptoAmount.toString(),
      eurAmount: deposit.eurAmount?.toString(),
      status: deposit.status
    });
  } catch (error) {
    return fail(error);
  }
}
