/**
 * AeThex Provider
 * Main context provider for AeThex Connect - handles auth, chat, and real-time features
 */

import React, { createContext, useContext, useState, useEffect, useCallback } from 'react';
import { io } from 'socket.io-client';

const API_URL = import.meta.env?.VITE_API_URL || 'http://localhost:5000';
const API_BASE = `${API_URL}/api`;

const AeThexContext = createContext(null);

export function useAeThex() {
  return useContext(AeThexContext);
}

export function AeThexProvider({ children }) {
  // Auth state
  const [user, setUser] = useState(null);
  const [token, setTokenState] = useState(null);
  const [loading, setLoading] = useState(true);
  const [error, setError] = useState(null);

  // Socket state
  const [socket, setSocket] = useState(null);
  const [connected, setConnected] = useState(false);

  // Chat state
  const [servers, setServers] = useState([]);
  const [channels, setChannels] = useState([]);
  const [messages, setMessages] = useState([]);
  const [currentServer, setCurrentServer] = useState(null);
  const [currentChannel, setCurrentChannel] = useState(null);
  const [onlineUsers, setOnlineUsers] = useState([]);

  // Token management
  const setToken = useCallback((newToken) => {
    setTokenState(newToken);
    if (newToken) {
      localStorage.setItem('aethex_token', newToken);
    } else {
      localStorage.removeItem('aethex_token');
    }
  }, []);

  // API request helper
  const apiRequest = useCallback(async (endpoint, options = {}) => {
    const headers = {
      'Content-Type': 'application/json',
      ...options.headers,
    };

    const currentToken = token || localStorage.getItem('aethex_token');
    if (currentToken) {
      headers['Authorization'] = `Bearer ${currentToken}`;
    }

    const response = await fetch(`${API_BASE}${endpoint}`, {
      ...options,
      headers,
    });

    const data = await response.json();
    if (!response.ok) {
      throw new Error(data.error || 'Request failed');
    }
    return data;
  }, [token]);

  // Auth functions
  const login = useCallback(async (email, password) => {
    setError(null);
    setLoading(true);
    try {
      const response = await apiRequest('/auth/login', {
        method: 'POST',
        body: JSON.stringify({ email, password }),
      });
      if (response.success) {
        setToken(response.data.token);
        setUser(response.data.user);
        return { success: true };
      }
      throw new Error(response.error || 'Login failed');
    } catch (err) {
      setError(err.message);
      return { success: false, error: err.message };
    } finally {
      setLoading(false);
    }
  }, [apiRequest, setToken]);

  const register = useCallback(async (email, password, username, displayName) => {
    setError(null);
    setLoading(true);
    try {
      const response = await apiRequest('/auth/register', {
        method: 'POST',
        body: JSON.stringify({ email, password, username, displayName }),
      });
      if (response.success) {
        setToken(response.data.token);
        setUser(response.data.user);
        return { success: true };
      }
      throw new Error(response.error || 'Registration failed');
    } catch (err) {
      setError(err.message);
      return { success: false, error: err.message };
    } finally {
      setLoading(false);
    }
  }, [apiRequest, setToken]);

  const demoLogin = useCallback(async () => {
    setError(null);
    setLoading(true);
    try {
      const response = await apiRequest('/auth/demo', {
        method: 'POST',
      });
      if (response.success) {
        setToken(response.data.token);
        setUser(response.data.user);
        return { success: true };
      }
      throw new Error(response.error || 'Demo login failed');
    } catch (err) {
      setError(err.message);
      return { success: false, error: err.message };
    } finally {
      setLoading(false);
    }
  }, [apiRequest, setToken]);

  const logout = useCallback(() => {
    setToken(null);
    setUser(null);
    if (socket) {
      socket.disconnect();
      setSocket(null);
    }
    setConnected(false);
  }, [socket, setToken]);

  // Socket connection
  const connectSocket = useCallback((authToken) => {
    if (socket) {
      socket.disconnect();
    }

    const newSocket = io(API_URL, {
      auth: { token: authToken },
      reconnection: true,
      reconnectionDelay: 1000,
      reconnectionAttempts: 10,
      transports: ['websocket', 'polling']
    });

    newSocket.on('connect', () => {
      console.log('✓ Connected to AeThex Connect');
      setConnected(true);
    });

    newSocket.on('disconnect', () => {
      console.log('✗ Disconnected from AeThex Connect');
      setConnected(false);
    });

    newSocket.on('message:new', (message) => {
      setMessages(prev => [...prev, message]);
    });

    newSocket.on('presence:online', (users) => {
      setOnlineUsers(users);
    });

    setSocket(newSocket);
    return newSocket;
  }, [socket]);

  // Chat functions
  const sendMessage = useCallback((content) => {
    if (!socket || !connected || !currentChannel) return;
    socket.emit('channel:message', {
      channelId: currentChannel.id,
      content
    });
  }, [socket, connected, currentChannel]);

  const joinChannel = useCallback((channelId) => {
    if (!socket || !connected) return;
    socket.emit('channel:join', { channelId });
  }, [socket, connected]);

  // Check auth on mount
  useEffect(() => {
    const checkAuth = async () => {
      const storedToken = localStorage.getItem('aethex_token');
      if (storedToken) {
        setTokenState(storedToken);
        try {
          const response = await fetch(`${API_BASE}/auth/me`, {
            headers: { 'Authorization': `Bearer ${storedToken}` }
          });
          const data = await response.json();
          if (data.success) {
            setUser(data.data);
            connectSocket(storedToken);
          } else {
            localStorage.removeItem('aethex_token');
          }
        } catch (err) {
          console.error('Auth check failed:', err);
          localStorage.removeItem('aethex_token');
        }
      }
      setLoading(false);
    };

    checkAuth();

    return () => {
      if (socket) {
        socket.disconnect();
      }
    };
  }, []);

  // Connect socket when user logs in
  useEffect(() => {
    if (user && token && !socket) {
      connectSocket(token);
    }
  }, [user, token]);

  const value = {
    // Auth
    user,
    loading,
    error,
    isAuthenticated: !!user,
    login,
    register,
    demoLogin,
    logout,

    // Socket
    socket,
    connected,

    // Chat
    servers,
    channels,
    messages,
    currentServer,
    currentChannel,
    onlineUsers,
    setCurrentServer,
    setCurrentChannel,
    setMessages,
    sendMessage,
    joinChannel,

    // API helper
    apiRequest
  };

  return (
    <AeThexContext.Provider value={value}>
      {children}
    </AeThexContext.Provider>
  );
}
