// src/context/AppContext.tsx

import React, { createContext, useState, useContext, useEffect, useCallback, ReactNode } from 'react';
import AsyncStorage from '@react-native-async-storage/async-storage';
import { translations, Theme, themes } from './config';
import { HistoricalFigure } from '../types/types';
import { db } from '../services/firebaseConfig';
import { collection, getDocs, doc, updateDoc, increment } from 'firebase/firestore';
import { Alert } from 'react-native';

// Define supported languages and themes
type Language = 'en' | 'tr';
type ThemeType = 'light' | 'dark';

// Define the shape of the context
interface AppContextType {
  language: Language;
  theme: ThemeType;
  toggleTheme: () => void;
  changeLanguage: (lang: Language) => void;
  t: (key: string) => string;
  currentTheme: Theme;
  historicalFigures: HistoricalFigure[];
  loading: boolean;
  refreshing: boolean;
  loadFigures: () => Promise<void>;
  refreshFigures: () => Promise<void>;
  incrementPopularity: (figureId: string) => Promise<void>;
  categories: string[];
}

// Create the context
const AppContext = createContext<AppContextType | undefined>(undefined);

// Define storage keys and cache duration
const STORAGE_KEY_FIGURES = 'historical_figures';
const STORAGE_KEY_FIGURES_TIMESTAMP = 'historical_figures_timestamp';
const CACHE_DURATION = 24 * 60 * 60 * 1000; // 1 day in milliseconds

// Create the provider component
export const AppProvider: React.FC<{ children: ReactNode }> = ({ children }) => {
  // State variables
  const [language, setLanguage] = useState<Language>('en');
  const [theme, setTheme] = useState<ThemeType>('light');
  const [historicalFigures, setHistoricalFigures] = useState<HistoricalFigure[]>([]);
  const [loading, setLoading] = useState<boolean>(false);
  const [refreshing, setRefreshing] = useState<boolean>(false);
  const [categories, setCategories] = useState<string[]>([]);

  // Load language and theme settings from AsyncStorage on mount
  useEffect(() => {
    const loadSettings = async () => {
      try {
        const storedLanguage = (await AsyncStorage.getItem('language')) as Language;
        const storedTheme = (await AsyncStorage.getItem('theme')) as ThemeType;
        if (storedLanguage) setLanguage(storedLanguage);
        if (storedTheme) setTheme(storedTheme);
      } catch (error) {
        console.error('Error loading settings:', error);
      }
    };

    loadSettings();
  }, []);

  // Load historical figures data when the component mounts
  useEffect(() => {
    loadFigures();
  }, []);

  // Function to toggle between light and dark themes
  const toggleTheme = () => {
    const newTheme = theme === 'light' ? 'dark' : 'light';
    setTheme(newTheme);
    AsyncStorage.setItem('theme', newTheme).catch((err) =>
      console.error('Error saving theme:', err)
    );
  };

  // Function to change the language
  const changeLanguage = (lang: Language) => {
    setLanguage(lang);
    AsyncStorage.setItem('language', lang).catch((err) =>
      console.error('Error saving language:', err)
    );
  };

  // Translation function based on the current language
  const t = (key: string): string => {
    return translations[language][key] || key;
  };

  /**
   * Function to load historical figures.
   * It first attempts to load from cache (AsyncStorage).
   * If cache is invalid or absent, it fetches from Firebase.
   */
  const loadFigures = useCallback(async () => {
    setLoading(true);
    try {
      const [cachedFigures, cachedTimestamp] = await Promise.all([
        AsyncStorage.getItem(STORAGE_KEY_FIGURES),
        AsyncStorage.getItem(STORAGE_KEY_FIGURES_TIMESTAMP),
      ]);

      const now = Date.now();
      const isCacheValid =
        cachedFigures &&
        cachedTimestamp &&
        now - parseInt(cachedTimestamp, 10) < CACHE_DURATION;

      if (isCacheValid) {
        const figuresList: HistoricalFigure[] = JSON.parse(cachedFigures);
        figuresList.sort((a, b) => (b.popularity || 0) - (a.popularity || 0));
        setHistoricalFigures(figuresList);
        extractCategories(figuresList);
      } else {
        await fetchFiguresFromFirebase();
      }
    } catch (error) {
      console.error('Error loading figures:', error);
      Alert.alert(t('error'), t('errorLoadingFigures'));
    } finally {
      setLoading(false);
    }
  }, [t]);

  /**
   * Function to fetch historical figures from Firebase.
   * It updates both the state and the cache.
   */
  const fetchFiguresFromFirebase = useCallback(async () => {
    try {
      const figuresCollection = collection(db, 'figures');
      const figuresSnapshot = await getDocs(figuresCollection);
      const figuresList: HistoricalFigure[] = figuresSnapshot.docs.map((doc) => {
        const data = doc.data();
        return {
          id: doc.id,
          name: data.name,
          image: data.image,
          systemPrompt: data.systemPrompt,
          description: data.description || '',
          ai: data.ai || 'openai',
          starterQuestions: data.starterQuestions || [],
          category: data.category || 'Uncategorized',
          popularity: data.popularity || 0,
        } as HistoricalFigure;
      });

      // Sort figures by popularity in descending order
      figuresList.sort((a, b) => (b.popularity || 0) - (a.popularity || 0));

      setHistoricalFigures(figuresList);
      extractCategories(figuresList);

      const now = Date.now();
      await Promise.all([
        AsyncStorage.setItem(STORAGE_KEY_FIGURES, JSON.stringify(figuresList)),
        AsyncStorage.setItem(STORAGE_KEY_FIGURES_TIMESTAMP, now.toString()),
      ]);
    } catch (error) {
      console.error('Error fetching figures from Firebase:', error);
      Alert.alert(t('error'), t('errorLoadingFigures'));
      throw error; // Re-throw to allow caller to handle if needed
    }
  }, [t]);

  /**
   * Function to refresh historical figures.
   * It fetches fresh data from Firebase regardless of the cache.
   */
  const refreshFigures = useCallback(async () => {
    setRefreshing(true);
    try {
      await fetchFiguresFromFirebase();
    } catch (error) {
      console.error('Error refreshing figures:', error);
      Alert.alert(t('error'), t('errorLoadingFigures'));
    } finally {
      setRefreshing(false);
    }
  }, [fetchFiguresFromFirebase, t]);

  /**
   * Function to increment the popularity of a specific historical figure.
   * It updates both the local state and Firebase.
   */
  const incrementPopularity = useCallback(
    async (figureId: string) => {
      // Update local state optimistically
      setHistoricalFigures((prevFigures) => {
        const updatedFigures = prevFigures.map((fig) => {
          if (fig.id === figureId) {
            return {
              ...fig,
              popularity: (fig.popularity || 0) + 1,
            };
          }
          return fig;
        });

        // Sort figures by popularity in descending order
        updatedFigures.sort((a, b) => (b.popularity || 0) - (a.popularity || 0));

        // Update the cache with the new figures list
        AsyncStorage.setItem(STORAGE_KEY_FIGURES, JSON.stringify(updatedFigures)).catch((err) =>
          console.error('Error saving figures:', err)
        );

        return updatedFigures;
      });

      // Update popularity in Firebase
      try {
        const figureDocRef = doc(db, 'figures', figureId);
        await updateDoc(figureDocRef, {
          popularity: increment(1),
        });
      } catch (error) {
        console.error('Error updating popularity in Firebase:', error);
        // Optional: Revert the local state change if Firebase update fails
      }
    },
    []
  );

  /**
   * Function to extract unique categories from the list of historical figures.
   * It ensures 'All' is always the first category and avoids duplicates.
   */
  const extractCategories = useCallback((figures: HistoricalFigure[]) => {
    const allCategoriesSet = new Set<string>(figures.map((fig) => fig.category));
    const allCategories = Array.from(allCategoriesSet).sort(); // Optional: sort categories

    // Ensure 'All' is not duplicated
    const uniqueCategories = allCategories.filter((category) => category !== 'All');

    setCategories(['All', ...uniqueCategories]);
  }, []);

  // Define the context value
  const value: AppContextType = {
    language,
    theme,
    toggleTheme,
    changeLanguage,
    t,
    currentTheme: themes[theme],
    historicalFigures,
    loading,
    refreshing,
    loadFigures,
    refreshFigures,
    incrementPopularity,
    categories,
  };

  return <AppContext.Provider value={value}>{children}</AppContext.Provider>;
};

// Custom hook to use the AppContext
export const useApp = (): AppContextType => {
  const context = useContext(AppContext);
  if (context === undefined) {
    throw new Error('useApp must be used within an AppProvider');
  }
  return context;
}; bu kodda şöyle bir değişiklik yapacaksın:

eğer kullanıcının dili tr ise türkçe, eğer tr dışında herhangi bir dil ise en kullanılacak. ve bu contextin dışından bir yerden kullanıcının diline erişilebilecek. mesela başka bir dosyada kullanıcının hangi dil seçeneğinde olduğunu anlayabileceğim şekilde güncelle.