import { db } from '@/lib/db'
import { NextRequest, NextResponse } from 'next/server'

export async function GET(request: NextRequest) {
  try {
    const { searchParams } = new URL(request.url)
    const areaId = searchParams.get('areaId')
    const fromDate = searchParams.get('fromDate')
    const toDate = searchParams.get('toDate')

    const where: Record<string, unknown> = {}
    if (areaId) where.id = areaId

    const areas = await db.area.findMany({
      where,
      include: {
        _count: {
          select: {
            users: { where: { status: 'ACTIVE' } },
            plans: { where: { isActive: true } },
          },
        },
        plans: {
          where: { isActive: true },
          include: {
            _count: {
              select: {
                subscriptions: { where: { status: 'ACTIVE' } },
              },
            },
          },
        },
      },
      orderBy: { name: 'asc' },
    })

    // Build area-wise report
    const report = await Promise.all(
      areas.map(async (area) => {
        const areaUserIds = await db.user.findMany({
          where: { areaId: area.id },
          select: { id: true },
        })
        const userIds = areaUserIds.map((u) => u.id)

        // Total users in area
        const totalUsers = await db.user.count({ where: { areaId: area.id } })
        const activeUsers = await db.user.count({ where: { areaId: area.id, status: 'ACTIVE' } })

        // Invoice stats for area
        const invoiceWhere: Record<string, unknown> = {
          userId: { in: userIds },
        }
        if (fromDate || toDate) {
          invoiceWhere.createdAt = {}
          if (fromDate) (invoiceWhere.createdAt as Record<string, unknown>).gte = new Date(fromDate)
          if (toDate) (invoiceWhere.createdAt as Record<string, unknown>).lte = new Date(toDate)
        }

        const invoiceStats = userIds.length > 0
          ? await db.invoice.aggregate({
              where: invoiceWhere,
              _sum: { totalAmount: true, paidAmount: true },
              _count: true,
            })
          : { _sum: { totalAmount: 0, paidAmount: 0 }, _count: 0 }

        // Active subscriptions in area
        const activeSubscriptions = area.plans.reduce(
          (sum, plan) => sum + plan._count.subscriptions,
          0
        )

        // Plan breakdown
        const planBreakdown = area.plans.map((plan) => ({
          planId: plan.id,
          planName: plan.name,
          price: plan.price,
          speed: `${plan.speedDown}/${plan.speedUp} Mbps`,
          activeSubscriptions: plan._count.subscriptions,
          monthlyRevenue: plan._count.subscriptions * plan.price,
        }))

        return {
          areaId: area.id,
          areaName: area.name,
          areaCode: area.code,
          totalUsers,
          activeUsers,
          activeSubscriptions,
          totalPlans: area._count.plans,
          totalBilled: invoiceStats._sum.totalAmount || 0,
          totalCollected: invoiceStats._sum.paidAmount || 0,
          totalDue: (invoiceStats._sum.totalAmount || 0) - (invoiceStats._sum.paidAmount || 0),
          totalInvoices: invoiceStats._count,
          planBreakdown,
        }
      })
    )

    // Grand totals
    const grandTotals = report.reduce(
      (totals, area) => ({
        totalUsers: totals.totalUsers + area.totalUsers,
        activeUsers: totals.activeUsers + area.activeUsers,
        activeSubscriptions: totals.activeSubscriptions + area.activeSubscriptions,
        totalBilled: totals.totalBilled + area.totalBilled,
        totalCollected: totals.totalCollected + area.totalCollected,
        totalDue: totals.totalDue + area.totalDue,
        totalInvoices: totals.totalInvoices + area.totalInvoices,
      }),
      { totalUsers: 0, activeUsers: 0, activeSubscriptions: 0, totalBilled: 0, totalCollected: 0, totalDue: 0, totalInvoices: 0 }
    )

    return NextResponse.json({
      success: true,
      data: {
        report,
        grandTotals,
      },
    })
  } catch (error: unknown) {
    const message = error instanceof Error ? error.message : 'Internal server error'
    return NextResponse.json(
      { success: false, error: message },
      { status: 500 }
    )
  }
}
