import { NextRequest, NextResponse } from "next/server"
import prisma from "@/lib/prisma"
import { createPledgeSchema } from "@/lib/validators"
import { generateReference } from "@/lib/reference"
import { calculateReminderSchedule } from "@/lib/reminders"

export async function POST(request: NextRequest) {
  try {
    const body = await request.json()

    if (!prisma) {
      return NextResponse.json({ error: "Database not configured" }, { status: 503 })
    }

    const parsed = createPledgeSchema.safeParse(body)
    if (!parsed.success) {
      return NextResponse.json(
        { error: "Invalid data", details: parsed.error.flatten() },
        { status: 400 }
      )
    }

    const { amountPence, rail, donorName, donorEmail, donorPhone, giftAid, eventId, qrSourceId } = parsed.data

    // Get event + org
    const event = await prisma.event.findUnique({
      where: { id: eventId },
      include: { organization: true },
    })

    if (!event) {
      return NextResponse.json({ error: "Event not found" }, { status: 404 })
    }

    const org = event.organization

    // Generate unique reference (retry on collision)
    let reference = ""
    let attempts = 0
    while (attempts < 10) {
      reference = generateReference(org.refPrefix || "PNPL", amountPence)
      const exists = await prisma.pledge.findUnique({ where: { reference } })
      if (!exists) break
      attempts++
    }
    if (attempts >= 10) {
      return NextResponse.json({ error: "Could not generate unique reference" }, { status: 500 })
    }

    // Create pledge + payment instruction + reminder schedule in transaction
    // eslint-disable-next-line @typescript-eslint/no-explicit-any
    const pledge = await prisma.$transaction(async (tx: any) => {
      const p = await tx.pledge.create({
        data: {
          reference,
          amountPence,
          currency: "GBP",
          rail,
          status: "new",
          donorName: donorName || null,
          donorEmail: donorEmail || null,
          donorPhone: donorPhone || null,
          giftAid,
          eventId,
          qrSourceId: qrSourceId || null,
          organizationId: org.id,
        },
      })

      // Create payment instruction for bank transfers
      if (rail === "bank" && org.bankSortCode && org.bankAccountNo) {
        await tx.paymentInstruction.create({
          data: {
            pledgeId: p.id,
            bankReference: reference,
            bankDetails: {
              bankName: org.bankName || "",
              sortCode: org.bankSortCode,
              accountNo: org.bankAccountNo,
              accountName: org.bankAccountName || org.name,
            },
          },
        })
      }

      // Create reminder schedule
      const schedule = calculateReminderSchedule(new Date())
      await tx.reminder.createMany({
        data: schedule.map((s) => ({
          pledgeId: p.id,
          step: s.step,
          channel: s.channel,
          scheduledAt: s.scheduledAt,
          status: "pending",
          payload: { templateKey: s.templateKey, subject: s.subject },
        })),
      })

      // Track analytics
      await tx.analyticsEvent.create({
        data: {
          eventType: "pledge_completed",
          pledgeId: p.id,
          eventId,
          qrSourceId: qrSourceId || null,
          metadata: { amountPence, rail },
        },
      })

      return p
    })

    // Build response
    const response: Record<string, unknown> = {
      id: pledge.id,
      reference: pledge.reference,
    }

    if (rail === "bank" && org.bankSortCode) {
      response.bankDetails = {
        bankName: org.bankName || "",
        sortCode: org.bankSortCode,
        accountNo: org.bankAccountNo || "",
        accountName: org.bankAccountName || org.name,
      }
    }

    return NextResponse.json(response, { status: 201 })
  } catch (error) {
    console.error("Pledge creation error:", error)
    return NextResponse.json({ error: "Internal error" }, { status: 500 })
  }
}
