import refreshTokenHelper from "../../../utils/refreshTokenHelper"
import getTokenHelper from "../../../utils/getTokenHelper"
import forceLogoutHelper from "../../../utils/forceLogoutHelper"
import errorHandlingHelper from "../../../utils/errorHandlingHelper"
import { parseCamtUploads } from "../../../utils/banking/camt052Parser"
import { planAccount, presentPlan, saveUpload } from "../../../utils/banking/bankFileImport"

// POST /api/accounting/bank-file-import/preview   (multipart, field `files`)
// Dry run of the manual CAMT.052/053 file import: parses the online-banking
// export (ZIP of XML pages or plain XML), splits it into one statement per
// booking day and compares every booking with what iDempiere already holds
// (duplicate key = AcctSvcrRef ↔ C_BankStatementLine.EftTrxID). Writes NOTHING
// to iDempiere — it only parks the parsed upload on disk and returns a `token`
// the import route works from.
const MAX_FILES = 40
const MAX_BYTES = 40 * 1024 * 1024

const handleFunc = async (event: any, parsed: any, authToken: any = null) => {
  const token = authToken ?? await getTokenHelper(event)
  const accounts = []
  for (const account of parsed.accounts) {
    accounts.push(presentPlan(await planAccount(event, token, account)))
  }
  return accounts
}

export default defineEventHandler(async (event) => {
  // Read the multipart body ONCE (a refresh-retry can't re-read it).
  const form = await readMultipartFormData(event)
  const uploads: { name: string; data: Uint8Array }[] = []
  let bytes = 0
  for (const part of (form || [])) {
    if (!['file', 'files'].includes(part.name || '') || !part.data?.length) continue
    const name = part.filename || 'upload'
    if (!/\.(zip|xml)$/i.test(name)) return { status: 415, message: `Nicht unterstützter Dateityp: ${name} (nur CAMT als .zip oder .xml)` }
    bytes += part.data.length
    uploads.push({ name, data: new Uint8Array(part.data) })
  }
  if (!uploads.length) return { status: 400, message: 'Keine Datei übermittelt' }
  if (uploads.length > MAX_FILES || bytes > MAX_BYTES) return { status: 413, message: 'Zu viele / zu große Dateien — bitte in mehreren Schritten hochladen' }

  const parsed = parseCamtUploads(uploads)
  if (!parsed.accounts.length) {
    return { status: 422, message: 'Keine Umsätze gefunden — ist das ein CAMT.052-Export?', errors: parsed.errors, files: parsed.files }
  }

  let accounts: any[] = []
  try {
    accounts = await handleFunc(event, parsed)
  } catch (err: any) {
    try {
      let authToken: any = await refreshTokenHelper(event)
      accounts = await handleFunc(event, parsed, authToken)
    } catch (error: any) {
      const data = errorHandlingHelper(err?.data ?? err, error?.data ?? error)
      forceLogoutHelper(event, data)
      return data
    }
  }

  const token = await saveUpload(parsed, uploads)
  return { status: 200, token, files: parsed.files, errors: parsed.errors, accounts }
})
