import { NextResponse } from 'next/server'
import { prisma } from '@/lib/prisma'
import { safeHandler, requireAuth } from '@/lib/auth'

export const GET = safeHandler(async (req: Request) => {
  await requireAuth()

  const { searchParams } = new URL(req.url)
  const tab = searchParams.get('tab') || 'overview'
  const startDate = searchParams.get('startDate')
  const endDate = searchParams.get('endDate')

  const dateFilter = (field: string) => {
    const filter: any = {}
    if (startDate) filter.gte = new Date(startDate)
    if (endDate) filter.lte = new Date(endDate)
    return Object.keys(filter).length > 0 ? { [field]: filter } : {}
  }

  if (tab === 'overview') {
    const [totalQueries, totalBookings, revenueResult, pendingResult] = await Promise.all([
      prisma.query.count({ where: { ...dateFilter('createdAt') } }),
      prisma.booking.count({ where: { ...dateFilter('createdAt') } }),
      prisma.payment.aggregate({
        _sum: { amount: true },
        where: { status: 'COMPLETED', ...dateFilter('paymentDate') },
      }),
      prisma.payment.aggregate({
        _sum: { amount: true },
        where: { status: { in: ['PENDING', 'PARTIAL'] }, ...dateFilter('paymentDate') },
      }),
    ])

    const totalRevenue = Number(revenueResult._sum.amount || 0)
    const conversionRate = totalQueries > 0 ? ((totalBookings / totalQueries) * 100).toFixed(1) : '0.0'
    const totalPendingPayments = Number(pendingResult._sum.amount || 0)

    return NextResponse.json({
      totalQueries,
      totalBookings,
      totalRevenue,
      conversionRate,
      totalPendingPayments,
    })
  }

  if (tab === 'queries') {
    const [queriesByStage, queriesWithSource, allQueries] = await Promise.all([
      prisma.query.groupBy({
        by: ['stage'],
        _count: { stage: true },
        where: { ...dateFilter('createdAt') },
      }),
      prisma.query.findMany({
        where: { ...dateFilter('createdAt'), tripSourceId: { not: null } },
        select: { tripSource: { select: { type: true } } },
      }),
      prisma.query.findMany({
        where: { ...dateFilter('createdAt') },
        select: { createdAt: true },
        orderBy: { createdAt: 'asc' },
      }),
    ])

    // Group queries by source type
    const sourceMap: Record<string, number> = {}
    queriesWithSource.forEach(q => {
      if (q.tripSource) {
        const type = q.tripSource.type
        sourceMap[type] = (sourceMap[type] || 0) + 1
      }
    })
    const queriesBySource = Object.entries(sourceMap).map(([type, count]) => ({ type, count }))

    // Group queries by month (last 12 months)
    const monthMap: Record<string, number> = {}
    const now = new Date()
    for (let i = 11; i >= 0; i--) {
      const d = new Date(now.getFullYear(), now.getMonth() - i, 1)
      const key = `${d.getFullYear()}-${String(d.getMonth() + 1).padStart(2, '0')}`
      monthMap[key] = 0
    }
    allQueries.forEach(q => {
      const d = new Date(q.createdAt)
      const key = `${d.getFullYear()}-${String(d.getMonth() + 1).padStart(2, '0')}`
      if (key in monthMap) monthMap[key]++
    })
    const queriesByMonth = Object.entries(monthMap).map(([month, count]) => ({ month, count }))

    return NextResponse.json({ queriesByStage, queriesBySource, queriesByMonth })
  }

  if (tab === 'revenue') {
    const [payments, receivedResult, pendingResult] = await Promise.all([
      prisma.payment.findMany({
        where: { status: 'COMPLETED', ...dateFilter('paymentDate') },
        select: { paymentDate: true, amount: true },
        orderBy: { paymentDate: 'asc' },
      }),
      prisma.payment.aggregate({
        _sum: { amount: true },
        where: { status: 'COMPLETED', ...dateFilter('paymentDate') },
      }),
      prisma.payment.aggregate({
        _sum: { amount: true },
        where: { status: { in: ['PENDING', 'PARTIAL'] }, ...dateFilter('paymentDate') },
      }),
    ])

    // Group payments by month
    const monthMap: Record<string, number> = {}
    const now = new Date()
    for (let i = 11; i >= 0; i--) {
      const d = new Date(now.getFullYear(), now.getMonth() - i, 1)
      const key = `${d.getFullYear()}-${String(d.getMonth() + 1).padStart(2, '0')}`
      monthMap[key] = 0
    }
    payments.forEach(p => {
      const d = new Date(p.paymentDate)
      const key = `${d.getFullYear()}-${String(d.getMonth() + 1).padStart(2, '0')}`
      if (key in monthMap) monthMap[key] = monthMap[key] + Number(p.amount)
    })
    const paymentsByMonth = Object.entries(monthMap).map(([month, amount]) => ({ month, amount }))

    return NextResponse.json({
      paymentsByMonth,
      paymentsReceived: Number(receivedResult._sum.amount || 0),
      paymentsPending: Number(pendingResult._sum.amount || 0),
    })
  }

  if (tab === 'suppliers') {
    const [fundsBySupplierRaw, fundsByStatusRaw] = await Promise.all([
      prisma.fundAllocation.groupBy({
        by: ['supplierId'],
        _sum: { amount: true },
        where: { ...dateFilter('allocatedDate') },
      }),
      prisma.fundAllocation.groupBy({
        by: ['status'],
        _count: { status: true },
        _sum: { amount: true },
        where: { ...dateFilter('allocatedDate') },
      }),
    ])

    // Get supplier names
    const supplierIds = fundsBySupplierRaw.map(f => f.supplierId)
    const suppliers = supplierIds.length > 0
      ? await prisma.supplier.findMany({
          where: { id: { in: supplierIds } },
          select: { id: true, name: true },
        })
      : []
    const supplierNameMap: Record<string, string> = {}
    suppliers.forEach(s => { supplierNameMap[s.id] = s.name })

    const fundsBySupplier = fundsBySupplierRaw.map(f => ({
      supplierId: f.supplierId,
      supplierName: supplierNameMap[f.supplierId] || 'Unknown',
      amount: Number(f._sum.amount || 0),
    }))

    const fundsByStatus = fundsByStatusRaw.map(f => ({
      status: f.status,
      count: f._count.status,
      amount: Number(f._sum.amount || 0),
    }))

    return NextResponse.json({ fundsBySupplier, fundsByStatus })
  }

  return NextResponse.json({ message: 'Invalid tab' }, { status: 400 })
})
