import React, { useState } from 'react'; import type { BonsaiAnalysis, ToolRecommendation } from '../types'; import { CheckCircleIcon, AlertTriangleIcon, SparklesIcon, ZapIcon, BookOpenIcon, ClipboardListIcon, ScissorsIcon, SunIcon, DropletIcon, ThermometerIcon, CalendarIcon, BonsaiIcon, LayersIcon, FlaskConicalIcon, GalleryVerticalEndIcon, WindIcon, SnowflakeIcon, SunriseIcon, LeafIcon, StethoscopeIcon, BugIcon, WrenchIcon, BookUserIcon, PaletteIcon, DownloadIcon } from './icons'; import Spinner from './Spinner'; import { generateBonsaiImage } from '../services/geminiService'; type Tab = 'Overview' | 'Care Plan' | 'Health and Pests' | 'Styling' | 'Fertilizer and Soil' | 'Seasonal Guide' | 'Diagnostics' | 'Pest Library' | 'Tools & Supplies' | 'Knowledge'; interface AnalysisDisplayProps { analysis: BonsaiAnalysis; onReset?: () => void; onSaveToDiary?: () => void; isReadonly?: boolean; treeImageBase64?: string; } const TABS: { name: Tab, icon: React.FC> }[] = [ { name: 'Overview', icon: CheckCircleIcon }, { name: 'Care Plan', icon: CalendarIcon }, { name: 'Diagnostics', icon: StethoscopeIcon }, { name: 'Health and Pests', icon: AlertTriangleIcon }, { name: 'Pest Library', icon: BugIcon }, { name: 'Styling', icon: ScissorsIcon }, { name: 'Fertilizer and Soil', icon: LayersIcon }, { name: 'Seasonal Guide', icon: LeafIcon }, { name: 'Tools & Supplies', icon: WrenchIcon }, { name: 'Knowledge', icon: BookOpenIcon }, ]; const InfoCard: React.FC<{ title: string; children: React.ReactNode; icon: React.ReactNode; className?: string }> = ({ title, children, icon, className = '' }) => (
{icon}

{title}

{children}
); const HealthGauge: React.FC<{ score: number }> = ({ score }) => { const circumference = 2 * Math.PI * 52; const offset = circumference - (score / 100) * circumference; const color = score > 80 ? 'text-green-600' : score > 50 ? 'text-yellow-500' : 'text-red-600'; return (
{score}
); }; const TabButton: React.FC<{ name: Tab, icon: React.ReactNode, isActive: boolean, onClick: () => void }> = ({ name, icon, isActive, onClick }) => ( ); const PotVisualizerModal: React.FC<{ isOpen: boolean; onClose: () => void; analysis: BonsaiAnalysis; }> = ({ isOpen, onClose, analysis }) => { const [isLoading, setIsLoading] = useState(false); const [generatedImage, setGeneratedImage] = useState(null); const [error, setError] = useState(''); const [promptUsed, setPromptUsed] = useState(''); const potStyles = [ "A shallow, rectangular, unglazed, dark brown ceramic pot.", "A round, blue-glazed ceramic pot with a soft patina.", "An oval, cream-colored pot with delicate feet.", "A modern, minimalist, square, grey concrete pot.", "A classic, hexagonal, deep red pot.", "A natural-looking pot carved from rock with rough texture." ]; const handleGenerate = async (potStyle: string) => { setIsLoading(true); setError(''); setGeneratedImage(null); const treeDescription = `A photorealistic image of a healthy ${analysis.species} bonsai tree. ${analysis.healthAssessment.observations.join(' ')}. The trunk is ${analysis.healthAssessment.trunkAndNebariHealth.toLowerCase()}.`; const fullPrompt = `${treeDescription} The tree is in ${potStyle}`; setPromptUsed(fullPrompt); const result = await generateBonsaiImage(fullPrompt); if (result) { setGeneratedImage(result); } else { setError("Sorry, the AI couldn't generate the image. Please try a different style."); } setIsLoading(false); }; if (!isOpen) return null; return (
e.stopPropagation()}>

AI Pot Visualizer

Choose a Pot Style:

{potStyles.map(style => ( ))}
{isLoading ? : generatedImage ? ( ) : error ?

{error}

:

Your generated image will appear here.

}
); }; const AnalysisDisplay: React.FC = ({ analysis, onReset, onSaveToDiary, isReadonly = false, treeImageBase64 }) => { const [activeTab, setActiveTab] = useState('Overview'); const [isPotVisualizerOpen, setPotVisualizerOpen] = useState(false); const { healthAssessment, careSchedule, pestAndDiseaseAlerts, stylingSuggestions, environmentalFactors, estimatedAge, species, wateringAnalysis, knowledgeNuggets, fertilizerRecommendations, soilRecipe, potSuggestion, seasonalGuide, diagnostics, pestLibrary, toolRecommendations } = analysis; const seasonIcons: { [key: string]: React.FC> } = { Spring: SunriseIcon, Summer: SunIcon, Autumn: WindIcon, Winter: SnowflakeIcon, }; const renderContent = () => { switch (activeTab) { case 'Overview': return (
} className="lg:col-span-1 flex flex-col items-center text-center">

Overall Health: {healthAssessment.overallHealth}

Species: {species}

Estimated Age: {estimatedAge}

} className="lg:col-span-2">
    {healthAssessment.observations.map((obs, i) =>
  • {obs}
  • )}
} className="lg:col-span-3 grid grid-cols-1 md:grid-cols-3 gap-4">
Light{environmentalFactors.idealLight}
Humidity{environmentalFactors.idealHumidity}
Temperature{environmentalFactors.temperatureRange}
); case 'Care Plan': return (
}>

Frequency: {wateringAnalysis.frequency}

Method: {wateringAnalysis.method}

Notes: {wateringAnalysis.notes}

4-Week Personalized Care Schedule

{careSchedule.sort((a,b) => a.week - b.week).map((item, i) => (

Week {item.week}

{item.task}

{item.details}

{item.toolsNeeded && item.toolsNeeded.length > 0 && (

Tools

{item.toolsNeeded.map(tool => {tool})}
)}
))}
); case 'Diagnostics': return ( }>
{diagnostics.map((diag, i) => (

{diag.issue}

{diag.confidence} Confidence

Symptoms to watch for: {diag.symptoms}

Solution/Prevention: {diag.solution}

))}
); case 'Health and Pests': return (
}> {pestAndDiseaseAlerts.length > 0 ? ( pestAndDiseaseAlerts.map((alert, i) => (

{alert.pestOrDisease}

{alert.severity}

Symptoms: {alert.symptoms}

Treatment: {alert.treatment}

)) ) :

No active threats detected. Check the 'Pest Library' tab for preventative knowledge on common threats in your area.

}
}>

Foliage: {healthAssessment.foliageHealth}

Trunk & Nebari: {healthAssessment.trunkAndNebariHealth}

Pot & Soil: {healthAssessment.potAndSoilHealth}

); case 'Pest Library': return ( }>

A reference for the most common threats to a {species} in your region.

{pestLibrary.map((pest, i) => (
{pest.name} ({pest.type}) Show Details Hide Details

{pest.description}

Symptoms:
    {pest.symptoms.map((s, idx) =>
  • {s}
  • )}
Organic Treatment:

{pest.treatment.organic}

Chemical Treatment:

{pest.treatment.chemical}

))}
); case 'Styling': return (
} className="lg:col-span-1"> {stylingSuggestions.length > 0 ? ( stylingSuggestions.map((suggestion, i) => (

{suggestion.technique} ({suggestion.area})

{suggestion.description}

)) ) :

No immediate styling is recommended. Focus on health first.

}
} className="lg:col-span-1">

Style: {potSuggestion.style}

Size: {potSuggestion.size}

Color Palette: {potSuggestion.colorPalette}

Rationale: {potSuggestion.rationale}

); case 'Fertilizer and Soil': return (
}> {fertilizerRecommendations.map(rec => (

{rec.phase}

Type: {rec.type}

Frequency: {rec.frequency}

Notes: {rec.notes}

))}
}>
{soilRecipe.components.map(comp => (
{comp.name} {comp.percentage}%

{comp.notes}

))}

Rationale: {soilRecipe.rationale}

); case 'Seasonal Guide': return (
{seasonalGuide.sort((a,b) => ['Spring', 'Summer', 'Autumn', 'Winter'].indexOf(a.season) - ['Spring', 'Summer', 'Autumn', 'Winter'].indexOf(b.season)).map(season => { const Icon = seasonIcons[season.season] || LeafIcon; return ( }>

{season.summary}

    {season.tasks.map(task => (
  • {task.task} {task.importance}
  • ))}
) })}
); case 'Tools & Supplies': const groupedTools = toolRecommendations.reduce((acc, tool) => { acc[tool.category] = acc[tool.category] || []; acc[tool.category].push(tool); return acc; }, {} as Record); return (
{Object.entries(groupedTools).map(([category, tools]) => ( }>
{tools.map(tool => (

{tool.name}

{tool.level}

{tool.description}

))}
))}
); case 'Knowledge': return ( }>
    {knowledgeNuggets.map((nugget, i) => (
  • {nugget}
  • ))}
); default: return null; } }; return (
setPotVisualizerOpen(false)} analysis={analysis} />

Your Bonsai Analysis is Ready

Master Yuki has assessed your {species}. Here is your report.

{TABS.map(({name, icon: Icon}) => ( } isActive={activeTab === name} onClick={() => setActiveTab(name)} /> ))}
{renderContent()}
{!isReadonly && (
{onSaveToDiary && ( )}
)}
); }; export default AnalysisDisplay;