/**
 * Reduce a genotype to per-locus PHENOTYPE TOKENS — the expressed effect at
 * each locus, collapsing genotypes that look identical (e.g. AA and Aa both
 * express agouti -> token "A"). The Farbschlag catalog matches on these tokens.
 *
 * Tokens per locus:
 *   A  : "A" (agouti, dominant present) | "a" (non-agouti, aa)
 *   C  : "C" (full colour) | "cchm" (marked colourpoint) | "ch" (himalayan)   [by dominant allele]
 *   D  : "D" | "d"
 *   E  : "E" (full) | "ef" (Schimmel/roan) | "e" (Fox)                         [by dominant allele]
 *   G  : "G" | "g"
 *   P  : "P" (black-eyed) | "p" (red-eyed)
 *   Sp : "Sp" (checkered) | "sp"
 *   Re : "Re" (rex) | "re"
 */
import { dominantAllele, LOCUS_ORDER, type LocusKey } from './loci'
import type { Genotype } from './genotype'
import { WILDCARD } from './genotype'

export type PhenotypeTokens = Record<LocusKey, string>

/** Expressed (dominant) allele at a locus; throws on unresolved wildcards. */
export function expressedAllele(g: Genotype, locus: LocusKey): string {
  const [a, b] = g[locus]
  if (a === WILDCARD || b === WILDCARD) {
    throw new Error(`Cannot resolve phenotype for locus ${locus}: contains wildcard`)
  }
  return dominantAllele(locus, a, b)
}

export function phenotypeTokens(g: Genotype): PhenotypeTokens {
  const tokens = {} as PhenotypeTokens
  for (const locus of LOCUS_ORDER) tokens[locus] = expressedAllele(g, locus)
  return tokens
}
