// Dedicated actual-vs-actual comparator for the Vue↔React parity gate.
// NOT the Figma-expected buildChecks — this compares two collectActual() flat
// objects (or two collectVisibleText() strings) directly, side to side.
// Reuses drift-compare-core's colour normalisation + numeric tolerance.
import { normalizeHex, colorToHex, closeEnough } from '../../visual-verify/lib/drift-compare-core'

const NUMERIC_FIELDS = new Set(['width', 'height'])
const COLOR_FIELDS = new Set(['color', 'backgroundColor', 'borderColor', 'textColor'])

function tokens(text: string): string[] {
  return text.split(' | ').map(t => t.trim()).filter(Boolean)
}

export function compareVisibleText(vue: string, react: string) {
  const v = new Set(tokens(vue))
  const r = new Set(tokens(react))
  return {
    vueOnly: [...v].filter(t => !r.has(t)),
    reactOnly: [...r].filter(t => !v.has(t)),
    shared: [...v].filter(t => r.has(t)),
  }
}

export function assertSlotTokensPresent(text: string, expected: string[]) {
  const have = new Set(tokens(text))
  return { missing: expected.filter(t => !have.has(t)) }
}

export function compareComputedStyle(vue: Record<string, unknown>, react: Record<string, unknown>) {
  const diffs: { field: string; vue: unknown; react: unknown }[] = []
  const fields = new Set([...Object.keys(vue), ...Object.keys(react)])
  for (const field of fields) {
    const a = vue[field]
    const b = react[field]
    if (a === undefined || b === undefined) continue
    if (NUMERIC_FIELDS.has(field)) {
      if (!closeEnough(Number(a), Number(b))) diffs.push({ field, vue: a, react: b })
    } else if (COLOR_FIELDS.has(field)) {
      const ah = normalizeHex(colorToHex(String(a)))
      const bh = normalizeHex(colorToHex(String(b)))
      if (ah !== bh) diffs.push({ field, vue: a, react: b })
    } else {
      if (String(a) !== String(b)) diffs.push({ field, vue: a, react: b })
    }
  }
  return diffs
}
