import { NextRequest, NextResponse } from 'next/server' import { withAdminAuth } from '@/lib/admin-middleware' import { connectDB } from '@/lib/mongodb' import { Billing } from '@/models/billing' import { Transaction } from '@/models/transaction' import { z } from 'zod' const BillingUpdateSchema = z.object({ payment_status: z.enum(['pending', 'completed', 'failed', 'refunded']).optional(), service_status: z.enum(['active', 'inactive', 'suspended', 'cancelled']).optional(), amount: z.number().min(0).optional(), notes: z.string().optional(), }) export async function GET(request: NextRequest) { return withAdminAuth(request, async (req, admin) => { try { await connectDB() const { searchParams } = new URL(request.url) const page = parseInt(searchParams.get('page') || '1') const limit = parseInt(searchParams.get('limit') || '20') const search = searchParams.get('search') || '' const serviceType = searchParams.get('serviceType') || '' const paymentStatus = searchParams.get('paymentStatus') || '' const dateFrom = searchParams.get('dateFrom') const dateTo = searchParams.get('dateTo') const skip = (page - 1) * limit // Build filter query const filter: any = {} if (search) { filter.$or = [ { user_email: { $regex: search, $options: 'i' } }, { silicon_id: { $regex: search, $options: 'i' } }, { service_name: { $regex: search, $options: 'i' } }, ] } if (serviceType && serviceType !== 'all') { filter.service_type = serviceType } if (paymentStatus && paymentStatus !== 'all') { filter.payment_status = paymentStatus } if (dateFrom || dateTo) { filter.created_at = {} if (dateFrom) filter.created_at.$gte = new Date(dateFrom) if (dateTo) filter.created_at.$lte = new Date(dateTo) } const [billings, totalBillings] = await Promise.all([ Billing.find(filter).sort({ created_at: -1 }).skip(skip).limit(limit), Billing.countDocuments(filter), ]) const totalPages = Math.ceil(totalBillings / limit) // Calculate summary statistics for current filter const summaryStats = await Billing.aggregate([ { $match: filter }, { $group: { _id: null, totalAmount: { $sum: '$amount' }, totalTax: { $sum: '$tax_amount' }, totalDiscount: { $sum: '$discount_applied' }, completedCount: { $sum: { $cond: [{ $eq: ['$payment_status', 'completed'] }, 1, 0] }, }, pendingCount: { $sum: { $cond: [{ $eq: ['$payment_status', 'pending'] }, 1, 0] }, }, failedCount: { $sum: { $cond: [{ $eq: ['$payment_status', 'failed'] }, 1, 0] }, }, }, }, ]) return NextResponse.json({ billings, pagination: { currentPage: page, totalPages, totalBillings, hasNext: page < totalPages, hasPrev: page > 1, }, summary: summaryStats[0] || { totalAmount: 0, totalTax: 0, totalDiscount: 0, completedCount: 0, pendingCount: 0, failedCount: 0, }, }) } catch (error) { console.error('Admin billing fetch error:', error) return NextResponse.json({ error: 'Failed to fetch billing data' }, { status: 500 }) } }) } export async function POST(request: NextRequest) { return withAdminAuth(request, async (req, admin) => { try { await connectDB() const body = await request.json() const { action, billingId, data } = body if (action === 'update') { const validatedData = BillingUpdateSchema.parse(data) const billing = await Billing.findByIdAndUpdate( billingId, { ...validatedData, updated_at: new Date(), }, { new: true, runValidators: true } ) if (!billing) { return NextResponse.json({ error: 'Billing record not found' }, { status: 404 }) } return NextResponse.json({ billing }) } if (action === 'refund') { const billing = await Billing.findById(billingId) if (!billing) { return NextResponse.json({ error: 'Billing record not found' }, { status: 404 }) } if (billing.payment_status !== 'paid') { return NextResponse.json({ error: 'Can only refund paid payments' }, { status: 400 }) } // Update billing status billing.payment_status = 'refunded' billing.status = 'cancelled' await billing.save() // Create refund transaction const refundTransaction = new Transaction({ userId: billing.user_id, type: 'credit', amount: billing.amount, description: `Refund for ${billing.service_name}`, status: 'completed', reference: `refund_${billing._id}`, metadata: { originalBillingId: billing._id, refundedBy: admin.id, refundReason: data.refundReason || 'Admin refund', }, }) await refundTransaction.save() return NextResponse.json({ billing, transaction: refundTransaction, message: 'Refund processed successfully', }) } return NextResponse.json({ error: 'Invalid action' }, { status: 400 }) } catch (error) { console.error('Admin billing action error:', error) return NextResponse.json({ error: 'Failed to perform billing action' }, { status: 500 }) } }) }