"use client"
import { useState, useEffect, useCallback } from "react"
import { Utensils, Plus, Clock, Flame } from "lucide-react"
import { Button } from "@/components/ui/button"
import { Progress } from "@/components/ui/progress"
import { cn } from "@/lib/utils"
import { useFitnessData } from "@/hooks/useFitnessData"
interface Meal {
id: string
type: string
name: string
calories: number
time: string
completed: boolean
protein: number
carbs: number
fat: number
}
interface MealTrackerProps {
loggedNutrition?: Array<{
id: string
foodItem: string
mealType: string
calories: number
protein: number
carbs: number
fat: number
timestamp: string
}>
}
export function MealTracker({ loggedNutrition = [] }: MealTrackerProps) {
const { logNewEntry, refreshContext } = useFitnessData()
// Helper function to check if a meal is completed based on logged nutrition
const isMealCompleted = useCallback((mealName: string) => {
return loggedNutrition.some(nutrition =>
nutrition.foodItem.toLowerCase().includes(mealName.toLowerCase()) ||
mealName.toLowerCase().includes(nutrition.foodItem.toLowerCase())
)
}, [loggedNutrition])
// Helper function to get actual calories from logged nutrition
const getActualCalories = useCallback((mealName: string) => {
const loggedMeal = loggedNutrition.find(nutrition =>
nutrition.foodItem.toLowerCase().includes(mealName.toLowerCase()) ||
mealName.toLowerCase().includes(nutrition.foodItem.toLowerCase())
)
return loggedMeal?.calories || 0
}, [loggedNutrition])
const [meals, setMeals] = useState<Meal[]>([
{
id: "1",
type: "Breakfast",
name: "Oatmeal with berries & almonds",
calories: 320,
time: "8:00 AM",
completed: isMealCompleted("Oatmeal with berries & almonds"),
protein: 12,
carbs: 45,
fat: 8,
},
{
id: "2",
type: "Lunch",
name: "Grilled chicken Caesar salad",
calories: 450,
time: "12:30 PM",
completed: isMealCompleted("Grilled chicken Caesar salad"),
protein: 35,
carbs: 15,
fat: 22,
},
{
id: "3",
type: "Snack",
name: "Greek yogurt with honey",
calories: 150,
time: "3:00 PM",
completed: isMealCompleted("Greek yogurt with honey"),
protein: 15,
carbs: 18,
fat: 3,
},
{
id: "4",
type: "Dinner",
name: "Baked salmon with quinoa & broccoli",
calories: 520,
time: "7:00 PM",
completed: isMealCompleted("Baked salmon with quinoa & broccoli"),
protein: 40,
carbs: 35,
fat: 18,
},
])
// Update meal completion status when loggedNutrition changes
useEffect(() => {
setMeals(prevMeals =>
prevMeals.map(meal => ({
...meal,
completed: isMealCompleted(meal.name)
}))
)
}, [isMealCompleted])
const toggleMeal = async (id: string) => {
const meal = meals.find(m => m.id === id)
if (!meal) return
const newCompletedState = !meal.completed
// Check if this meal is already logged via + button
const isAlreadyLogged = isMealCompleted(meal.name)
if (isAlreadyLogged && !newCompletedState) {
// If trying to uncheck a logged meal, just return (keep it completed)
return
}
// Update local state immediately for UI responsiveness
setMeals(
meals.map((m) => (m.id === id ? { ...m, completed: newCompletedState } : m)),
)
// If completing the meal and it's not already logged, log it to the API
if (newCompletedState && !isAlreadyLogged) {
try {
const result = await logNewEntry('nutrition', {
nutrition: {
mealType: meal.type.toLowerCase() as 'breakfast' | 'lunch' | 'dinner' | 'snack',
foodItem: meal.name,
calories: meal.calories,
protein: meal.protein,
carbs: meal.carbs,
fat: meal.fat,
}
})
if (result.success) {
console.log(`✅ Logged completed meal: ${meal.name} (${meal.calories} cal)`)
} else {
console.error('❌ Failed to log meal:', result.error)
}
} catch (error) {
console.error('Failed to log meal completion:', error)
// Revert the state if API call failed
setMeals(
meals.map((m) => (m.id === id ? { ...m, completed: !newCompletedState } : m)),
)
}
}
}
const completedMeals = meals.filter((meal) => meal.completed)
// Calculate totals using actual logged calories if available, otherwise plan calories
let totalCalories = 0
let totalProtein = 0
completedMeals.forEach(meal => {
const loggedCalories = getActualCalories(meal.name)
if (loggedCalories > 0) {
totalCalories += loggedCalories
// Estimate protein from logged calories (25% of calories / 4 cal per gram)
totalProtein += Math.round(loggedCalories * 0.25 / 4)
} else {
// Use plan values for manually completed meals
totalCalories += meal.calories
totalProtein += meal.protein
}
})
const progress = (completedMeals.length / meals.length) * 100
const targetCalories = 1440
const targetProtein = 120
return (
<div className="bg-white/80 backdrop-blur-sm rounded-3xl shadow-lg border border-white/20 p-6">
{/* Header */}
<div className="flex items-center justify-between mb-6">
<div className="flex items-center gap-3">
<div className="w-12 h-12 bg-gradient-to-br from-green-400 to-emerald-500 rounded-2xl flex items-center justify-center">
<Utensils className="w-6 h-6 text-white" />
</div>
<div>
<h3 className="text-lg font-bold text-slate-800">Today's Meals</h3>
<div className="flex items-center gap-2 mt-1">
<Progress value={progress} className="w-20 h-2" />
<span className="text-sm text-slate-600">{Math.round(progress)}%</span>
</div>
</div>
</div>
<Button size="sm" className="rounded-full bg-gradient-to-r from-green-400 to-emerald-500">
<Plus className="w-4 h-4" />
</Button>
</div>
{/* Meals List */}
<div className="space-y-3 mb-6">
{meals.map((meal) => (
<button
key={meal.id}
onClick={() => toggleMeal(meal.id)}
className={cn(
"w-full p-4 rounded-2xl border-2 transition-all duration-200 text-left group",
meal.completed
? "bg-gradient-to-r from-green-50 to-emerald-50 border-green-200 shadow-sm"
: "bg-gradient-to-r from-slate-50 to-gray-50 border-slate-200 hover:border-green-300 hover:shadow-md hover:scale-[1.01]",
)}
>
<div className="flex items-start justify-between">
<div className="flex items-start gap-3 flex-1">
<div
className={cn(
"w-4 h-4 rounded-full mt-0.5 transition-all duration-200 flex items-center justify-center",
meal.completed
? "bg-green-500 shadow-lg shadow-green-200"
: "bg-slate-300 group-hover:bg-green-400",
)}
>
{meal.completed && (
<svg className="w-2.5 h-2.5 text-white" fill="currentColor" viewBox="0 0 20 20">
<path
fillRule="evenodd"
d="M16.707 5.293a1 1 0 010 1.414l-8 8a1 1 0 01-1.414 0l-4-4a1 1 0 011.414-1.414L8 12.586l7.293-7.293a1 1 0 011.414 0z"
clipRule="evenodd"
/>
</svg>
)}
</div>
<div className="flex-1 min-w-0">
<div className="flex items-center gap-2 mb-1">
<span
className={cn(
"text-xs font-semibold px-2 py-1 rounded-full",
meal.completed
? "bg-green-100 text-green-700"
: "bg-slate-100 text-slate-600 group-hover:bg-green-100 group-hover:text-green-700",
)}
>
{meal.type.toUpperCase()}
</span>
<div className="flex items-center gap-1 text-xs text-slate-500">
<Clock className="w-3 h-3" />
{meal.time}
</div>
</div>
<p
className={cn(
"font-medium text-sm leading-relaxed mb-2",
meal.completed ? "text-green-800" : "text-slate-700",
)}
>
{meal.name}
</p>
<div className="flex items-center gap-4 text-xs">
<div className="flex items-center gap-1">
<Flame className="w-3 h-3 text-orange-500" />
<span className={meal.completed ? "text-green-600" : "text-slate-500"}>{meal.calories} cal</span>
</div>
<span className={meal.completed ? "text-green-600" : "text-slate-500"}>P: {meal.protein}g</span>
<span className={meal.completed ? "text-green-600" : "text-slate-500"}>C: {meal.carbs}g</span>
<span className={meal.completed ? "text-green-600" : "text-slate-500"}>F: {meal.fat}g</span>
</div>
</div>
</div>
</div>
</button>
))}
</div>
{/* Nutrition Summary */}
<div className="bg-gradient-to-r from-green-50 to-emerald-50 rounded-2xl p-4 border border-green-200/50">
<h4 className="font-semibold text-green-800 mb-3 text-sm flex items-center gap-2">
<Flame className="w-4 h-4" />
Daily Progress
</h4>
<div className="grid grid-cols-2 gap-4">
<div>
<div className="flex items-center justify-between mb-1">
<span className="text-xs text-green-600">Calories</span>
<span className="text-xs text-green-600">
{totalCalories}/{targetCalories}
</span>
</div>
<div className="w-full bg-green-200 rounded-full h-2">
<div
className="bg-gradient-to-r from-green-400 to-emerald-500 h-2 rounded-full transition-all duration-300"
style={{ width: `${Math.min((totalCalories / targetCalories) * 100, 100)}%` }}
></div>
</div>
</div>
<div>
<div className="flex items-center justify-between mb-1">
<span className="text-xs text-green-600">Protein</span>
<span className="text-xs text-green-600">
{totalProtein}g/{targetProtein}g
</span>
</div>
<div className="w-full bg-green-200 rounded-full h-2">
<div
className="bg-gradient-to-r from-green-400 to-emerald-500 h-2 rounded-full transition-all duration-300"
style={{ width: `${Math.min((totalProtein / targetProtein) * 100, 100)}%` }}
></div>
</div>
</div>
</div>
</div>
</div>
)
}