import { NextRequest, NextResponse } from 'next/server'
import { db } from '@/lib/db'
import { startOfDay, endOfDay, startOfWeek, endOfWeek, startOfMonth, endOfMonth, startOfYear, endOfYear, format } from 'date-fns'

export async function GET(request: NextRequest) {
  try {
    const searchParams = request.nextUrl.searchParams
    const range = searchParams.get('range') || 'month'

    const now = new Date()
    let startDate: Date
    let endDate: Date
    let dateFormat: string

    switch (range) {
      case 'today':
        startDate = startOfDay(now)
        endDate = endOfDay(now)
        dateFormat = 'HH:mm'
        break
      case 'week':
        startDate = startOfWeek(now, { weekStartsOn: 1 })
        endDate = endOfWeek(now, { weekStartsOn: 1 })
        dateFormat = 'dd/MM'
        break
      case 'year':
        startDate = startOfYear(now)
        endDate = endOfYear(now)
        dateFormat = 'MMM'
        break
      case 'month':
      default:
        startDate = startOfMonth(now)
        endDate = endOfMonth(now)
        dateFormat = 'dd/MM'
        break
    }

    // Sales by date
    const salesByDate = await db.vente.findMany({
      where: {
        date: { gte: startDate, lte: endDate },
        statut: 'PAYEE'
      },
      select: {
        date: true,
        montantHT: true,
        montantTTC: true
      },
      orderBy: {
        date: 'asc'
      }
    })

    // Group sales by date
    const salesByDateGrouped = salesByDate.reduce((acc, sale) => {
      const dateKey = format(sale.date, dateFormat)
      const existing = acc.find((item) => item.date === dateKey)
      
      if (existing) {
        existing.sales += 1
        existing.revenue += sale.montantTTC
      } else {
        acc.push({
          date: dateKey,
          sales: 1,
          revenue: sale.montantTTC
        })
      }
      return acc
    }, [] as { date: string; sales: number; revenue: number }[])

    // Sales by category (via products)
    const salesByCategoryRaw = await db.ligneVente.groupBy({
      by: ['produitId'],
      where: {
        vente: {
          date: { gte: startDate, lte: endDate },
          statut: 'PAYEE'
        }
      },
      _sum: {
        quantite: true,
        montantTTC: true
      }
    })

    // Get product categories and group
    const salesByCategoryMap = new Map<string, { count: number; revenue: number }>()
    
    for (const item of salesByCategoryRaw) {
      const product = await db.produit.findUnique({
        where: { id: item.produitId },
        select: { categorie: true }
      })
      
      if (product) {
        const existing = salesByCategoryMap.get(product.categorie) || { count: 0, revenue: 0 }
        salesByCategoryMap.set(product.categorie, {
          count: existing.count + (item._sum.quantite || 0),
          revenue: existing.revenue + (item._sum.montantTTC || 0)
        })
      }
    }

    const salesByCategory = Array.from(salesByCategoryMap.entries()).map(([category, data]) => ({
      category,
      count: data.count,
      revenue: data.revenue
    }))

    // Sales by employee
    const salesByEmployeeRaw = await db.vente.groupBy({
      by: ['employeId'],
      where: {
        date: { gte: startDate, lte: endDate },
        statut: 'PAYEE',
        employeId: { not: null }
      },
      _count: true,
      _sum: {
        montantTTC: true
      }
    })

    const salesByEmployee = await Promise.all(
      salesByEmployeeRaw.map(async (item) => {
        const employee = await db.employe.findUnique({
          where: { id: item.employeId! },
          select: { nom: true, prenom: true }
        })
        return {
          employee: employee ? `${employee.prenom} ${employee.nom}` : 'Inconnu',
          sales: item._count,
          revenue: item._sum.montantTTC || 0
        }
      })
    )

    // Sales by payment method
    const salesByPaymentMethodRaw = await db.paiement.groupBy({
      by: ['mode'],
      where: {
        date: { gte: startDate, lte: endDate },
        vente: {
          statut: 'PAYEE'
        }
      },
      _count: true,
      _sum: {
        montant: true
      }
    })

    const paymentMethodLabels: Record<string, string> = {
      ESPECES: 'Espèces',
      CARTE: 'Carte bancaire',
      CHEQUE: 'Chèque',
      VIREMENT: 'Virement',
      BON_CAISSE: 'Bon de caisse'
    }

    const salesByPaymentMethod = salesByPaymentMethodRaw.map((item) => ({
      method: paymentMethodLabels[item.mode] || item.mode,
      count: item._count,
      amount: item._sum.montant || 0
    }))

    const salesData = {
      salesByDate: salesByDateGrouped,
      salesByCategory,
      salesByEmployee,
      salesByPaymentMethod
    }

    return NextResponse.json(salesData)
  } catch (error) {
    console.error('Error fetching sales data:', error)
    return NextResponse.json(
      { error: 'Failed to fetch sales data' },
      { status: 500 }
    )
  }
}
