/**
 * GET /api/accounting/incoming-invoices/match-vendor?vat=&iban=&name=&email=
 *
 * Reuse-first vendor matching for the review card. Order of preference:
 *   1. a c_bpartner already REMEMBERED on the learned vendor profile (fingerprint),
 *   2. exact TaxID match, 3. exact EMail match, 4. name contains.
 * Returns a "remembered" match (if any) + a candidate list so the UI can default
 * to reuse and only offer "create new" when nothing matches.
 */
import { string } from 'alga-js'
import refreshTokenHelper from '../../../utils/refreshTokenHelper'
import errorHandlingHelper from '../../../utils/errorHandlingHelper'
import fetchHelper from '../../../utils/fetchHelper'
import { getInboxScope, buildInboxCtx } from '../../../utils/inbox/scope'
import { getVendorProfile } from '../../../utils/inbox/inboxDb'
import { fingerprintFromData } from '../../../utils/inbox/vendorProfile'

const slim = (r: any) => ({
  id: r.id,
  name: r.Name,
  taxId: r.TaxID || r.taxID || '',
  isVendor: r.IsVendor ?? r.isVendor ?? false,
  email: r.EMail || r.eMail || ''
})

const handleFunc = async (event: any, authToken: any = null) => {
  const token = authToken ?? await getTokenHelper(event)
  const organizationId = getCookie(event, 'logship_organization_id')
  const scope = getInboxScope(event)
  const q = getQuery(event)
  const vat = String(q.vat || '').trim()
  const iban = String(q.iban || '').trim()
  const name = String(q.name || '').trim()
  const email = String(q.email || '').trim()

  const out: any = { status: 200, remembered: null, candidates: [] }

  // 1. remembered profile binding
  const fp = fingerprintFromData({ seller: { name, vatId: vat }, paymentIban: iban } as any)
  if (fp) {
    try {
      const profile = await getVendorProfile(buildInboxCtx(event, token), fp)
      if (profile?.c_bpartner_id) {
        const r: any = await fetchHelper(event, `models/c_bpartner/${profile.c_bpartner_id}`, 'GET', token, null)
        if (r?.id) out.remembered = slim(r)
      }
    } catch {}
  }

  const seen = new Set<number>()
  const add = (records: any[]) => {
    for (const r of records || []) { if (r?.id && !seen.has(r.id)) { seen.add(r.id); out.candidates.push(slim(r)) } }
  }

  const orgFilter = `AD_Org_ID eq ${organizationId} AND IsVendor eq true`
  try {
    if (vat) {
      const r: any = await fetchHelper(event, `models/c_bpartner?$filter=${string.urlEncode(`${orgFilter} AND TaxID eq '${vat}'`)}`, 'GET', token, null)
      add(r?.records || [])
    }
    if (email && out.candidates.length === 0) {
      const r: any = await fetchHelper(event, `models/c_bpartner?$filter=${string.urlEncode(`${orgFilter} AND EMail eq '${email}'`)}`, 'GET', token, null)
      add(r?.records || [])
    }
    if (name && out.candidates.length < 5) {
      const safe = name.replace(/'/g, '').slice(0, 40)
      const r: any = await fetchHelper(event, `models/c_bpartner?$filter=${string.urlEncode(`${orgFilter} AND contains(Name,'${safe}')`)}`, 'GET', token, null)
      add(r?.records || [])
    }
  } catch (e) { /* fail-soft: return whatever matched */ }

  return out
}

export default defineEventHandler(async (event) => {
  let data: any = {}
  try {
    data = await handleFunc(event)
  } catch (err: any) {
    try {
      const authToken: any = await refreshTokenHelper(event)
      data = await handleFunc(event, authToken)
    } catch (error: any) {
      data = errorHandlingHelper(err?.data ?? err, error?.data ?? error)
    }
  }
  return data
})
