import { NextRequest, NextResponse } from 'next/server'
import { db } from '@/lib/db'
import { StatutVente, ModePaiement } from '@prisma/client'
import { getCurrentUserId, requireAuth } from '@/lib/auth-utils'

// Helper function to generate sale number
async function generateSaleNumber(): Promise<string> {
  const today = new Date()
  const year = today.getFullYear()
  const month = String(today.getMonth() + 1).padStart(2, '0')
  
  // Count sales for this month
  const salesThisMonth = await db.vente.count({
    where: {
      date: {
        gte: new Date(year, today.getMonth(), 1),
        lt: new Date(year, today.getMonth() + 1, 1)
      }
    }
  })
  
  const sequence = String(salesThisMonth + 1).padStart(4, '0')
  return `V${year}${month}${sequence}`
}

// GET /api/pos/sales - Get all sales with relations
export async function GET(request: NextRequest) {
  try {
    const sales = await db.vente.findMany({
      include: {
        client: true,
        employe: true,
        lignes: {
          include: {
            produit: true
          }
        },
        paiements: true
      },
      orderBy: {
        date: 'desc'
      },
      take: 50 // Limit to last 50 sales
    })

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

// POST /api/pos/sales - Create a new sale
export async function POST(request: NextRequest) {
  try {
    const authError = await requireAuth()
    if (authError) return authError

    const body = await request.json()
    const { 
      clientId, 
      lignes, 
      paiements, 
      remise, 
      montantHT, 
      montantTVA, 
      montantTTC,
      notes 
    } = body

    // Validate required fields
    if (!lignes || lignes.length === 0) {
      return NextResponse.json(
        { error: 'Sale must have at least one line' },
        { status: 400 }
      )
    }

    if (!paiements || paiements.length === 0) {
      return NextResponse.json(
        { error: 'Sale must have at least one payment' },
        { status: 400 }
      )
    }

    // Verify product availability
    for (const ligne of lignes) {
      const product = await db.produit.findUnique({
        where: { id: ligne.produitId }
      })

      if (!product) {
        return NextResponse.json(
          { error: `Product ${ligne.produitId} not found` },
          { status: 400 }
        )
      }

      if (product.stock < ligne.quantite) {
        return NextResponse.json(
          { error: `Insufficient stock for product ${product.designation}` },
          { status: 400 }
        )
      }
    }

    // Get current user
    const employeId = await getCurrentUserId()

    // Generate sale number
    const numero = await generateSaleNumber()

    // Create sale with transaction
    const sale = await db.$transaction(async (tx) => {
      // Create sale
      const vente = await tx.vente.create({
        data: {
          numero,
          clientId: clientId || null,
          statut: StatutVente.PAYEE,
          montantHT,
          montantTVA,
          montantTTC,
          remise: remise || 0,
          notes: notes || null,
          employeId: null // Can be updated with authentication
        }
      })

      // Create sale lines and update product stock
      for (const ligne of lignes) {
        await tx.ligneVente.create({
          data: {
            venteId: vente.id,
            produitId: ligne.produitId,
            quantite: ligne.quantite,
            prixUnitaireHT: ligne.prixUnitaireHT,
            prixUnitaireTTC: ligne.prixUnitaireTTC,
            remise: ligne.remise || 0,
            montantHT: ligne.montantHT,
            montantTTC: ligne.montantTTC
          }
        })

        // Update product stock
        await tx.produit.update({
          where: { id: ligne.produitId },
          data: {
            stock: {
              decrement: ligne.quantite
            }
          }
        })
      }

      // Create payments
      for (const paiement of paiements) {
        await tx.paiement.create({
          data: {
            venteId: vente.id,
            mode: paiement.mode as ModePaiement,
            montant: paiement.montant,
            reference: paiement.reference || null,
            notes: paiement.notes || null,
          employeId
          }
        })
      }

      return vente
    })

    // Fetch the complete sale with relations
    const completeSale = await db.vente.findUnique({
      where: { id: sale.id },
      include: {
        client: true,
        employe: true,
        lignes: {
          include: {
            produit: true
          }
        },
        paiements: true
      }
    })

    return NextResponse.json(completeSale, { status: 201 })
  } catch (error) {
    console.error('Error creating sale:', error)
    return NextResponse.json(
      { error: 'Failed to create sale' },
      { status: 500 }
    )
  }
}
