// Pokemon API functionality using functional programming approach
// Base URL for the PokeAPI
const POKE_API_BASE = 'https://pokeapi.co/api/v2';
// Utility function to fetch data from the API
const fetchPokeData = async (endpoint) => {
try {
const response = await fetch(`${POKE_API_BASE}${endpoint}`);
if (!response.ok) throw new Error(`HTTP error! status: ${response.status}`);
return await response.json();
} catch (error) {
console.error('Error fetching Pokemon data:', error);
throw error;
}
};
// Function to get Pokemon basic info
const getPokemonInfo = async (pokemonName) => {
try {
const data = await fetchPokeData(`/pokemon/${pokemonName.toLowerCase()}`);
return {
name: data.name,
id: data.id,
types: data.types.map(type => type.type.name),
abilities: data.abilities.map(ability => ({
name: ability.ability.name,
isHidden: ability.is_hidden
})),
stats: data.stats.map(stat => ({
name: stat.stat.name,
value: stat.base_stat
})),
height: data.height / 10, // Convert to meters
weight: data.weight / 10, // Convert to kilograms
sprite: data.sprites.front_default
};
} catch (error) {
throw new Error(`Could not find Pokemon: ${pokemonName}`);
}
};
// Function to get ability details
const getAbilityInfo = async (abilityName) => {
try {
const data = await fetchPokeData(`/ability/${abilityName.toLowerCase()}`);
return {
name: data.name,
effect: data.effect_entries.find(e => e.language.name === 'en')?.effect || 'No effect description available.',
pokemon: data.pokemon.map(p => p.pokemon.name)
};
} catch (error) {
throw new Error(`Could not find ability: ${abilityName}`);
}
};
// Function to get move details
const getMoveInfo = async (moveName) => {
try {
const data = await fetchPokeData(`/move/${moveName.toLowerCase()}`);
return {
name: data.name,
type: data.type.name,
power: data.power,
accuracy: data.accuracy,
pp: data.pp,
effect: data.effect_entries.find(e => e.language.name === 'en')?.effect || 'No effect description available.'
};
} catch (error) {
throw new Error(`Could not find move: ${moveName}`);
}
};
const getEvolutionInfo = async (pokemonName) => {
const data = await fetchPokeData(`/pokemon-species/${pokemonName.toLowerCase()}`);
return data.evolution_chain;
};
// Function to format Pokemon info into a readable message
const formatPokemonInfo = (info) => {
const spriteImage = info.sprite ? `<img src="${info.sprite}" alt="${info.name} sprite" style="width: 100px; height: auto;" />` : '';
return `
🔍 Pokemon: ${info.name.toUpperCase()} (#${info.id})
📊 Types: ${info.types.join(', ')}
💪 Abilities: ${info.abilities.map(a => `${a.name}${a.isHidden ? ' (Hidden)' : ''}`).join(', ')}
📈 Stats:
${info.stats.map(s => ` ${s.name}: ${s.value}`).join('\n')}
📏 Height: ${info.height}m
⚖️ Weight: ${info.weight}kg
${spriteImage}
`.trim();
};
// Function to format ability info into a readable message
const formatAbilityInfo = (info) => {
return `
🔰 Ability: ${info.name.toUpperCase()}
📝 Effect: ${info.effect}
✨ Pokemon with this ability: ${info.pokemon.join(', ')}
`.trim();
};
// Function to format move info into a readable message
const formatMoveInfo = (info) => {
return `
⚔️ Move: ${info.name.toUpperCase()}
🎯 Type: ${info.type}
💥 Power: ${info.power || 'N/A'}
🎲 Accuracy: ${info.accuracy || 'N/A'}
🔄 PP: ${info.pp}
📝 Effect: ${info.effect}
`.trim();
};
const formatEvolutionInfo = (info) => {
return `
🔗 Evolution Chain: ${info.name.toUpperCase()}
`.trim();
};
// Main handler for Pokemon commands
const handlePokemonCommand = async (args) => {
if (!args.length) {
return "Usage: /pokemon [pokemon|ability|move] [name]";
}
const [type, ...nameArgs] = args;
const name = nameArgs.join(' ').replace(/\s+/g, '-'); // Replace spaces with hyphens
if (!name) {
return "Please provide a name to search for.";
}
try {
switch (type.toLowerCase()) {
case 'pokemon':
const pokemonInfo = await getPokemonInfo(name);
return formatPokemonInfo(pokemonInfo);
case 'ability':
const abilityInfo = await getAbilityInfo(name);
return formatAbilityInfo(abilityInfo);
case 'move':
const moveInfo = await getMoveInfo(name);
return formatMoveInfo(moveInfo);
case 'evolution-chain':
const evolutionInfo = await getEvolutionInfo(name);
return formatEvolutionInfo(evolutionInfo);
default:
return "Invalid type. Use: pokemon, ability, or move.";
}
} catch (error) {
return `Error: ${error.message}`;
}
};
// Export the handler for use in main application
export { handlePokemonCommand };