import { NextRequest, NextResponse } from "next/server"
import prisma from "@/lib/prisma"
import Papa from "papaparse"
import { matchBankRow } from "@/lib/matching"
import { resolveOrgId } from "@/lib/org"

export async function POST(request: NextRequest) {
  try {
    if (!prisma) {
      return NextResponse.json({ error: "Database not configured" }, { status: 503 })
    }
    const orgId = await resolveOrgId(request.headers.get("x-org-id"))
    if (!orgId) {
      return NextResponse.json({ error: "Organization not found" }, { status: 404 })
    }
    const formData = await request.formData()
    const file = formData.get("file") as File
    const mappingJson = formData.get("mapping") as string

    if (!file) {
      return NextResponse.json({ error: "No file uploaded" }, { status: 400 })
    }

    let mapping: Record<string, string> = {}
    try {
      mapping = mappingJson ? JSON.parse(mappingJson) : {}
    } catch {
      return NextResponse.json({ error: "Invalid column mapping JSON" }, { status: 400 })
    }
    const csvText = await file.text()
    const parsed = Papa.parse(csvText, { header: true, skipEmptyLines: true })

    if (parsed.errors.length > 0 && parsed.data.length === 0) {
      return NextResponse.json({ error: "CSV parse error", details: parsed.errors }, { status: 400 })
    }

    // Get all unmatched pledges for this org
    const openPledges = await prisma.pledge.findMany({
      where: {
        organizationId: orgId,
        status: { in: ["new", "initiated", "overdue"] },
      },
      select: { id: true, reference: true, amountPence: true },
    })

    const pledgeMap = new Map<string, { id: string; amountPence: number }>(
      openPledges.map((p: { id: string; reference: string; amountPence: number }) => [p.reference, { id: p.id, amountPence: p.amountPence }])
    )

    // Convert rows and match
    const rows = (parsed.data as Record<string, string>[]).map((raw) => ({
      date: raw[mapping.dateCol || "Date"] || "",
      description: raw[mapping.descriptionCol || "Description"] || "",
      amount: parseFloat(raw[mapping.creditCol || mapping.amountCol || "Amount"] || "0"),
      reference: raw[mapping.referenceCol || "Reference"] || "",
      raw,
    }))

    const results = rows
      .filter((r) => r.amount > 0) // only credits
      .map((r) => matchBankRow(r, pledgeMap))

    // Create import record
    const importRecord = await prisma.import.create({
      data: {
        organizationId: orgId,
        kind: "bank_statement",
        fileName: file.name,
        rowCount: rows.length,
        matchedCount: results.filter((r) => r.confidence === "exact").length,
        unmatchedCount: results.filter((r) => r.confidence === "none").length,
        mappingConfig: mapping,
        status: "completed",
        stats: {
          totalRows: rows.length,
          credits: rows.filter((r) => r.amount > 0).length,
          exactMatches: results.filter((r) => r.confidence === "exact").length,
          partialMatches: results.filter((r) => r.confidence === "partial").length,
          unmatched: results.filter((r) => r.confidence === "none").length,
        },
      },
    })

    // Auto-confirm exact matches
    const confirmed: string[] = []
    for (const result of results) {
      if (result.confidence === "exact" && result.pledgeId) {
        await prisma.$transaction([
          prisma.pledge.update({
            where: { id: result.pledgeId },
            data: { status: "paid", paidAt: new Date() },
          }),
          prisma.payment.create({
            data: {
              pledgeId: result.pledgeId,
              provider: "bank",
              amountPence: Math.round(result.matchedAmount * 100),
              status: "confirmed",
              matchedBy: "auto",
              receivedAt: new Date(result.bankRow.date) || new Date(),
              importId: importRecord.id,
            },
          }),
          // Skip remaining reminders
          prisma.reminder.updateMany({
            where: { pledgeId: result.pledgeId, status: "pending" },
            data: { status: "skipped" },
          }),
        ])
        confirmed.push(result.pledgeId)
      }
    }

    return NextResponse.json({
      importId: importRecord.id,
      summary: {
        totalRows: rows.length,
        credits: rows.filter((r) => r.amount > 0).length,
        exactMatches: results.filter((r) => r.confidence === "exact").length,
        partialMatches: results.filter((r) => r.confidence === "partial").length,
        unmatched: results.filter((r) => r.confidence === "none").length,
        autoConfirmed: confirmed.length,
      },
      matches: results.map((r) => ({
        ...r,
        autoConfirmed: r.pledgeId ? confirmed.includes(r.pledgeId) : false,
      })),
    })
  } catch (error) {
    console.error("Bank import error:", error)
    return NextResponse.json({ error: "Internal error" }, { status: 500 })
  }
}
