"use client"; import { useCallback, useState } from "react"; import { motion } from "framer-motion"; import { CalendarDays, ChevronRight, Clock3, CloudRain, CloudSun, Droplets, ExternalLink, RefreshCw, ThermometerSun, Wind } from "lucide-react"; import { DayForecastCharts } from "@/components/charts/day-forecast-charts"; import { DayForecastModal } from "@/components/forecast/day-forecast-modal"; import { ForecastIcon } from "@/components/forecast/forecast-icon"; import { LoadingSkeleton } from "@/components/states/loading-skeleton"; import { EmptyState } from "@/components/states/empty-state"; import { Button } from "@/components/ui/button"; import { Card } from "@/components/ui/card"; import { useForecast } from "@/hooks/use-forecast"; import { useI18n } from "@/lib/i18n"; import { formatForecastRainfall, formatForecastTemperature, formatForecastWind, getForecastCondition, getHourlyForecastForDay, getUpcomingHourlyForecast, } from "@/lib/forecast-utils"; import type { DailyForecast } from "@/types/forecast"; function formatHour(value: string) { return value.slice(11, 16); } function formatDay(value: string, locale: string, todayLabel: string, index: number) { if (index === 0) return todayLabel; return new Intl.DateTimeFormat(locale, { weekday: "short", timeZone: "UTC" }).format(new Date(`${value}T12:00:00Z`)); } function DailyForecastRow({ day, index, onSelect }: { day: DailyForecast; index: number; onSelect: (day: DailyForecast) => void }) { const { language, locale, t } = useI18n(); const label = formatDay(day.date, locale, t("forecast.today"), index); return ( onSelect(day)} >

{label}

{getForecastCondition(day.weatherCode, language)} · {formatForecastRainfall(day.precipitation, language)}
{day.precipitationProbability === null ? "—" : `${day.precipitationProbability}%`}

{formatForecastTemperature(day.temperatureMax, language)}{formatForecastTemperature(day.temperatureMin, language)}

); } export function ForecastPanel({ latitude, longitude, locationName }: { latitude?: number; longitude?: number; locationName: string }) { const { language, t } = useI18n(); const { data: forecast, isPending, isError, refetch } = useForecast(latitude, longitude); const [selectedDay, setSelectedDay] = useState(null); const closeDayDetails = useCallback(() => setSelectedDay(null), []); const upcomingHours = forecast ? getUpcomingHourlyForecast(forecast.hourly) : []; const todayHours = forecast?.daily[0] ? getHourlyForecastForDay(forecast.hourly, forecast.daily[0].date) : []; const selectedDayHours = forecast && selectedDay ? getHourlyForecastForDay(forecast.hourly, selectedDay.date) : []; return (

{t("forecast.label")}

{t("forecast.title")}

{t("forecast.description", { location: locationName })}

{!Number.isFinite(latitude) || !Number.isFinite(longitude) || isPending ? (
) : isError || !forecast ? (

{t("forecast.error")}

) : !forecast.hourly.length || !forecast.daily.length ? ( ) : (

{t("forecast.hourly")}

    {upcomingHours.map((hour, index) => (

    {formatHour(hour.time)}

    {formatForecastTemperature(hour.temperature, language)}

    {hour.precipitationProbability === null ? "—" : `${hour.precipitationProbability}%`}

    {formatForecastTemperature(hour.feelsLike, language)}

    {formatForecastWind(hour.windSpeed, language)}

    {formatForecastRainfall(hour.precipitation, language)}

    ))}

{t("forecast.daily")}

    {forecast.daily.map((day, index) => )}
)}

{t("forecast.source")} Open-Meteo

); }