import { NextRequest } from "next/server";
import { prisma } from "@/server/db";
import { env, isProductionRuntime } from "@/server/env";
import { fail, ok } from "@/server/http";
import { requireUser } from "@/server/security/auth";
import { serializeWelcomePromotion, WELCOME_PROMO_TYPE } from "@/server/bonus/welcome";
import { ensureUserCryptoAddresses } from "@/server/crypto/custody";
import { formatNetwork, SUPPORTED_CRYPTO_ASSETS } from "@/server/crypto/assets";
import { getCryptoEurRate } from "@/server/crypto/rates";

export const dynamic = "force-dynamic";

export async function GET(request: NextRequest) {
  try {
    const { user } = await requireUser(request);
    const addresses = await ensureUserCryptoAddresses(user.id);
    const pendingWelcomeBonus = await prisma.userBonus.findFirst({
      where: {
        userId: user.id,
        status: "OFFERED",
        bonusAmount: { lte: 0 },
        promotion: {
          type: WELCOME_PROMO_TYPE,
          status: "ACTIVE",
          currency: "EUR"
        }
      },
      include: { promotion: true },
      orderBy: { createdAt: "asc" }
    });
    const rates = await Promise.all(
      SUPPORTED_CRYPTO_ASSETS.map(async (asset) => {
        try {
          const rate = await getCryptoEurRate(asset.asset);
          return [asset.asset, { rate: rate.rate.toString(), source: rate.source }] as const;
        } catch {
          return [asset.asset, null] as const;
        }
      })
    );
    const rateMap = Object.fromEntries(rates);
    const config = env();

    return ok({
      minDepositEur: "25.00",
      canSimulate: !isProductionRuntime(config) && config.CRYPTO_DEV_ALLOW_SIMULATION,
      welcomeBonus: pendingWelcomeBonus ? serializeWelcomePromotion(pendingWelcomeBonus.promotion) : null,
      assets: SUPPORTED_CRYPTO_ASSETS.map((asset) => {
        const address = addresses.find((item) => item.network === asset.network);
        return {
          ...asset,
          networkLabel: formatNetwork(asset.network),
          address: address?.address,
          rate: rateMap[asset.asset]
        };
      })
    });
  } catch (error) {
    return fail(error);
  }
}
