import React from 'react' import { Box, Text, type Color } from '@anthropic/ink' import type { BuddyData, Creature, SpeciesId } from '../types' import { STAT_NAMES, STAT_LABELS } from '../types' import { getSpeciesData } from '../data/species' import { SPECIES_PERSONALITY } from '../data/names' import { calculateStats, getCreatureName, getTotalEV } from '../core/creature' import { getXpProgress } from '../core/experience' import { getEVSummary } from '../core/effort' import { getGenderSymbol } from '../core/gender' import { getStatColor } from './shared' import { getNextEvolution } from '../data/evolution' import { StatBar } from './StatBar' interface CompanionCardProps { creature: Creature buddyData: BuddyData spriteLines?: string[] } // ANSI color constants const CYAN: Color = 'ansi:cyan' const YELLOW: Color = 'ansi:yellow' const GREEN: Color = 'ansi:green' const BLUE: Color = 'ansi:blue' const RED: Color = 'ansi:red' const MAGENTA: Color = 'ansi:magenta' const WHITE: Color = 'ansi:whiteBright' const GRAY: Color = 'ansi:white' /** Type → display color mapping */ const TYPE_COLORS: Record = { grass: 'ansi:green', poison: 'ansi:magenta', fire: 'ansi:red', flying: 'ansi:cyan', water: 'ansi:blue', electric: 'ansi:yellow', normal: 'ansi:white', } /** * Redesigned companion card with Pokémon-style stats display. */ export function CompanionCard({ creature, buddyData, spriteLines }: CompanionCardProps) { const species = getSpeciesData(creature.speciesId) const stats = calculateStats(creature) const xp = getXpProgress(creature) const genderSymbol = getGenderSymbol(creature.gender) const name = getCreatureName(creature) const evSummary = getEVSummary(creature) const totalEV = getTotalEV(creature) const nextEvo = getNextEvolution(creature.speciesId) // Type badges const typeBadges = species.types.filter((t): t is string => Boolean(t)).map((t, i) => ( {i > 0 ? '/' : ''}{t.toUpperCase()} )) // Friendship color const friendshipColor: Color = creature.friendship > 200 ? GREEN : creature.friendship > 100 ? YELLOW : RED // Shiny badge const shinyBadge = creature.isShiny ? ★SHINY★ : null // Evolution hint const evoHint = nextEvo ? ( {getSpeciesData(nextEvo.to).names.zh ?? getSpeciesData(nextEvo.to).name} Lv.{nextEvo.minLevel} ) : null return ( {/* Header row */} {name} #{String(species.dexNumber).padStart(3, '0')} {shinyBadge} Lv.{creature.level} {/* Species + type + gender */} {species.names.zh ?? species.name} {typeBadges} {genderSymbol && {genderSymbol}} {/* Sprite */} {spriteLines ? ( spriteLines.map((line, i) => {line}) ) : ( [Loading sprite...] )} {/* Personality */} "{SPECIES_PERSONALITY[creature.speciesId] ?? species.personality}" {/* Stats section */} ─── Base Stats ─── {STAT_NAMES.map((stat) => ( ))} {/* XP progress */} XP {'█'.repeat(Math.round(xp.percentage / 10))} {'░'.repeat(10 - Math.round(xp.percentage / 10))} {xp.current}/{xp.needed} {/* EV + Friendship */} EV = 510 ? GREEN : GRAY}>{evSummary} ({totalEV}/510) {'█'.repeat(Math.round((creature.friendship / 255) * 10))} {'░'.repeat(10 - Math.round((creature.friendship / 255) * 10))} {creature.friendship}/255 {/* Evolution hint */} {evoHint && ( Next: {evoHint} )} ) }