import React, { createContext, useContext, useEffect, useState } from 'react';
import { io, Socket } from 'socket.io-client';
import { useSelector } from 'react-redux';
import { RootState } from '../store';

interface SocketContextType {
    socket: Socket | null;
    isConnected: boolean;
}

const SocketContext = createContext<SocketContextType>({
    socket: null,
    isConnected: false
});

export const useSocket = () => useContext(SocketContext);

export const SocketProvider: React.FC<{ children: React.ReactNode }> = ({ children }) => {
    const [socket, setSocket] = useState<Socket | null>(null);
    const [isConnected, setIsConnected] = useState(false);

    const { user: currentUser } = useSelector((state: RootState) => state.auth);

    useEffect(() => {
        let socketUrl = (import.meta as any).env.VITE_API_URL || 'http://localhost:5000';

        // If URL ends with /api, strip it as Socket.io usually connects to the root
        if (socketUrl.endsWith('/api')) {
            socketUrl = socketUrl.replace(/\/api$/, '');
        }

        const newSocket = io(socketUrl, {
            withCredentials: true
        });

        newSocket.on('connect', () => {
            console.log('Socket connected:', newSocket.id);
            setIsConnected(true);
        });

        newSocket.on('disconnect', () => {
            console.log('Socket disconnected');
            setIsConnected(false);
        });

        setSocket(newSocket);

        return () => {
            newSocket.close();
        };
    }, []);

    // Join personal room for notifications
    useEffect(() => {
        if (socket && isConnected && currentUser?.id) {
            socket.emit('join_room', `user_${currentUser.id}`);
            console.log(`Joined private notification room: user_${currentUser.id}`);

            return () => {
                socket.emit('leave_room', `user_${currentUser.id}`);
            };
        }
    }, [socket, isConnected, currentUser?.id]);

    return (
        <SocketContext.Provider value={{ socket, isConnected }}>
            {children}
        </SocketContext.Provider>
    );
};
