import { NextRequest, 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 startDate = searchParams.get('startDate')
  const endDate = searchParams.get('endDate')

  // Build date filter for queries
  const queryDateFilter: any = {}
  if (startDate) queryDateFilter.gte = new Date(startDate)
  if (endDate) queryDateFilter.lte = new Date(endDate)
  const hasDateFilter = startDate || endDate

  const queryWhere = hasDateFilter ? { createdAt: queryDateFilter } : {}
  const bookingWhere = hasDateFilter ? { createdAt: queryDateFilter } : {}
  const paymentWhere = hasDateFilter ? { createdAt: queryDateFilter } : {}

  // 12 months ago for monthly revenue
  const twelveMonthsAgo = new Date()
  twelveMonthsAgo.setMonth(twelveMonthsAgo.getMonth() - 12)
  twelveMonthsAgo.setDate(1)
  twelveMonthsAgo.setHours(0, 0, 0, 0)

  const [
    activeQueries,
    confirmedBookings,
    pendingPayments,
    totalDestinations,
    recentQueries,
    pipelineCounts,
    revenuePayments,
    allQueries,
    allBookings,
  ] = await Promise.all([
    prisma.query.count({ where: { ...queryWhere, stage: { in: ['NEW', 'IN_PROGRESS', 'QUOTED'] } } }),
    prisma.booking.count({ where: { ...bookingWhere, status: 'CONFIRMED' } }),
    prisma.payment.count({ where: { ...paymentWhere, status: 'PENDING' } }),
    prisma.destination.count({ where: { isActive: true } }),
    prisma.query.findMany({
      take: 5,
      orderBy: { createdAt: 'desc' },
      where: queryWhere,
      select: {
        id: true, queryNo: true, leadName: true, stage: true,
        adults: true, children: true, travelStartDate: true, createdAt: true,
      },
    }),
    prisma.query.groupBy({
      by: ['stage'],
      where: queryWhere,
      _count: { stage: true },
    }),
    // Monthly revenue: payments from last 12 months with COMPLETED or PARTIAL status
    prisma.payment.findMany({
      where: {
        paymentDate: { gte: twelveMonthsAgo },
        status: { in: ['COMPLETED', 'PARTIAL'] },
      },
      select: { paymentDate: true, amount: true },
    }),
    // Queries by source: all queries with tripSource type
    prisma.query.findMany({
      where: queryWhere,
      include: { tripSource: { select: { type: true } } },
    }),
    // Bookings by destination
    prisma.booking.findMany({
      where: bookingWhere,
      include: {
        query: {
          include: {
            destinations: {
              include: { destination: { select: { name: true } } },
            },
          },
        },
      },
    }),
  ])

  const pipelineData = pipelineCounts.map(p => ({ stage: p.stage, count: p._count.stage }))

  // Group monthly revenue by month
  const monthlyRevenueMap = new Map<string, number>()
  for (const p of revenuePayments) {
    const d = new Date(p.paymentDate)
    const key = `${d.toLocaleString('en-US', { month: 'short' })} ${d.getFullYear()}`
    monthlyRevenueMap.set(key, (monthlyRevenueMap.get(key) || 0) + Number(p.amount))
  }

  // Build last 12 months in order
  const monthlyRevenue: { month: string; amount: 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.toLocaleString('en-US', { month: 'short' })} ${d.getFullYear()}`
    monthlyRevenue.push({ month: key, amount: monthlyRevenueMap.get(key) || 0 })
  }

  // Group queries by source type
  const sourceMap = new Map<string, number>()
  for (const q of allQueries) {
    const type = q.tripSource?.type || 'DIRECT'
    sourceMap.set(type, (sourceMap.get(type) || 0) + 1)
  }
  const queriesBySource = Array.from(sourceMap.entries()).map(([source, count]) => ({ source, count }))

  // Group bookings by destination (top 10)
  const destMap = new Map<string, number>()
  for (const b of allBookings) {
    const destinations = b.query?.destinations || []
    for (const qd of destinations) {
      const name = qd.destination.name
      destMap.set(name, (destMap.get(name) || 0) + 1)
    }
  }
  const bookingsByDestination = Array.from(destMap.entries())
    .map(([destination, count]) => ({ destination, count }))
    .sort((a, b) => b.count - a.count)
    .slice(0, 10)

  return NextResponse.json({
    kpis: { activeQueries, confirmedBookings, pendingPayments, totalDestinations },
    recentQueries,
    pipelineData,
    monthlyRevenue,
    queriesBySource,
    bookingsByDestination,
  })
})
