"use client"; import { create } from "zustand"; import { persist } from "zustand/middleware"; import type { SelectedLocation } from "@/types/location"; import type { Province } from "@/types/province"; import type { DistanceUnit, PrecipitationUnit, PressureUnit, TemperatureUnit, WindSpeedUnit } from "@/types/units"; import { DEFAULT_APP_SECTION_VISIBILITY, normalizeAppSectionVisibility, type AppSectionId, type AppSectionVisibility, } from "@/lib/app-sections"; import { DEFAULT_DASHBOARD_SECTION_VISIBILITY, normalizeDashboardSectionVisibility, type DashboardSectionId, type DashboardSectionVisibility, } from "@/lib/dashboard-sections"; import { DEFAULT_DISTANCE_UNIT, DEFAULT_PRECIPITATION_UNIT, DEFAULT_PRESSURE_UNIT, DEFAULT_TEMPERATURE_UNIT, DEFAULT_WIND_SPEED_UNIT, isDistanceUnit, isPrecipitationUnit, isPressureUnit, isTemperatureUnit, isWindSpeedUnit, } from "@/lib/weather-utils"; import type { WeatherRegion } from "@/types/weather-region"; import { getWeatherRegionForCountryCode } from "@/types/weather-region"; type NotificationProvinceMode = "selected" | "manual"; interface WeatherStore { favorites: string[]; selectedStationId: string | null; selectedLocation: SelectedLocation | null; warningNotificationsEnabled: boolean; morningBriefNotificationsEnabled: boolean; tomorrowBriefNotificationsEnabled: boolean; warningNotificationProvinceMode: NotificationProvinceMode; warningNotificationProvince: Province | null; temperatureUnit: TemperatureUnit; windSpeedUnit: WindSpeedUnit; precipitationUnit: PrecipitationUnit; pressureUnit: PressureUnit; distanceUnit: DistanceUnit; dashboardSections: DashboardSectionVisibility; appSections: AppSectionVisibility; toggleFavorite: (id: string) => void; selectStation: (id: string) => void; selectLocation: (location: SelectedLocation) => void; setWarningNotificationsEnabled: (enabled: boolean) => void; setMorningBriefNotificationsEnabled: (enabled: boolean) => void; setTomorrowBriefNotificationsEnabled: (enabled: boolean) => void; setWarningNotificationProvinceMode: (mode: NotificationProvinceMode) => void; setWarningNotificationProvince: (province: Province | null) => void; setTemperatureUnit: (unit: TemperatureUnit) => void; setWindSpeedUnit: (unit: WindSpeedUnit) => void; setPrecipitationUnit: (unit: PrecipitationUnit) => void; setPressureUnit: (unit: PressureUnit) => void; setDistanceUnit: (unit: DistanceUnit) => void; setDashboardSectionVisible: (section: DashboardSectionId, visible: boolean) => void; setAppSectionVisible: (section: AppSectionId, visible: boolean) => void; } export const useWeatherStore = create()( persist( (set) => ({ favorites: [], selectedStationId: null, selectedLocation: null, warningNotificationsEnabled: false, morningBriefNotificationsEnabled: false, tomorrowBriefNotificationsEnabled: false, warningNotificationProvinceMode: "selected", warningNotificationProvince: null, temperatureUnit: DEFAULT_TEMPERATURE_UNIT, windSpeedUnit: DEFAULT_WIND_SPEED_UNIT, precipitationUnit: DEFAULT_PRECIPITATION_UNIT, pressureUnit: DEFAULT_PRESSURE_UNIT, distanceUnit: DEFAULT_DISTANCE_UNIT, dashboardSections: DEFAULT_DASHBOARD_SECTION_VISIBILITY, appSections: DEFAULT_APP_SECTION_VISIBILITY, toggleFavorite: (id) => set((state) => ({ favorites: state.favorites.includes(id) ? state.favorites.filter((favoriteId) => favoriteId !== id) : [...state.favorites, id], })), selectStation: (id) => set({ selectedStationId: id, selectedLocation: null }), selectLocation: (location) => set({ selectedStationId: location.stationId, selectedLocation: location }), setWarningNotificationsEnabled: (enabled) => set({ warningNotificationsEnabled: enabled }), setMorningBriefNotificationsEnabled: (enabled) => set({ morningBriefNotificationsEnabled: enabled }), setTomorrowBriefNotificationsEnabled: (enabled) => set({ tomorrowBriefNotificationsEnabled: enabled }), setWarningNotificationProvinceMode: (mode) => set({ warningNotificationProvinceMode: mode }), setWarningNotificationProvince: (province) => set({ warningNotificationProvince: province }), setTemperatureUnit: (unit) => set({ temperatureUnit: unit }), setWindSpeedUnit: (unit) => set({ windSpeedUnit: unit }), setPrecipitationUnit: (unit) => set({ precipitationUnit: unit }), setPressureUnit: (unit) => set({ pressureUnit: unit }), setDistanceUnit: (unit) => set({ distanceUnit: unit }), setDashboardSectionVisible: (section, visible) => set((state) => ({ dashboardSections: { ...state.dashboardSections, [section]: visible }, })), setAppSectionVisible: (section, visible) => set((state) => ({ appSections: { ...state.appSections, [section]: visible }, })), }), { name: "wtr:preferences", migrate: (persisted) => { const state = persisted as Partial | undefined; const location = state?.selectedLocation as | (Partial & { region?: WeatherRegion }) | null | undefined; if (!state) return persisted; const dashboardSections = normalizeDashboardSectionVisibility(state.dashboardSections); const appSections = normalizeAppSectionVisibility(state.appSections); const unitPreferences = { temperatureUnit: isTemperatureUnit(state.temperatureUnit) ? state.temperatureUnit : DEFAULT_TEMPERATURE_UNIT, windSpeedUnit: isWindSpeedUnit(state.windSpeedUnit) ? state.windSpeedUnit : DEFAULT_WIND_SPEED_UNIT, precipitationUnit: isPrecipitationUnit(state.precipitationUnit) ? state.precipitationUnit : DEFAULT_PRECIPITATION_UNIT, pressureUnit: isPressureUnit(state.pressureUnit) ? state.pressureUnit : DEFAULT_PRESSURE_UNIT, distanceUnit: isDistanceUnit(state.distanceUnit) ? state.distanceUnit : DEFAULT_DISTANCE_UNIT, }; if (!location) return { ...state, ...unitPreferences, dashboardSections, appSections }; const countryCode = location.countryCode ?? (location.province ? "PL" : null); const region = location.region ?? getWeatherRegionForCountryCode(countryCode); return { ...state, ...unitPreferences, dashboardSections, appSections, selectedLocation: { ...location, country: location.country ?? (countryCode === "PL" ? "Polska" : null), countryCode, admin1: location.admin1 ?? location.province ?? null, admin2: location.admin2 ?? location.district ?? null, timezone: location.timezone ?? (countryCode === "PL" ? "Europe/Warsaw" : null), region, stationId: location.stationId ?? null, stationName: location.stationName ?? null, distanceKm: location.distanceKm ?? null, }, }; }, }, ), );