ERROR  Warning: Encountered two children with the same key, `.$2`. Keys should be unique so that components maintain their identity across updates. Non-unique keys may cause children to be duplicated and/or omitted — the behavior is unsupported and could change in a future version.
    in RCTView (created by View)
    in View (created by ScrollView)
    in RCTScrollView (created by ScrollView)
    in ScrollView (created by ScrollView)
    in ScrollView (created by VirtualizedList)
    in VirtualizedListContextProvider (created by VirtualizedList)
    in VirtualizedList (created by FlatList)
    in FlatList (created by ChatListScreen)
    in RCTView (created by View)
    in View (created by ChatListScreen)
    in RCTView (created by View)
    in View (created by ChatListScreen)
    in ChatListScreen (created by SceneView)
    in StaticContainer
    in EnsureSingleNavigator (created by SceneView)
    in SceneView (created by CardContainer)
    in RCTView (created by View)
    in View (created by CardContainer)
    in RCTView (created by View)
    in View (created by CardContainer)
    in RCTView (created by View)
    in View
    in CardSheet (created by Card)
    in RCTView (created by View)
    in View (created by Animated(View))
    in Animated(View) (created by PanGestureHandler)
    in PanGestureHandler (created by PanGestureHandler)
    in PanGestureHandler (created by Card)
    in RCTView (created by View)
    in View (created by Animated(View))
    in Animated(View) (created by Card)
    in RCTView (created by View)
    in View (created by Card)
    in Card (created by CardContainer)
    in CardContainer (created by CardStack)
    in RNSScreen (created by Animated(Anonymous))
    in Animated(Anonymous) (created by InnerScreen)
    in Suspender (created by Freeze)
    in Suspense (created by Freeze)
    in Freeze (created by DelayedFreeze)
    in DelayedFreeze (created by InnerScreen)
    in InnerScreen (created by Screen)
    in Screen (created by MaybeScreen)
    in MaybeScreen (created by CardStack)
    in RNSScreenContainer (created by ScreenContainer)
 bu hatayı düzelt. proje kodlarımı atıyorum işine yarar belki. kodları düzelt:

// 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.
   */
  const extractCategories = useCallback((figures: HistoricalFigure[]) => {
    const allCategoriesSet = new Set<string>(figures.map((fig) => fig.category));
    const allCategories = Array.from(allCategoriesSet).sort(); // Optional: sort categories
    setCategories(['All', ...allCategories]);
  }, []);

  // 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;
};

import React, { createContext, useState, useEffect, useCallback, ReactNode, useContext } from 'react';
import AsyncStorage from '@react-native-async-storage/async-storage';
import { Chat, Message } from '../types/types';
import { CoinContext } from './CoinContext';
import { doc, updateDoc, increment } from 'firebase/firestore';
import { db } from '../services/firebaseConfig';

interface ChatWithLastMessage extends Chat {
  lastMessage?: string;
  lastMessageTimestamp?: number;
}

interface ChatContextProps {
  chats: ChatWithLastMessage[];
  addChat: (chat: Chat, messages?: Message[]) => Promise<void>;
  updateChat: (chatId: string, message: Message) => Promise<void>;
  deleteChat: (chatId: string) => Promise<void>;
  deleteAllChats: () => Promise<void>;
}

export const ChatContext = createContext<ChatContextProps>({
  chats: [],
  addChat: async () => {},
  updateChat: async () => {},
  deleteChat: async () => {},
  deleteAllChats: async () => {},
});

interface ChatProviderProps {
  children: ReactNode;
}

export const ChatProvider: React.FC<ChatProviderProps> = ({ children }) => {
  const [chats, setChats] = useState<ChatWithLastMessage[]>([]);
  const { deductCoins } = useContext(CoinContext);

  useEffect(() => {
    const loadChats = async () => {
      try {
        const chatsData = await AsyncStorage.getItem('chats');
        const chatsList: Chat[] = chatsData ? JSON.parse(chatsData) : [];

        const chatsWithMessages: ChatWithLastMessage[] = await Promise.all(
          chatsList.map(async (chat) => {
            const messagesData = await AsyncStorage.getItem(`chat_${chat.id}_messages`);
            const messages: Message[] = messagesData ? JSON.parse(messagesData) : [];
            const lastMessage = messages[messages.length - 1]?.text || '';
            const lastTimestamp = messages[messages.length - 1]?.timestamp || chat.createdAt;
            return {
              ...chat,
              lastMessage,
              lastMessageTimestamp: lastTimestamp,
            };
          })
        );

        const sortedChats = chatsWithMessages.sort(
          (a, b) => (b.lastMessageTimestamp || 0) - (a.lastMessageTimestamp || 0)
        );

        setChats(sortedChats);
      } catch (error) {
        console.error('Error loading chats:', error);
      }
    };

    loadChats();
  }, []);

  const addChat = useCallback(async (chat: Chat, messages: Message[] = []): Promise<void> => {
    try {
      const newChat: ChatWithLastMessage = {
        ...chat,
        lastMessage: messages.length > 0 ? messages[messages.length - 1].text : '',
        lastMessageTimestamp: messages.length > 0 ? messages[messages.length - 1].timestamp : chat.createdAt,
      };
      setChats((prevChats) => {
        const updatedChats = [...prevChats, newChat];
        AsyncStorage.setItem('chats', JSON.stringify(updatedChats)).catch((err: Error) =>
          console.error('Error updating chats in AsyncStorage:', err)
        );
        return updatedChats;
      });
      await AsyncStorage.setItem(`chat_${chat.id}_messages`, JSON.stringify(messages));
    } catch (error) {
      console.error('Error adding chat:', error);
    }
  }, []);

  const updateChat = useCallback(async (chatId: string, message: Message): Promise<void> => {
    try {
      const messagesData = await AsyncStorage.getItem(`chat_${chatId}_messages`);
      const messages: Message[] = messagesData ? JSON.parse(messagesData) : [];
      const updatedMessages = [...messages, message];
      await AsyncStorage.setItem(`chat_${chatId}_messages`, JSON.stringify(updatedMessages));

      setChats((prevChats) => {
        const updatedChats = prevChats
          .map((chat) => {
            if (chat.id === chatId) {
              return {
                ...chat,
                lastMessage: message.text,
                lastMessageTimestamp: message.timestamp,
              };
            }
            return chat;
          })
          .sort((a, b) => (b.lastMessageTimestamp || 0) - (a.lastMessageTimestamp || 0));

        AsyncStorage.setItem('chats', JSON.stringify(updatedChats)).catch((err: Error) =>
          console.error('Error updating chats in AsyncStorage:', err)
        );

        return updatedChats;
      });

      if (message.isUser) {
        deductCoins(1);
      }
    } catch (error) {
      console.error('Error updating chat:', error);
    }
  }, [deductCoins]);

  const deleteChat = useCallback(async (chatId: string): Promise<void> => {
    try {
      const updatedChats = chats.filter((chat) => chat.id !== chatId);
      setChats(updatedChats);
      await AsyncStorage.setItem('chats', JSON.stringify(updatedChats));
      await AsyncStorage.removeItem(`chat_${chatId}_messages`);
    } catch (error) {
      console.error('Error deleting chat:', error);
    }
  }, [chats]);

  const deleteAllChats = useCallback(async (): Promise<void> => {
    try {
      setChats([]);
      await AsyncStorage.removeItem('chats');
      const keys = await AsyncStorage.getAllKeys();
      const chatMessageKeys = keys.filter(
        (key) => key.startsWith('chat_') && key.endsWith('_messages')
      );
      await AsyncStorage.multiRemove(chatMessageKeys);
    } catch (error) {
      console.error('Error deleting all chats:', error);
    }
  }, []);

  return (
    <ChatContext.Provider value={{ chats, addChat, updateChat, deleteChat, deleteAllChats }}>
      {children}
    </ChatContext.Provider>
  );
};


// src/screens/ChatListScreen.tsx

import React, { useContext, useEffect, useState, useCallback } from 'react';
import { 
  View,
  FlatList, 
  Image, 
  TouchableOpacity, 
  StyleSheet, 
  Alert,
  SafeAreaView,
  Platform,
  StatusBar as RNStatusBar
} from 'react-native';
import { StatusBar } from 'expo-status-bar';
import { useNavigation, useIsFocused } from '@react-navigation/native';
import { Ionicons } from '@expo/vector-icons';
import { ChatContext, ChatWithLastMessage } from '../context/ChatContext';
import CustomText from '../components/CustomText';
import { useApp } from '../context/AppContext';
import { StackNavigationProp } from '@react-navigation/stack';
import { TabParamList } from '../navigation/types'; // Navigasyon türlerini import edin

type NavigationProp = StackNavigationProp<TabParamList, 'Chats'>;

const ChatListScreen: React.FC = () => {
  const navigation = useNavigation<NavigationProp>();
  const { chats, deleteChat, deleteAllChats } = useContext(ChatContext);
  const [sortedChats, setSortedChats] = useState<ChatWithLastMessage[]>([]);
  const [loading, setLoading] = useState<boolean>(true);
  const isFocused = useIsFocused();
  const { t, currentTheme } = useApp();

  useEffect(() => {
    const sortChats = () => {
      const sorted = [...chats].sort(
        (a, b) => (b.lastMessageTimestamp || 0) - (a.lastMessageTimestamp || 0)
      );
      setSortedChats(sorted);
      setLoading(false);
    };

    sortChats();
  }, [chats, isFocused]);

  const handleDeleteChat = useCallback(
    (chatId: string) => {
      Alert.alert(
        t('deleteChat'),
        t('deleteChatConfirmation'),
        [
          { text: t('cancel'), style: "cancel" },
          { text: t('delete'), style: "destructive", onPress: () => deleteChat(chatId) }
        ]
      );
    },
    [deleteChat, t]
  );

  const handleDeleteAllChats = useCallback(() => {
    Alert.alert(
      t('deleteAllChats'),
      t('deleteAllChatsConfirmation'),
      [
        { text: t('cancel'), style: "cancel" },
        { text: t('delete'), style: "destructive", onPress: deleteAllChats }
      ]
    );
  }, [deleteAllChats, t]);

  const renderChatItem = useCallback(
    ({ item }: { item: ChatWithLastMessage }) => (
      <TouchableOpacity
        style={[styles.chatItem, { backgroundColor: currentTheme.cardBackground }]}
        onPress={() =>
          navigation.navigate('Chat', { chatId: item.id, figure: item.figure })
        }
      >
        <Image source={{ uri: item.figure.image }} style={styles.avatar} />
        <View style={styles.chatInfo}>
          <CustomText bold style={[styles.chatName, { color: currentTheme.textColor }]}>
            {item.figure.name}
          </CustomText>
          <CustomText style={[styles.chatLastMessage, { color: currentTheme.secondaryTextColor }]} numberOfLines={1}>
            {item.lastMessage || t('noMessages')}
          </CustomText>
        </View>
        <View style={styles.chatMeta}>
          <CustomText style={[styles.chatDate, { color: currentTheme.secondaryTextColor }]}>
            {timeAgo(item.lastMessageTimestamp)}
          </CustomText>
          <TouchableOpacity onPress={() => handleDeleteChat(item.id)} style={styles.deleteButton}>
            <Ionicons name="trash-outline" size={24} color={currentTheme.errorColor} />
          </TouchableOpacity>
        </View>
      </TouchableOpacity>
    ),
    [navigation, handleDeleteChat, currentTheme, t]
  );

  const keyExtractor = useCallback((item: ChatWithLastMessage) => item.id, []);

  const timeAgo = (timestamp: number | undefined): string => {
    if (!timestamp) return '';
    const now = Date.now();
    const diff = Math.floor((now - timestamp) / 60000); // difference in minutes
    if (diff < 1) return t('justNow');
    if (diff < 60) return t('minutesAgo').replace('{{count}}', diff.toString());
    const hours = Math.floor(diff / 60);
    if (hours < 24) return t('hoursAgo').replace('{{count}}', hours.toString());
    const days = Math.floor(hours / 24);
    return t('daysAgo').replace('{{count}}', days.toString());
  };

  return (
    <SafeAreaView style={[styles.safeArea, { backgroundColor: currentTheme.backgroundColor }]}>
      <StatusBar style={currentTheme.statusBarStyle} />
      <View style={styles.container}>
        <View style={styles.header}>
          <CustomText bold style={[styles.title, { color: currentTheme.textColor }]}>{t('myChats')}</CustomText>
          {chats.length > 0 && (
            <TouchableOpacity onPress={handleDeleteAllChats} style={styles.deleteAllButton}>
              <Ionicons name="trash-outline" size={24} color={currentTheme.errorColor} />
            </TouchableOpacity>
          )}
        </View>
        {sortedChats.length === 0 ? (
          <View style={styles.emptyContainer}>
            <CustomText style={[styles.emptyText, { color: currentTheme.secondaryTextColor }]}>
              {t('noChatsYet')}
            </CustomText>
          </View>
        ) : (
          <FlatList
            data={sortedChats}
            renderItem={renderChatItem}
            keyExtractor={keyExtractor}
            contentContainerStyle={styles.chatList}
            showsVerticalScrollIndicator={false}
          />
        )}
        <TouchableOpacity
          style={[styles.fab, { backgroundColor: currentTheme.accentColor }]}
          onPress={() => navigation.navigate('Figures', { screen: 'Home' })} // Güncellenmiş yönlendirme
        >
          <Ionicons name="add" size={30} color={currentTheme.buttonTextColor} />
        </TouchableOpacity>
      </View>
    </SafeAreaView>
  );
};

const styles = StyleSheet.create({
  safeArea: {
    flex: 1,
  },
  container: {
    flex: 1,
    paddingHorizontal: 10,
  },
  header: {
    flexDirection: 'row',
    justifyContent: 'space-between',
    alignItems: 'center',
    paddingHorizontal: 15,
    paddingVertical: 15,
  },
  title: {
    fontSize: 24,
    fontFamily: 'Poppins_700Bold',
  },
  deleteAllButton: {
    padding: 5,
  },
  chatList: {
    paddingHorizontal: 15,
    paddingBottom: 80, // FAB için boşluk bırakmak
  },
  emptyContainer: {
    flex: 1,
    justifyContent: 'center',
    alignItems: 'center',
    paddingHorizontal: 32,
  },
  emptyText: {
    fontSize: 16,
    textAlign: 'center',
    fontFamily: 'Poppins_400Regular',
  },
  chatItem: {
    flexDirection: 'row',
    alignItems: 'center',
    borderRadius: 12,
    marginVertical: 8,
    padding: 15,
    shadowOffset: {
      width: 0,
      height: 1,
    },
    shadowOpacity: 0.1,
    shadowRadius: 2,
    shadowColor: '#000',
    elevation: 2,
  },
  avatar: {
    width: 50,
    height: 50,
    borderRadius: 25,
  },
  chatInfo: {
    flex: 1,
    marginLeft: 15,
  },
  chatName: {
    fontSize: 16,
    fontFamily: 'Poppins_700Bold',
  },
  chatLastMessage: {
    fontSize: 14,
    fontFamily: 'Poppins_400Regular',
    marginTop: 2,
  },
  chatMeta: {
    alignItems: 'flex-end',
  },
  chatDate: {
    fontSize: 12,
    fontFamily: 'Poppins_400Regular',
    marginBottom: 5,
  },
  deleteButton: {
    padding: 5,
  },
  fab: {
    position: 'absolute',
    right: 20,
    bottom: 20,
    width: 56,
    height: 56,
    borderRadius: 28,
    justifyContent: 'center',
    alignItems: 'center',
    shadowOffset: {
      width: 0,
      height: 2,
    },
    shadowOpacity: 0.25,
    shadowRadius: 3.84,
    elevation: 5,
  },
});

export default ChatListScreen;


// src/screens/HomeScreen.tsx

import React, { useCallback, useContext, useState } from 'react';
import { 
  View, 
  FlatList, 
  Image, 
  TouchableOpacity, 
  StyleSheet, 
  SafeAreaView,
  ActivityIndicator,
  useWindowDimensions,
  RefreshControl,
  ScrollView,
} from 'react-native';
import { StatusBar } from 'expo-status-bar';
import { useNavigation } from '@react-navigation/native';
import { HistoricalFigure } from '../types/types';
import CustomText from '../components/CustomText';
import { Ionicons } from '@expo/vector-icons';
import { useApp } from '../context/AppContext';
import { ChatContext } from '../context/ChatContext';
import { CoinContext } from '../context/CoinContext';

const HomeScreen = () => {
  const navigation = useNavigation();
  const { 
    historicalFigures, 
    loading, 
    refreshing, 
    t, 
    currentTheme, 
    refreshFigures,
    categories,
  } = useApp();
  const { width } = useWindowDimensions();

  const { addChat } = useContext(ChatContext);
  const { coins, showRewardedAd } = useContext(CoinContext);
  const [selectedCategory, setSelectedCategory] = useState<string>('All');

  const numColumns = 2;

const startChat = useCallback(async (figure: HistoricalFigure) => {
  try {
    // Assuming addChat might create or fetch a chat, adjust as necessary
    // If chatId is generated differently, ensure to retrieve it correctly
    const chatId = figure.id; // Or retrieve from addChat if different

    // Add or initialize the chat
    addChat({
      id: chatId,
      figure,
      messages: [],
    });

    // Navigate to ChatScreen with both chatId and figure
    navigation.navigate('Chat', { chatId, figure });
  } catch (error) {
    console.error('Error starting chat:', error);
    Alert.alert(t('error'), t('errorStartingChat'));
  }
}, [addChat, navigation, t]);

  const renderFigureItem = useCallback(({ item }: { item: HistoricalFigure }) => (
    <TouchableOpacity
      style={[styles.figureItem, { backgroundColor: currentTheme.cardBackground }]}
      onPress={() => startChat(item)}
    >
      <Image source={{ uri: item.image }} style={styles.avatar} />
      <View style={styles.figureInfo}>
        <CustomText bold style={[styles.figureName, { color: currentTheme.textColor }]}>
          {item.name}
        </CustomText>
        <CustomText style={[styles.figureCategory, { color: currentTheme.accentColor }]}>
          {item.category}
        </CustomText>
        <CustomText 
          style={[styles.figureDescription, { color: currentTheme.secondaryTextColor }]} 
          numberOfLines={3}
        >
          {item.description}
        </CustomText>
        <CustomText style={[styles.popularity, { color: currentTheme.accentColor }]}>
          {t('popularity')} {item.popularity || 0}
        </CustomText>
      </View>
    </TouchableOpacity>
  ), [currentTheme, startChat, t]);

  const keyExtractor = useCallback((item: HistoricalFigure) => item.id, []);

  const onRefresh = useCallback(async () => {
    await refreshFigures(); // This will handle refreshing state in AppContext
  }, [refreshFigures]);

  const filteredFigures = selectedCategory === 'All' 
    ? historicalFigures 
    : historicalFigures.filter(fig => fig.category === selectedCategory);

  const renderCategoryItem = useCallback((category: string) => {
    const isSelected = category === selectedCategory;
    return (
      <TouchableOpacity
        key={category} // Ensure each item has a unique key
        style={[
          styles.categoryButton,
          { 
            backgroundColor: isSelected ? currentTheme.accentColor : 'transparent',
            borderColor: isSelected ? currentTheme.accentColor : currentTheme.secondaryTextColor,
          }
        ]}
        onPress={() => setSelectedCategory(category)}
      >
        <CustomText 
          style={[
            styles.categoryText, 
            { 
              color: isSelected ? currentTheme.backgroundColor : currentTheme.textColor,
            }
          ]}
        >
          {t(category)}
        </CustomText>
      </TouchableOpacity>
    );
  }, [selectedCategory, currentTheme, t]);

  const renderCategoryRows = () => {
    // Display categories in two rows for better organization
    const halfLength = Math.ceil(categories.length / 2);
    return (
      <ScrollView 
        horizontal 
        showsHorizontalScrollIndicator={false}
        contentContainerStyle={styles.categoryRowsContainer}
      >
        <View>
          <View style={styles.categoryRow}>
            {categories.slice(0, halfLength).map(renderCategoryItem)}
          </View>
          <View style={styles.categoryRow}>
            {categories.slice(halfLength).map(renderCategoryItem)}
          </View>
        </View>
      </ScrollView>
    );
  };

  return (
    <SafeAreaView style={[styles.safeArea, { backgroundColor: currentTheme.backgroundColor }]}>
      <StatusBar style={currentTheme.statusBarStyle} />
      <View style={styles.container}>
        {/* Header */}
        <View style={styles.header}>
          <CustomText bold style={[styles.title, { color: currentTheme.textColor }]}>
            {t('historicalFigures')}
          </CustomText>
          <View style={styles.headerRight}>
            {/* Coin Display */}
            <TouchableOpacity style={styles.coinContainer} onPress={showRewardedAd}>
              <Ionicons name="flash" size={20} color={currentTheme.accentColor} />
              <CustomText style={[styles.coinText, { color: currentTheme.textColor }]}>
                {coins}
              </CustomText>
            </TouchableOpacity>
            {/* Settings Button */}
            <TouchableOpacity 
              style={styles.settingsButton} 
              onPress={() => navigation.navigate('Settings')}
            >
              <Ionicons name="settings-outline" size={24} color={currentTheme.accentColor} />
            </TouchableOpacity>
          </View>
        </View>

        {/* Category Selector (Two Rows, Scrollable Horizontally) */}
        {renderCategoryRows()}

        {/* Content */}
        {loading ? (
          // Show a single loading indicator during the initial load
          <View style={styles.loadingContainer}>
            <ActivityIndicator size="large" color={currentTheme.accentColor} />
          </View>
        ) : (
          <>
            {filteredFigures.length === 0 ? (
              <View style={styles.emptyContainer}>
                <CustomText style={[styles.emptyText, { color: currentTheme.textColor }]}>
                  {t('noFiguresInThisCategory')}
                </CustomText>
              </View>
            ) : (
              <FlatList
                data={filteredFigures}
                renderItem={renderFigureItem}
                keyExtractor={keyExtractor}
                contentContainerStyle={styles.figureList}
                numColumns={numColumns}
                key={numColumns.toString()} // Helps in re-rendering when numColumns change
                showsVerticalScrollIndicator={false}
                refreshControl={
                  <RefreshControl
                    refreshing={refreshing}
                    onRefresh={onRefresh}
                    colors={[currentTheme.accentColor]}
                    tintColor={currentTheme.accentColor}
                  />
                }
              />
            )}
          </>
        )}
      </View>
    </SafeAreaView>
  );
};

const styles = StyleSheet.create({
  safeArea: {
    flex: 1,
  },
  container: {
    flex: 1,
    paddingHorizontal: 10,
  },
  header: {
    flexDirection: 'row',
    justifyContent: 'space-between',
    alignItems: 'center',
    paddingVertical: 15,
    paddingHorizontal: 15,
  },
  title: {
    fontFamily: 'Poppins_700Bold',
    fontSize: 24,
  },
  headerRight: {
    flexDirection: 'row',
    alignItems: 'center',
  },
  coinContainer: {
    flexDirection: 'row',
    alignItems: 'center',
    padding: 5,
  },
  coinText: {
    fontFamily: 'Poppins_700Bold',
    fontSize: 18,
    marginLeft: 5,
  },
  settingsButton: {
    padding: 2,
    marginLeft: 2,
  },
  categoryRowsContainer: {
    paddingHorizontal: 5,
    paddingBottom: 20,
  },
  categoryRow: {
    flexDirection: 'row',
    marginBottom: 6,
  },
  categoryButton: {
    paddingVertical: 6,
    paddingHorizontal: 8,
    borderRadius: 16,
    borderWidth: 1,
    marginRight: 5,
  },
  categoryText: {
    fontFamily: 'Poppins_600SemiBold',
    fontSize: 14,
  },
  figureList: {
    paddingVertical: 10,
  },
  figureItem: {
    borderRadius: 12,
    elevation: 3,
    flex: 1,
    margin: 5,
    padding: 10,
    shadowOffset: {
      width: 0,
      height: 1,
    },
    shadowOpacity: 0.22,
    shadowRadius: 2.22,
    shadowColor: '#000',
  },
  avatar: {
    borderRadius: 30,
    height: 100,
    width: 100,
    alignSelf: 'center',
    marginBottom: 10,
  },
  figureInfo: {
    alignItems: 'center',
    flex: 1,
  },
  figureName: {
    fontFamily: 'Poppins_700Bold',
    fontSize: 16,
    textAlign: 'center',
  },
  figureCategory: {
    fontFamily: 'Poppins_600SemiBold',
    fontSize: 12,
  },
  figureDescription: {
    fontFamily: 'Poppins_400Regular',
    fontSize: 14,
    marginTop: 4,
    textAlign: 'center',
  },
  popularity: {
    fontSize: 14,
    marginTop: 8,
    fontFamily: 'Poppins_600SemiBold',
  },
  loadingContainer: {
    flex: 1,
    justifyContent: 'center',
    alignItems: 'center',
  },
  emptyContainer: {
    flex: 1,
    justifyContent: 'center',
    alignItems: 'center',
    padding: 20,
  },
  emptyText: {
    fontSize: 16,
    textAlign: 'center',
  },
});

export default HomeScreen;

// ChatScreen.tsx

import React, { useState, useEffect, useRef, useCallback, useContext } from 'react';
import {
  View,
  FlatList,
  Image,
  TouchableOpacity,
  TextInput,
  StyleSheet,
  KeyboardAvoidingView,
  Platform,
  Dimensions,
  Alert,
  ActivityIndicator,
  LayoutAnimation,
  UIManager,
  Keyboard,
} from 'react-native';
import { useNavigation, useRoute } from '@react-navigation/native';
import { HistoricalFigure, Message } from '../types/types';
import { fetchAIResponse } from '../services/openaiService';
import uuid from 'react-native-uuid';
import MessageItem from '../components/MessageItem';
import { Ionicons } from '@expo/vector-icons';
import CustomText from '../components/CustomText';
import * as Clipboard from 'expo-clipboard';
import { ChatContext } from '../context/ChatContext';
import AsyncStorage from '@react-native-async-storage/async-storage';
import { useApp } from '../context/AppContext';
import { doc, updateDoc, increment } from 'firebase/firestore';
import { db } from '../services/firebaseConfig';
import { CoinContext } from '../context/CoinContext'; 

interface RouteParams {
  chatId: string;
  figure: HistoricalFigure;
}

interface APIMessage {
  role: 'system' | 'user' | 'assistant';
  content: string;
}

const { width, height } = Dimensions.get('window');

// Enable LayoutAnimation on Android
if (
  Platform.OS === 'android' &&
  UIManager.setLayoutAnimationEnabledExperimental
) {
  UIManager.setLayoutAnimationEnabledExperimental(true);
}

const ChatScreen = () => {
  const navigation = useNavigation();
  const route = useRoute();
  const { chatId, figure } = route.params as RouteParams;
  const { updateChat, addChat } = useContext(ChatContext);
  const { t, currentTheme, incrementPopularity } = useApp();
  const [messages, setMessages] = useState<Message[]>([]);
  const [inputText, setInputText] = useState<string>('');
  const [isLoading, setIsLoading] = useState<boolean>(false);
  const flatListRef = useRef<FlatList>(null);
  const isInitialLoad = useRef<boolean>(false);
  const { coins, deductCoins, showRewardedAd } = useContext(CoinContext);
  
  // Keyboard visibility state
  const [isKeyboardVisible, setKeyboardVisible] = useState<boolean>(false);

  // AI Models
  const aiModel = figure.ai ? figure.ai : 'openai';

  // Ref to track pending AI message IDs
  const pendingAIMessageIdsRef = useRef<string[]>([]);

  // Listen to keyboard events
  useEffect(() => {
    const keyboardDidShowListener = Keyboard.addListener(
      'keyboardDidShow',
      () => {
        setKeyboardVisible(true); // Keyboard is visible
      }
    );
    const keyboardDidHideListener = Keyboard.addListener(
      'keyboardDidHide',
      () => {
        setKeyboardVisible(false); // Keyboard is hidden
      }
    );

    return () => {
      keyboardDidShowListener.remove();
      keyboardDidHideListener.remove();
    };
  }, []);

  // Load messages on mount
  useEffect(() => {
    if (isInitialLoad.current) return;

    const loadMessages = async () => {
      try {
        setIsLoading(true);
        setMessages([]);

        const messagesData = await AsyncStorage.getItem(`chat_${chatId}_messages`);
        let msgs: Message[] = messagesData ? JSON.parse(messagesData) : [];

        if (msgs.length === 0) {
          const aiDescription: Message = {
            id: uuid.v4().toString(),
            text: figure.description || t('noDescriptionAvailable'),
            isUser: false,
            timestamp: Date.now(),
            status: 'completed',
          };

          msgs = [aiDescription];

          const newChat = {
            id: chatId,
            figure: figure,
            createdAt: Date.now(),
          };
          await addChat(newChat, msgs);
        }

        // Ensure messages are unique and sorted as [new, ...old]
        const uniqueMsgsMap = new Map<string, Message>();
        msgs.forEach(msg => {
          uniqueMsgsMap.set(msg.id, msg);
        });
        const uniqueMsgs = Array.from(uniqueMsgsMap.values()).sort((a, b) => b.timestamp - a.timestamp);

        setMessages(uniqueMsgs);
        setIsLoading(false);

        // Scroll to the latest message
        setTimeout(() => {
          flatListRef.current?.scrollToOffset({ animated: true, offset: 0 });
        }, 100);
      } catch (error) {
        console.error('Mesajlar yüklenirken hata oluştu:', error);
        setIsLoading(false);
      }
    };

    loadMessages();
    isInitialLoad.current = true;
  }, [chatId, figure, addChat, t]);

  // Save messages to AsyncStorage
  const saveMessages = useCallback(
    async (updatedMessages: Message[]) => {
      try {
        // Ensure messages are unique and sorted as [new, ...old]
        const uniqueMsgsMap = new Map<string, Message>();
        updatedMessages.forEach(msg => {
          uniqueMsgsMap.set(msg.id, msg);
        });
        const uniqueMsgs = Array.from(uniqueMsgsMap.values()).sort((a, b) => b.timestamp - a.timestamp);

        await AsyncStorage.setItem(`chat_${chatId}_messages`, JSON.stringify(uniqueMsgs));
      } catch (error) {
        console.error('Mesajlar kaydedilirken hata oluştu:', error);
      }
    },
    [chatId]
  );

  // Add a unique pending AI message
  const addPendingAIMessage = () => {
    const pendingId = uuid.v4().toString(); // Generate unique ID
    pendingAIMessageIdsRef.current.push(pendingId); // Track pending AI message ID

    const pendingMessage: Message = {
      id: pendingId,
      text: '💬 Gelen yanıt bekleniyor...', // Placeholder text
      isUser: false,
      timestamp: Date.now(),
      status: 'pending',
    };
    LayoutAnimation.configureNext(LayoutAnimation.Presets.easeInEaseOut);
    setMessages(prevMessages => [pendingMessage, ...prevMessages]); // Prepend pending message
  };

  // Send message function
  const sendMessage = useCallback(
    async (text?: string) => {
      const messageText = text !== undefined ? text : inputText;
      if (messageText.trim() === '') return;

      // Coin kontrolü
      if (coins <= 0) {
        Alert.alert(
          'Yetersiz Coin',
          'Coin\'unuz tükenmiş. Daha fazla coin kazanmak için bir reklam izlemek ister misiniz?',
          [
            { text: 'İptal', style: 'cancel' },
            { text: 'Reklam İzle', onPress: showRewardedAd },
          ]
        );
        return;
      }

      const userMessage: Message = {
        id: uuid.v4().toString(),
        text: messageText,
        isUser: true,
        timestamp: Date.now(),
      };

      LayoutAnimation.configureNext(LayoutAnimation.Presets.easeInEaseOut);

      // Update messages state using functional updater to ensure latest state
      setMessages(prevMessages => {
        const updatedMessages = [userMessage, ...prevMessages];
        saveMessages(updatedMessages);
        return updatedMessages;
      });

      setInputText('');

      // Update chat and increment popularity
      await updateChat(chatId, userMessage);
      try {
        const figureDocRef = doc(db, 'figures', figure.id);
        await updateDoc(figureDocRef, {
          popularity: increment(1),
        });
        await incrementPopularity(figure.id);
      } catch (error) {
        console.error('Popülerlik güncellenirken hata oluştu:', error);
      }

      // Add pending AI message
      addPendingAIMessage();

      // Get the current messages including the new user message
      // Since setMessages is async, it's safer to get them from AsyncStorage
      const messagesData = await AsyncStorage.getItem(`chat_${chatId}_messages`);
      let currentMessages: Message[] = messagesData ? JSON.parse(messagesData) : [];
      // currentMessages are [new,...old], so to get all messages including pending ones
      // It would be better to use the latest state. But for safety, re-fetch.

      const apiMessages: APIMessage[] = [
        {
          role: 'system',
          content: figure.systemPrompt || 'Sen, yardımsever ve bilgilendirici bir yapay zeka asistanısın.',
        },
        ...currentMessages
          .reverse() // Reverse to be [old, ...new]
          .map((msg) => ({
            role: msg.isUser ? 'user' : 'assistant',
            content: msg.text,
          })),
      ];

      console.log('==== AI\'a Gönderilen Mesajlar ====');
      apiMessages.forEach((msg, index) => {
        console.log(`Mesaj ${index + 1}: [${msg.role}] ${msg.content}`);
      });
      console.log('===============================');

      try {
        const aiResponse = await fetchAIResponse(apiMessages, aiModel);

        const aiMessage: Message = {
          id: uuid.v4().toString(),
          text: aiResponse,
          isUser: false,
          timestamp: Date.now(),
          status: 'completed',
        };

        // Coin düşürme işlemi
        if (!text) {
          deductCoins(1);
        }

        // Replace the oldest pending AI message with the actual AI message
        setMessages(prevMessages => {
          const pendingId = pendingAIMessageIdsRef.current.shift(); // Get the first pending AI message ID
          if (!pendingId) {
            // No pending AI message found, cannot replace
            return prevMessages;
          }

          const updatedMessages = prevMessages.map(msg =>
            msg.id === pendingId && msg.status === 'pending'
              ? aiMessage
              : msg
          );

          saveMessages(updatedMessages);
          return updatedMessages;
        });

        await updateChat(chatId, aiMessage);
      } catch (error) {
        console.error('AI yanıtı alınırken hata oluştu:', error);
        Alert.alert(t('error'), t('errorFetchingAIResponse'));
        // Remove the pending AI message on error
        setMessages(prevMessages => {
          const pendingId = pendingAIMessageIdsRef.current.shift(); // Get the first pending AI message ID
          if (!pendingId) {
            // No pending AI message found, nothing to remove
            return prevMessages;
          }

          const filteredMessages = prevMessages.filter(msg => msg.id !== pendingId);
          saveMessages(filteredMessages);
          return filteredMessages;
        });
      } finally {
        // Scroll to the latest message
        flatListRef.current?.scrollToOffset({ animated: true, offset: 0 });
      }
    },
    [
      inputText,
      coins,
      showRewardedAd,
      deductCoins,
      saveMessages,
      updateChat,
      chatId,
      aiModel,
      figure,
      t,
      incrementPopularity,
    ]
  );

  // Render each message
  const renderMessageItem = useCallback(
    ({ item }: { item: Message }) => (
      <MessageItem
        message={item}
        onLongPress={() => {
          Clipboard.setString(item.text);
          Alert.alert(t('copied'), t('messageCopied'));
        }}
      />
    ),
    [t]
  );

  const keyExtractor = useCallback((item: Message) => item.id, []);

  // Scroll to the latest message when messages change
  useEffect(() => {
    if (messages.length > 0) {
      flatListRef.current?.scrollToOffset({ animated: true, offset: 0 });
    }
  }, [messages]);

  return (
    <KeyboardAvoidingView
      style={[styles.container, { backgroundColor: currentTheme.backgroundColor }]}
      behavior={Platform.OS === 'ios' ? 'padding' : undefined}
      keyboardVerticalOffset={Platform.OS === 'ios' ? 60 : 0}
    >
      {/* Header */}
      <View
        style={[
          styles.header,
          {
            backgroundColor: currentTheme.cardBackground,
            borderBottomColor: currentTheme.borderColor,
            paddingTop: Platform.OS === 'ios' ? 20 : 10,
          },
        ]}
      >
        <TouchableOpacity onPress={() => navigation.goBack()} style={styles.backButton}>
          <Ionicons name="arrow-back" size={28} color={currentTheme.textColor} />
        </TouchableOpacity>
        <Image source={{ uri: figure.image }} style={styles.headerAvatar} />
        <View style={styles.headerInfo}>
          <CustomText bold style={[styles.headerName, { color: currentTheme.textColor }]}>
            {figure.name}
          </CustomText>
          <CustomText style={[styles.headerDescription, { color: currentTheme.secondaryTextColor }]} numberOfLines={1}>
            {figure.description || t('noDescriptionAvailable')}
          </CustomText>
        </View>
        <View style={styles.coinContainer}>
          <Ionicons name="flash" size={20} color={currentTheme.accentColor} />
          <CustomText style={[styles.coinText, { color: currentTheme.textColor }]}>{coins}</CustomText>
          {/* Yeni Reklam İzle Butonu */}
          <TouchableOpacity
            onPress={showRewardedAd}
            style={styles.adButton}
          >
            <Ionicons name="videocam" size={24} color={currentTheme.accentColor} />
          </TouchableOpacity>
        </View>
      </View>

      {/* Message List */}
      <View style={styles.chatContainer}>
        {/* Message List or Loading */}
        {isLoading ? (
          <View style={styles.loadingContainer}>
            <ActivityIndicator size="large" color={currentTheme.accentColor} />
          </View>
        ) : (
          <FlatList
            ref={flatListRef}
            data={messages}
            renderItem={renderMessageItem}
            keyExtractor={keyExtractor}
            style={styles.messageList}
            contentContainerStyle={styles.messageListContent}
            inverted
          />
        )}
      </View>

      {/* Input Field */}
      <View
        style={[
          styles.inputContainer,
          {
            backgroundColor: currentTheme.cardBackground,
            borderTopColor: currentTheme.borderColor,
            paddingHorizontal: 15,
            paddingVertical: 10,
          },
        ]}
      >
        <TextInput
          style={[
            styles.input,
            {
              backgroundColor: currentTheme.inputBackground,
              color: currentTheme.textColor,
              borderColor: currentTheme.borderColor,
            },
          ]}
          value={inputText}
          onChangeText={setInputText}
          placeholder={t('writeYourMessage')}
          placeholderTextColor={currentTheme.placeholderTextColor}
          onSubmitEditing={() => sendMessage()}
          returnKeyType="send"
          multiline={true}
        />
        <TouchableOpacity
          onPress={() => sendMessage()}
          style={[
            styles.sendButton,
            { backgroundColor: currentTheme.accentColor },
            { shadowColor: currentTheme.shadowColor },
          ]}
        >
          <Ionicons name="send" size={24} color="#fff" />
        </TouchableOpacity>
      </View>
    </KeyboardAvoidingView>
  );
};

const styles = StyleSheet.create({
  backButton: {
    marginRight: 10,
  },
  container: {
    flex: 1,
  },
  header: {
    alignItems: 'center',
    borderBottomWidth: 1,
    flexDirection: 'row',
    padding: 15,
  },
  headerAvatar: {
    borderRadius: 20,
    height: 48,
    marginRight: 10,
    width: 48,
  },
  headerDescription: {
    fontFamily: 'Poppins_400Regular',
    fontSize: 14,
    marginTop: 2,
  },
  headerInfo: {
    flex: 1,
  },
  coinContainer: {
    flexDirection: 'row',
    alignItems: 'center',
    marginLeft: 'auto',
  },
  coinText: {
    fontFamily: 'Poppins_700Bold',
    fontSize: 18,
    marginLeft: 5,
  },
  headerName: {
    fontFamily: 'Poppins_700Bold',
    fontSize: 18,
  },
  chatContainer: {
    flex: 1,
  },
  messageList: {
    flex: 1,
    paddingTop: 10,
  },
  messageListContent: {
    paddingVertical: 10,
    paddingHorizontal: 15,
  },
  loadingContainer: {
    alignItems: 'center',
    flex: 1,
    justifyContent: 'center',
  },
  input: {
    borderRadius: 20,
    flex: 1,
    fontFamily: 'Poppins_400Regular',
    minHeight: 40,
    maxHeight: 100,
    marginRight: 10,
    paddingHorizontal: 15,
    paddingVertical: 10,
    borderWidth: 1,
  },
  inputContainer: {
    alignItems: 'center',
    borderTopWidth: 1,
    flexDirection: 'row',
  },
  sendButton: {
    borderRadius: 20,
    padding: 10,
    shadowOffset: {
      width: 0,
      height: 1,
    },
    shadowOpacity: 0.3,
    shadowRadius: 1.41,
    elevation: 2,
  },
  // Yeni Reklam İzle Butonu Stili
  adButton: {
    marginLeft: 10,
    padding: 5,
  },
});

export default ChatScreen;
// src/components/MessageItem.tsx

import React, { memo, useEffect, useRef, useState } from 'react';
import { View, StyleSheet, TouchableOpacity, Animated } from 'react-native';
import { Message } from '../types/types';
import Markdown from 'react-native-markdown-display';
import { useApp } from '../context/AppContext';

interface MessageItemProps {
  message: Message;
  onLongPress?: () => void;
}

const MessageItem: React.FC<MessageItemProps> = memo(({ message, onLongPress }) => {
  const { currentTheme } = useApp();
  const [timer, setTimer] = useState<number>(0);
  const timerRef = useRef<NodeJS.Timeout | null>(null);

  useEffect(() => {
    if (message.status === 'pending') {
      // Start timer
      timerRef.current = setInterval(() => {
        setTimer(prevTimer => prevTimer + 0.1);
      }, 100);

      return () => {
        if (timerRef.current) {
          clearInterval(timerRef.current);
        }
      };
    }
  }, [message.status]);

  useEffect(() => {
    if (message.status === 'pending' && timer >= 30) { // Optional: Max 30 seconds
      if (timerRef.current) {
        clearInterval(timerRef.current);
      }
    }
  }, [timer, message.status]);

  return (
    <View
      style={[
        styles.container,
        message.isUser ? styles.userContainer : styles.assistantContainer,
      ]}
    >
      <TouchableOpacity
        onLongPress={onLongPress}
        activeOpacity={0.7}
        style={[
          styles.messageBubble,
          message.isUser ? styles.userBubble : styles.assistantBubble,
          { backgroundColor: message.isUser ? currentTheme.accentColor : currentTheme.cardBackground },
          { shadowColor: currentTheme.shadowColor },
        ]}
      >
        {message.status === 'pending' ? (
          <Markdown
            style={{
              body: {
                fontSize: 16,
                fontFamily: 'Poppins_400Regular',
                color: message.isUser ? currentTheme.buttonTextColor : currentTheme.textColor,
              },
              strong: {
                fontFamily: 'Poppins_700Bold',
              },
              em: {
                fontFamily: 'Poppins_400Regular',
                fontStyle: 'italic',
              },
              // Other Markdown styles can be added here
            }}
          >
            {`💬 ${timer.toFixed(1)}s`}
          </Markdown>
        ) : (
          <Markdown
            style={{
              body: {
                fontSize: 16,
                fontFamily: 'Poppins_400Regular',
                color: message.isUser ? currentTheme.buttonTextColor : currentTheme.textColor,
              },
              strong: {
                fontFamily: 'Poppins_700Bold',
              },
              em: {
                fontFamily: 'Poppins_400Regular',
                fontStyle: 'italic',
              },
              // Other Markdown styles can be added here
            }}
          >
            {message.text}
          </Markdown>
        )}
      </TouchableOpacity>
    </View>
  );
});

MessageItem.displayName = 'MessageItem';

const styles = StyleSheet.create({
  assistantBubble: {
    borderTopLeftRadius: 0,
  },
  assistantContainer: {
    justifyContent: 'flex-start',
    paddingRight: 0,
    alignSelf: 'flex-start',
  },
  container: {
    flexDirection: 'row',
    marginVertical: 4,
    paddingHorizontal: 10,
  },
  messageBubble: {
    borderRadius: 16,
    maxWidth: '80%',
    paddingHorizontal: 12,
    paddingVertical: 8,
    shadowOffset: {
      width: 0,
      height: 1,
    },
    shadowOpacity: 0.2,
    shadowRadius: 1.41,
    elevation: 2,
  },
  userBubble: {
    borderTopRightRadius: 0,
  },
  userContainer: {
    justifyContent: 'flex-end',
    paddingLeft: 0,
    alignSelf: 'flex-end',
  },
});

export default MessageItem;
hatayı düzelt ve kodları eksiksiz bir şekilde geri gönder. ayrıca daha performanslı hale getirebileceğin şeyler varsa onu da yap. gereksiz kodlar varsa onları da kaldırabilirsin.