/**
 * POST /api/telephony/match-contacts  { numbers: string[] }
 *
 * Resolves phone numbers (as they appear in the PBX CDR, e.g. "01743479603")
 * to ERP contacts via the Elasticsearch `ad_user` index (phone/phone2 are
 * keyword fields, so a regexp on the last digits tolerates the usual
 * "+49 174 …" / "0174 …" / "0174-…" spellings). Called ASYNCHRONOUSLY by the
 * dashboard card after it rendered — never on the critical path. Fail-soft:
 * numbers without a match (or an ES error) simply come back unmatched.
 */
import elasticHelper from '../../utils/elasticHelper'
import { isAdminVerified } from '../../utils/mobileReleases'

const digitsOf = (n: any) => String(n ?? '').replace(/\D+/g, '')
/** Regexp over a keyword phone field: the significant digits (last 8), any separators in between. */
const phoneRegexp = (digits: string) => {
  const tail = digits.slice(-8).split('').join('[ /().\\-]?')
  return `.*${tail}`
}

export default defineEventHandler(async (event) => {
  const token = await getTokenHelper(event)
  if (!token) return { status: 401, matches: {} }
  if (!(await isAdminVerified(event, token))) return { status: 403, matches: {} }
  const body: any = await readBody(event).catch(() => ({}))
  const numbers = [...new Set<string>((Array.isArray(body?.numbers) ? body.numbers : []).map((n: any) => String(n || '').trim()).filter((n: string) => digitsOf(n).length >= 6))].slice(0, 25)
  const matches: Record<string, { userId: number; name: string; partnerId: number | null; partnerName?: string; isLead?: boolean }> = {}
  await Promise.all(numbers.map(async (n) => {
    const d = digitsOf(n)
    try {
      const res: any = await elasticHelper('ad_user/_search', 'POST', {
        size: 3,
        _source: ['ad_user_id', 'name', 'c_bpartner_id', 'phone', 'phone2'],
        query: { bool: { filter: [{ term: { isactive: true } }], should: [{ regexp: { phone: phoneRegexp(d) } }, { regexp: { phone2: phoneRegexp(d) } }], minimum_should_match: 1 } }
      })
      const hits: any[] = res?.hits?.hits || []
      // Prefer an exact digit match over a suffix match.
      const pick = hits.find((h) => [h._source?.phone, h._source?.phone2].some((p) => digitsOf(p).endsWith(d.slice(-9)))) || hits[0]
      if (pick?._source?.ad_user_id) matches[n] = { userId: Number(pick._source.ad_user_id), name: String(pick._source.name || ''), partnerId: pick._source.c_bpartner_id ? Number(pick._source.c_bpartner_id) : null }
    } catch (err: any) {
      console.warn('[dial] contact match failed for', n, '-', err?.message || err)
    }
  }))
  // Enrich (fail-soft, still off the critical path): lead flag + partner name from
  // iDempiere so the card can offer "open as lead / user / partner" links.
  await Promise.all(Object.values(matches).map(async (m) => {
    try {
      const u: any = await fetchHelper(event, `models/ad_user/${m.userId}?$select=Name,IsSalesLead,IsVendorLead,C_BPartner_ID`, 'GET', token, null)
      m.isLead = u?.IsSalesLead === true || u?.IsVendorLead === true
      if (u?.C_BPartner_ID?.id) { m.partnerId = Number(u.C_BPartner_ID.id); m.partnerName = String(u.C_BPartner_ID.identifier || '') }
    } catch { /* keep the ES match as is */ }
  }))
  return { status: 200, matches }
})
