import { create } from 'zustand';
import { persist, createJSONStorage } from 'zustand/middleware';
import AsyncStorage from '@react-native-async-storage/async-storage';
import { UserPreferences } from '../types';
import { getPreferences } from '../services/api';

interface PrefState {
  /** Cached user preferences — available immediately after first load. */
  preferences: UserPreferences | null;
  /** True after the store has been hydrated from AsyncStorage. */
  hydrated: boolean;
  /** True while a network refresh is in progress. */
  loading: boolean;
  /** True if loadPreferences() has completed at least once (from cache or net). */
  loaded: boolean;

  /** Load preferences from the API and update the cache. */
  loadPreferences: () => Promise<void>;

  /** Directly set preferences (e.g. after a local toggle). */
  setPreferences: (prefs: UserPreferences) => void;

  /** Build API query params from active preferences. */
  getRaceQueryParams: () => Record<string, any>;

  /** Check whether any feed filters are active. */
  hasActiveFilters: () => boolean;
}

export const usePrefStore = create<PrefState>()(
  persist(
    (set, get) => ({
      preferences: null,
      hydrated: false,
      loading: false,
      loaded: false,

      loadPreferences: async () => {
        const { loaded } = get();
        // Don't show a loading spinner on cache-hit re-fetches
        if (!loaded) set({ loading: true });

        try {
          const prefs = await getPreferences();
          set({ preferences: prefs, loaded: true, loading: false, hydrated: true });
        } catch (error) {
          console.error('[prefStore] Failed to load preferences:', error);
          // If we have cached data, keep it; otherwise set loaded so UI proceeds
          if (!get().preferences) {
            set({ loaded: true, loading: false, hydrated: true });
          } else {
            set({ loaded: true, loading: false, hydrated: true });
          }
        }
      },

      setPreferences: (prefs: UserPreferences) => {
        set({ preferences: prefs });
      },

      getRaceQueryParams: () => {
        const { preferences } = get();
        const params: Record<string, any> = { limit: 50 };

        if (!preferences) return params;

        // API supports a single racing_type — if exactly one is selected, pass it
        if (preferences.preferred_racing_types?.length === 1) {
          params.racing_type = preferences.preferred_racing_types[0];
        }

        // API supports a single track substring — if exactly one is selected, pass it
        if (preferences.favorite_tracks?.length === 1) {
          params.track = preferences.favorite_tracks[0];
        }

        return params;
      },

      hasActiveFilters: () => {
        const { preferences } = get();
        if (!preferences) return false;
        return (
          (preferences.preferred_racing_types?.length ?? 0) > 0 ||
          (preferences.favorite_tracks?.length ?? 0) > 0
        );
      },
    }),
    {
      name: 'tipsharks-prefs',
      storage: createJSONStorage(() => AsyncStorage),
      // Only persist the preference data, not transient state flags
      partialize: (state) => ({
        preferences: state.preferences,
        loaded: state.loaded,
        hydrated: state.hydrated,
      }),
      // On rehydrate, mark hydrated so UI knows data is available
      onRehydrateStorage: () => (state) => {
        if (state) {
          state.hydrated = true;
        }
      },
    },
  ),
);
