import React, { createContext, useContext, useState, useEffect, useCallback } from 'react';
import { getFriends, sendFriendRequest, acceptFriendRequest, deleteFriendRequest, removeFriend, searchUsers, Friend, FriendRequest } from '@/services/friends';

interface FriendsContextType {
  friends: Friend[];
  incoming: FriendRequest[];
  outgoing: FriendRequest[];
  loading: boolean;
  error: string | null;
  refresh: () => Promise<void>;
  sendRequest: (username: string) => Promise<void>;
  acceptRequest: (requestId: string) => Promise<void>;
  declineRequest: (requestId: string) => Promise<void>;
  removeFriend: (friendId: string) => Promise<void>;
  searchUsers: (query: string) => Promise<Friend[]>;
}

const FriendsContext = createContext<FriendsContextType | null>(null);

export function FriendsProvider({ children }: { children: React.ReactNode }) {
  const [friends, setFriends] = useState<Friend[]>([]);
  const [incoming, setIncoming] = useState<FriendRequest[]>([]);
  const [outgoing, setOutgoing] = useState<FriendRequest[]>([]);
  const [loading, setLoading] = useState(true);
  const [error, setError] = useState<string | null>(null);

  const fetchFriends = useCallback(async () => {
    try {
      setLoading(true);
      setError(null);
      const data = await getFriends();
      setFriends(data.friends);
      setIncoming(data.incoming);
      setOutgoing(data.outgoing);
    } catch (err) {
      setError(err instanceof Error ? err.message : 'Failed to load friends');
    } finally {
      setLoading(false);
    }
  }, []);

  useEffect(() => {
    // eslint-disable-next-line react-hooks/set-state-in-effect
    fetchFriends();
  }, [fetchFriends]);

  const sendRequest = async (username: string) => {
    await sendFriendRequest(username);
    await fetchFriends();
  };

  const acceptRequest = async (requestId: string) => {
    await acceptFriendRequest(requestId);
    await fetchFriends();
  };

  const declineRequest = async (requestId: string) => {
    await deleteFriendRequest(requestId);
    await fetchFriends();
  };

  const handleRemoveFriend = async (friendId: string) => {
    await removeFriend(friendId);
    await fetchFriends();
  };

  const handleSearchUsers = async (query: string) => {
    return searchUsers(query);
  };

  return (
    <FriendsContext.Provider
      value={{
        friends,
        incoming,
        outgoing,
        loading,
        error,
        refresh: fetchFriends,
        sendRequest,
        acceptRequest,
        declineRequest,
        removeFriend: handleRemoveFriend,
        searchUsers: handleSearchUsers,
      }}
    >
      {children}
    </FriendsContext.Provider>
  );
}

export function useFriends(): FriendsContextType {
  const context = useContext(FriendsContext);
  if (!context) {
    throw new Error('useFriends must be used within a FriendsProvider');
  }
  return context;
}