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

export async function POST(request: NextRequest) {
  try {
    const body = await request.json()
    const { month, year, areaId, dryRun } = body

    const targetDate = new Date()
    if (year) targetDate.setFullYear(parseInt(year))
    if (month) targetDate.setMonth(parseInt(month) - 1)
    targetDate.setDate(1)
    targetDate.setHours(0, 0, 0, 0)

    // Find all active subscriptions that haven't had an invoice for the target month
    const startDate = new Date(targetDate.getFullYear(), targetDate.getMonth(), 1)
    const endDate = new Date(targetDate.getFullYear(), targetDate.getMonth() + 1, 0, 23, 59, 59, 999)

    const where: Record<string, unknown> = {
      status: 'ACTIVE',
    }
    if (areaId) {
      where.plan = { areaId }
    }

    const subscriptions = await db.subscription.findMany({
      where,
      include: {
        user: { select: { id: true, name: true, email: true, areaId: true } },
        plan: true,
        invoices: {
          where: {
            createdAt: { gte: startDate, lte: endDate },
          },
        },
      },
    })

    // Filter out subscriptions that already have an invoice for this month
    const subscriptionsToInvoice = subscriptions.filter((s) => s.invoices.length === 0)

    if (dryRun) {
      return NextResponse.json({
        success: true,
        data: {
          wouldGenerate: subscriptionsToInvoice.length,
          totalAmount: subscriptionsToInvoice.reduce((sum, s) => sum + s.plan.price, 0),
          subscriptions: subscriptionsToInvoice.map((s) => ({
            subscriptionId: s.id,
            userId: s.user.id,
            userName: s.user.name,
            planName: s.plan.name,
            amount: s.plan.price,
          })),
        },
        message: 'Dry run - no invoices were generated',
      })
    }

    // Generate invoice numbers
    const invoiceCount = await db.invoice.count()
    const baseInvoiceNum = `INV-${String(targetDate.getFullYear()).slice(2)}${String(targetDate.getMonth() + 1).padStart(2, '0')}`

    const invoices = []
    for (let i = 0; i < subscriptionsToInvoice.length; i++) {
      const sub = subscriptionsToInvoice[i]
      const invoiceNumber = `${baseInvoiceNum}-${String(invoiceCount + i + 1).padStart(4, '0')}`
      const dueDate = new Date(endDate)
      dueDate.setDate(dueDate.getDate() + 15) // 15 days after end of month

      const invoice = await db.invoice.create({
        data: {
          invoiceNumber,
          userId: sub.user.id,
          subscriptionId: sub.id,
          amount: sub.plan.price,
          tax: 0,
          discount: 0,
          lateFee: 0,
          totalAmount: sub.plan.price,
          dueDate,
          status: 'UNPAID',
        },
        include: {
          user: { select: { id: true, name: true, email: true } },
          subscription: { include: { plan: true } },
        },
      })

      invoices.push(invoice)
    }

    return NextResponse.json({
      success: true,
      data: {
        generatedCount: invoices.length,
        totalAmount: invoices.reduce((sum, inv) => sum + inv.totalAmount, 0),
        invoices,
      },
      message: `Successfully generated ${invoices.length} invoices`,
    })
  } catch (error: unknown) {
    const message = error instanceof Error ? error.message : 'Internal server error'
    return NextResponse.json(
      { success: false, error: message },
      { status: 500 }
    )
  }
}
