/** * API Route: Find plants with similar growing environments * GET /api/environment/similar?plantId=xyz&minScore=70 */ import type { NextApiRequest, NextApiResponse } from 'next'; import { getBlockchain } from '../../../lib/blockchain/manager'; import { findSimilarEnvironments } from '../../../lib/environment/analysis'; export default async function handler( req: NextApiRequest, res: NextApiResponse ) { if (req.method !== 'GET') { return res.status(405).json({ error: 'Method not allowed' }); } try { const { plantId, minScore } = req.query; if (!plantId || typeof plantId !== 'string') { return res.status(400).json({ error: 'Missing plantId parameter' }); } const blockchain = getBlockchain(); const targetPlant = blockchain.getPlant(plantId); if (!targetPlant) { return res.status(404).json({ error: 'Plant not found' }); } if (!targetPlant.environment) { return res.status(400).json({ error: 'Plant has no environmental data', message: 'Add environmental information to find similar plants', }); } // Get all plants const allPlants = Array.from( new Set(blockchain.chain.map(block => block.plant.id)) ) .map(id => blockchain.getPlant(id)!) .filter(Boolean); const minScoreValue = minScore ? parseInt(minScore as string) : 70; const similarPlants = findSimilarEnvironments(targetPlant, allPlants, minScoreValue); res.status(200).json({ success: true, targetPlant: { id: targetPlant.id, commonName: targetPlant.commonName, scientificName: targetPlant.scientificName, }, similarCount: similarPlants.length, similar: similarPlants.map(({ plant, comparison }) => ({ plant: { id: plant.id, commonName: plant.commonName, scientificName: plant.scientificName, owner: plant.owner.name, location: plant.location.city || plant.location.country, }, similarityScore: comparison.score, similarities: comparison.similarities, differences: comparison.differences, })), }); } catch (error: any) { console.error('Error finding similar environments:', error); res.status(500).json({ error: error.message || 'Internal server error' }); } }