import { NextRequest, NextResponse } from 'next/server' import { cookies } from 'next/headers' import pool from '@/lib/db' import { ALLOWED_PAYMENT_CURRENCIES, isAllowedCurrency } from '@/lib/payment-currencies' // POST /api/referral-points/redeem - Redeem referral points to crypto export async function POST(request: NextRequest) { const connection = await pool.getConnection() try { const cookieStore = await cookies() const buyerIdCookie = cookieStore.get('buyer_id')?.value if (!buyerIdCookie) { return NextResponse.json( { error: 'Authentication required' }, { status: 401 } ) } const buyer_id = parseInt(buyerIdCookie, 10) const body = await request.json() const { points, crypto_currency, wallet_address } = body // Validate required fields if (!points || !crypto_currency || !wallet_address) { return NextResponse.json( { error: 'Missing required fields: points, crypto_currency, wallet_address' }, { status: 400 } ) } const pointsToRedeem = parseFloat(points) const normalizedCryptoCurrency = crypto_currency.toLowerCase().trim() const normalizedWalletAddress = wallet_address.trim() // Validate points amount if (isNaN(pointsToRedeem) || pointsToRedeem <= 0) { return NextResponse.json( { error: 'Points must be a positive number' }, { status: 400 } ) } // Validate crypto currency - only USDT (SOL) is allowed for redemption if (normalizedCryptoCurrency !== 'usdtsol') { return NextResponse.json( { error: 'Only USDT (SOL) is supported for point redemption' }, { status: 400 } ) } // Basic wallet address validation (non-empty, reasonable length) if (normalizedWalletAddress.length < 10 || normalizedWalletAddress.length > 255) { return NextResponse.json( { error: 'Invalid wallet address format' }, { status: 400 } ) } await connection.beginTransaction() try { // Get buyer's current points balance const [buyerRows] = await connection.execute( 'SELECT referral_points FROM buyers WHERE id = ? FOR UPDATE', [buyer_id] ) const buyers = buyerRows as any[] if (buyers.length === 0) { await connection.rollback() return NextResponse.json( { error: 'Buyer not found' }, { status: 404 } ) } const currentPoints = parseFloat(buyers[0].referral_points) || 0 // Get redemption settings const [settingsRows] = await connection.execute( 'SELECT setting_key, setting_value FROM referral_settings' ) const settings = settingsRows as any[] const pointsToCryptoChf = parseFloat( settings.find(s => s.setting_key === 'points_to_crypto_chf')?.setting_value || '100' ) const minRedemptionPoints = parseFloat( settings.find(s => s.setting_key === 'min_redemption_points')?.setting_value || '1000' ) // Validate minimum redemption amount if (pointsToRedeem < minRedemptionPoints) { await connection.rollback() return NextResponse.json( { error: `Minimum redemption is ${minRedemptionPoints} points` }, { status: 400 } ) } // Validate user has enough points if (currentPoints < pointsToRedeem) { await connection.rollback() return NextResponse.json( { error: 'Insufficient points' }, { status: 400 } ) } // Calculate CHF value of points const chfValue = pointsToRedeem / pointsToCryptoChf // TODO: Get current crypto exchange rate // For now, we'll use a placeholder that would need to be replaced with actual exchange rate API // This should fetch the current rate from an exchange API (e.g., CoinGecko, Binance, etc.) const cryptoExchangeRate = await getCryptoExchangeRate(normalizedCryptoCurrency, 'chf') if (!cryptoExchangeRate) { await connection.rollback() return NextResponse.json( { error: 'Failed to fetch exchange rate. Please try again later.' }, { status: 500 } ) } // Calculate crypto amount const cryptoAmount = chfValue / cryptoExchangeRate // Deduct points from buyer's balance const newBalance = currentPoints - pointsToRedeem await connection.execute( 'UPDATE buyers SET referral_points = ? WHERE id = ?', [newBalance, buyer_id] ) // Create redemption record const [redemptionResult] = await connection.execute( `INSERT INTO point_redemptions (buyer_id, points, crypto_currency, wallet_address, crypto_amount, status) VALUES (?, ?, ?, ?, ?, 'pending')`, [buyer_id, pointsToRedeem, normalizedCryptoCurrency, normalizedWalletAddress, cryptoAmount] ) const redemptionId = (redemptionResult as any).insertId // Record transaction await connection.execute( `INSERT INTO referral_point_transactions (buyer_id, points, type, description) VALUES (?, ?, 'redeemed', ?)`, [ buyer_id, pointsToRedeem, `Points redeemed to ${normalizedCryptoCurrency.toUpperCase()} (Redemption #${redemptionId})` ] ) await connection.commit() return NextResponse.json({ success: true, redemption_id: redemptionId, points_redeemed: pointsToRedeem, crypto_currency: normalizedCryptoCurrency, crypto_amount: cryptoAmount, chf_value: chfValue, new_balance: newBalance, message: 'Redemption request created successfully. Your crypto will be sent within 24-48 hours.' }) } catch (error) { await connection.rollback() throw error } } catch (error: any) { console.error('Error redeeming points:', error) return NextResponse.json( { error: error.message || 'Failed to redeem points' }, { status: 500 } ) } finally { connection.release() } } // Helper function to get crypto exchange rate // TODO: Replace with actual exchange rate API integration async function getCryptoExchangeRate(crypto: string, fiat: string): Promise { try { // Placeholder: In production, this should call a real exchange rate API // Examples: CoinGecko, Binance, Coinbase, etc. // For now, return a mock rate (this should be replaced) // In production, you would do something like: // const response = await fetch(`https://api.coingecko.com/api/v3/simple/price?ids=${crypto}&vs_currencies=${fiat}`) // const data = await response.json() // return data[crypto][fiat] // Mock rates (CHF per 1 unit of crypto) - REPLACE WITH REAL API const mockRates: Record = { 'btc': 85000, 'eth': 2500, 'sol': 100, 'xrp': 0.6, 'bnbbsc': 300, 'usdterc20': 0.9, // Approximate CHF per USDT 'usdtsol': 0.9, // Approximate CHF per USDT on Solana } return mockRates[crypto.toLowerCase()] || null } catch (error) { console.error('Error fetching exchange rate:', error) return null } }