// Pick-code resolution shared by every picklist surface (the digital lists on
// /generate-shipments, /mobile/generate-shipments, /mobile/picklist,
// /integrations/picklist-desktop and the PDF in ~/utils/picklistPdf.ts): which
// product code the picker should match.
//
// Priority:
//   1. the merchant's C_BPartner.PickProductIdentifier (value|upc|sku|mpn|asin) —
//      arrives on each line as `pickIdentifier` from /api/processes/inouts/[id]
//   2. the product's own M_Product.PickListCode (val|sku|upc|mpn)
//   3. first filled of mpn -> sku -> upc -> val
// A configured code that is EMPTY on the product falls through to the next step,
// so the picker is never pointed at a blank field.

export const PICK_CODE_KEYS = ['val', 'sku', 'upc', 'mpn', 'asin']
export const PICK_CODE_FALLBACK = ['mpn', 'sku', 'upc', 'val']
export const PICK_CODE_LABELS: Record<string, string> = { val: 'Value', sku: 'SKU', upc: 'UPC', mpn: 'MPN', asin: 'ASIN' }

// Options of the partner-level setting (keys = the iDempiere list values).
export const PICK_IDENTIFIER_OPTIONS = [
  { id: 'value', Name: 'Value' },
  { id: 'upc', Name: 'UPC / EAN' },
  { id: 'sku', Name: 'SKU' },
  { id: 'mpn', Name: 'MPN' },
  { id: 'asin', Name: 'ASIN' },
]

// iDempiere list value ({ id, identifier } or bare string) -> 'value'|'upc'|'sku'|'mpn'|'asin'|''.
export const pickIdentifierListValue = (raw: any): string => {
  const code = (raw && typeof raw === 'object') ? (raw.id ?? raw.identifier ?? '') : (raw ?? '')
  const key = code.toString().trim().toLowerCase()
  return PICK_IDENTIFIER_OPTIONS.some(o => o.id === key) ? key : ''
}

export type PickCodeSource = 'partner' | 'product' | 'fallback'

export const getProductCodeValue = (product: any, key: string | null): string => {
  if (!product) return ''
  switch (key) {
    case 'val': return product.Value || ''
    case 'sku': return product.SKU || ''
    case 'upc': return product.UPC || ''
    case 'mpn': return product.mpn || product.MPN || ''
    case 'asin': return product.asin || product.ASIN || ''
  }
  return ''
}

// Partner list value ('value', as an iDempiere list object or a bare string) -> pick-code key ('val').
const partnerKeyToPickCode = (raw: any): string | null => {
  const code = (raw && typeof raw === 'object') ? (raw.id ?? raw.identifier ?? '') : (raw ?? '')
  const key = code.toString().trim().toLowerCase()
  if (key === 'value') return 'val'
  return PICK_CODE_KEYS.includes(key) ? key : null
}

export const resolvePickCode = (product: any, partnerKey: any = null): { key: string, source: PickCodeSource } | null => {
  if (!product) return null

  const fromPartner = partnerKeyToPickCode(partnerKey)
  if (fromPartner && getProductCodeValue(product, fromPartner)) return { key: fromPartner, source: 'partner' }

  const fromProduct = partnerKeyToPickCode(product.PickListCode ?? product.pickListCode ?? product.picklistcode)
  // Without a partner setting an explicit PickListCode wins even when empty (legacy behaviour).
  if (fromProduct && (!fromPartner || getProductCodeValue(product, fromProduct))) return { key: fromProduct, source: 'product' }

  for (const k of PICK_CODE_FALLBACK) {
    if (getProductCodeValue(product, k)) return { key: k, source: 'fallback' }
  }
  return { key: PICK_CODE_FALLBACK[0], source: 'fallback' }
}

export const resolvePrimaryPickCode = (product: any, partnerKey: any = null) => resolvePickCode(product, partnerKey)?.key ?? null

// All code rows for a digital picklist card, primary first. `isConfigured` = the primary
// comes from the partner setting (drawn larger). ASIN only shows when filled or primary.
export const getPickCodeRows = (product: any, partnerKey: any = null) => {
  const resolved = resolvePickCode(product, partnerKey)
  const primary = resolved?.key ?? null
  const order = primary
    ? [primary, ...PICK_CODE_KEYS.filter(k => k !== primary)]
    : PICK_CODE_KEYS.slice()
  return order
    .map(key => ({
      key,
      label: PICK_CODE_LABELS[key],
      value: getProductCodeValue(product, key),
      isPrimary: key === primary,
      isConfigured: key === primary && resolved?.source === 'partner',
    }))
    .filter(row => row.key !== 'asin' || row.isPrimary || row.value)
}

// Compact "primary code" label for preview lists / tables.
export const primaryCode = (product: any, partnerKey: any = null) => {
  const key = resolvePrimaryPickCode(product, partnerKey)
  return { label: (key && PICK_CODE_LABELS[key]) || 'Code', value: getProductCodeValue(product, key) || '-' }
}
