import type { Address } from '@znet/magento'

/**
 * Masking applied to order/customer data unless the caller holds `orders:pii`.
 * Keeps enough to recognise a customer in conversation without exposing contact details.
 */
export function maskEmail(email: string | null | undefined): string | null {
  if (!email) return null
  const [local = '', domain = ''] = email.split('@')
  return `${local.slice(0, 1)}***@${domain}`
}

export function maskName(first?: string | null, last?: string | null): string | null {
  const parts = [first, last].filter((p): p is string => Boolean(p && p.trim())).map(p => `${p.trim()[0]!.toUpperCase()}.`)
  return parts.length ? parts.join(' ') : null
}

export function maskPhone(phone?: string | null): string | null {
  if (!phone) return null
  const digits = phone.replace(/\D/g, '')
  return digits.length > 3 ? `***${digits.slice(-3)}` : '***'
}

/** UK postcodes keep the outward code (district); others keep the first two characters. */
export function maskPostcode(pc?: string | null): string | null {
  if (!pc) return null
  const trimmed = pc.trim().toUpperCase()
  const uk = /^([A-Z]{1,2}\d[A-Z\d]?)\s*\d[A-Z]{2}$/.exec(trimmed)
  return uk ? `${uk[1]} ***` : `${trimmed.slice(0, 2)}***`
}

export function presentAddress(a: Address | undefined, pii: boolean) {
  if (!a) return null
  if (pii) {
    return {
      name: [a.firstname, a.lastname].filter(Boolean).join(' ') || null,
      company: a.company ?? null,
      street: a.street ?? [],
      city: a.city ?? null,
      region: a.region ?? null,
      postcode: a.postcode ?? null,
      country: a.country_id ?? null,
      telephone: a.telephone ?? null,
      email: a.email ?? null,
    }
  }
  return {
    name: maskName(a.firstname, a.lastname),
    city: a.city ?? null,
    region: a.region ?? null,
    postcode: maskPostcode(a.postcode),
    country: a.country_id ?? null,
    telephone: maskPhone(a.telephone),
  }
}

/** Redact likely-PII argument values before they go into the audit log. */
export function redactArgs(args: Record<string, unknown>): Record<string, unknown> {
  const out: Record<string, unknown> = {}
  for (const [k, v] of Object.entries(args)) {
    out[k] = typeof v === 'string' && /email/i.test(k) ? maskEmail(v) : v
  }
  return out
}
