/**
 * POST /api/accounting/amazon-ads/upload  (multipart, field "files", PDFs)
 * Fallback source while the Ads API access is pending — and for invoices that
 * were downloaded manually anyway. Each PDF is parsed (parseInvoicePdf.ts) and
 * cached in the store together with the file, so the import can attach the
 * ORIGINAL Amazon document to the created iDempiere invoice.
 *
 * Two document families are accepted in the same drop: Sponsored-Ads invoices and
 * SELLER FEE invoices (Seller Central → Tax Document Library → Seller Invoices —
 * no Amazon API exists for those). The fee parser runs first: it gates on the
 * supplier/recipient block, which an Ads invoice does not have.
 */
import { parseAmazonAdsInvoicePdf } from '../../../utils/amazonAds/parseInvoicePdf'
import { parseAmazonSellerFeeInvoicePdf } from '../../../utils/amazonAds/parseSellerFeeInvoicePdf'
import { upsertInvoice, getInvoice, inboxBackendInfo } from '../../../utils/amazonAds/invoiceStore'
import { orgIdOf } from '../../../utils/amazonAds/routeShared'
import getTokenHelper from '../../../utils/getTokenHelper'
import refreshTokenHelper from '../../../utils/refreshTokenHelper'
import errorHandlingHelper from '../../../utils/errorHandlingHelper'

// Stored in the iDempiere table CUST_AmazonInvoiceInbox (PDF → Strapi) — see invoiceStore.ts;
// the local SQLite file is only the fallback when that table is not reachable.
const handle = async (event: any, files: any[], token: string) => {
  const organizationId = orgIdOf(event)
  const results: any[] = []
  for (const f of files) {
    const name = f.filename || 'invoice.pdf'
    try {
      if (!/\.pdf$/i.test(name) && !/pdf/i.test(f.type || '')) { results.push({ fileName: name, status: 415, message: 'Keine PDF-Datei' }); continue }
      const buf = Buffer.from(f.data)
      const inv = (await parseAmazonSellerFeeInvoicePdf(buf, name)) || (await parseAmazonAdsInvoicePdf(buf, name))
      if (!inv) { results.push({ fileName: name, status: 422, message: 'Keine Amazon-Ads- oder Amazon-Gebührenrechnung erkannt (Rechnungsnummer/Beträge nicht gefunden)' }); continue }
      const existing = await getInvoice(event, token, inv.invoiceNo)
      // keep the richer API payload if we already have it, but always store the PDF
      const toStore = existing?.invoice?.source === 'api' ? { ...existing.invoice, documentAvailable: true } : inv
      await upsertInvoice(event, token, organizationId, toStore, { pdf: buf, pdfName: name })
      results.push({ fileName: name, status: 200, kind: inv.kind || 'ads', isCreditNote: !!inv.isCreditNote, invoiceNo: inv.invoiceNo, invoiceDate: inv.invoiceDate, gross: inv.gross, currency: inv.currency, lines: inv.lines.length, alreadyKnown: !!existing })
    } catch (e: any) {
      const st = Number(e?.status || e?.statusCode || 0)
      if (st === 401 || st === 403) throw e   // expired token → refresh + retry the whole batch (upserts are idempotent)
      results.push({ fileName: name, status: 500, message: e?.data?.detail || e?.message || String(e) })
    }
  }
  return { status: 200, results, backend: inboxBackendInfo().backend }
}

export default defineEventHandler(async (event) => {
  // multipart is read ONCE — the token-refresh retry below must not read the body again
  const parts = await readMultipartFormData(event)
  const files = (parts || []).filter(p => p.filename && p.data?.length)
  if (!files.length) return { status: 400, message: 'Keine PDF-Dateien empfangen' }
  if (!orgIdOf(event)) return { status: 422, message: 'Keine Organisation im Login-Kontext — bitte erneut anmelden.' }
  try {
    return await handle(event, files, await getTokenHelper(event))
  } catch (err: any) {
    try { return await handle(event, files, await refreshTokenHelper(event)) }
    catch (error: any) { return errorHandlingHelper(err?.data ?? err, error?.data ?? error) }
  }
})
