import React, { createContext, useContext, useState, useEffect, useCallback } from 'react';
import { walletAPI } from '../api/wallet';

const WalletContext = createContext();

export const useWallet = () => {
  const context = useContext(WalletContext);
  if (!context) {
    throw new Error('useWallet must be used within WalletProvider');
  }
  return context;
};

export const WalletProvider = ({ children }) => {
  const [sessionLogin, setSessionLogin] = useState(null);
  const [activeWallet, setActiveWallet] = useState(null);
  const [userSessionWalletList, setUserSessionWalletList] = useState([]);
  const [userId, setUserId] = useState(null);
  const [loading, setLoading] = useState(false);
  const [error, setError] = useState(null);

  const loadSession = useCallback(async (sessionLoginValue) => {
    try {
      setLoading(true);
      setError(null);
      const data = await walletAPI.getSession(sessionLoginValue);
      
      if (data.success) {
        setSessionLogin(sessionLoginValue);
        setActiveWallet(data.data.activeWallet);
        setUserSessionWalletList(data.data.userSessionWalletList || []);
        setUserId(data.data.userId);
        localStorage.setItem('sessionLogin', sessionLoginValue);
      } else {
        throw new Error('Session not found');
      }
    } catch (err) {
      console.error('Failed to load session:', err);
      setError(err.message);
      throw err; // Пробрасываем ошибку для обработки в useEffect
    } finally {
      setLoading(false);
    }
  }, []);

  useEffect(() => {
    const autoLogin = async () => {
      const savedSessionLogin = localStorage.getItem('sessionLogin');
      
      if (savedSessionLogin) {
        try {
          // Попробуем загрузить существующую сессию
          await loadSession(savedSessionLogin);
        } catch (error) {
          // Если сессия не найдена, очищаем localStorage
          console.log('[AutoLogin] Session not found, clearing saved data');
          localStorage.removeItem('sessionLogin');
          localStorage.removeItem('userPassword');
          localStorage.removeItem('userMnemonic');
        }
      }
    };
    
    autoLogin();
  }, [loadSession]);

  const login = async (mnemonic, password, username, isImport = false) => {
    try {
      setLoading(true);
      setError(null);
      
      // Валидация входных данных
      if (!mnemonic || !password || !username) {
        const error = 'Не все обязательные поля заполнены';
        setError(error);
        return { success: false, error };
      }
      
      if (password.length < 8) {
        const error = 'Пароль должен содержать минимум 8 символов';
        setError(error);
        return { success: false, error };
      }
      
      const data = await walletAPI.initSession(mnemonic, password, username, isImport);
      
      if (data.success) {
        const sessionLoginValue = data.data.sessionLogin;
        
        // Сохраняем в sessionStorage для автовхода после перезагрузки (безопаснее)
        sessionStorage.setItem(`password_${sessionLoginValue}`, password);
        sessionStorage.setItem(`mnemonic_${sessionLoginValue}`, mnemonic);
        
        await loadSession(sessionLoginValue);
        return { success: true };
      }
      
      // Обработка различных типов ошибок от сервера
      let errorMessage = 'Ошибка входа';
      if (data.error) {
        if (data.error.includes('Слишком много попыток')) {
          errorMessage = 'Превышено количество попыток входа. Попробуйте через 15 минут.';
        } else if (data.error.includes('Неверная мнемоника')) {
          errorMessage = 'Неверная мнемоническая фраза. Проверьте правильность ввода.';
        } else if (data.error.includes('Неверный пароль')) {
          errorMessage = 'Неверный пароль. Попробуйте еще раз.';
        } else {
          errorMessage = data.error;
        }
      }
      
      setError(errorMessage);
      return { success: false, error: errorMessage };
    } catch (err) {
      console.error('Login error:', err);
      
      // Обработка сетевых ошибок
      let errorMessage = 'Ошибка подключения к серверу';
      if (err.code === 'NETWORK_ERROR' || err.message.includes('Network Error')) {
        errorMessage = 'Проблемы с подключением к интернету. Проверьте соединение.';
      } else if (err.response?.status === 429) {
        errorMessage = 'Слишком много запросов. Подождите немного и попробуйте снова.';
      } else if (err.response?.status >= 500) {
        errorMessage = 'Временные проблемы с сервером. Попробуйте позже.';
      } else if (err.message) {
        errorMessage = err.message;
      }
      
      setError(errorMessage);
      return { success: false, error: errorMessage };
    } finally {
      setLoading(false);
    }
  };

  const createNewWallet = async () => {
    try {
      setLoading(true);
      setError(null);
      const data = await walletAPI.createNewAccount();
      return { success: true, data };
    } catch (err) {
      console.error('Create wallet error:', err);
      setError(err.message);
      return { success: false, error: err.message };
    } finally {
      setLoading(false);
    }
  };

  const switchWallet = async (mnemonic, walletIndex) => {
    try {
      setLoading(true);
      setError(null);
      const data = await walletAPI.changeActiveWallet(
        sessionLogin,
        mnemonic,
        walletIndex
      );
      
      if (data.success) {
        await loadSession(sessionLogin);
        return { success: true };
      }
      return { success: false, error: 'Switch wallet failed' };
    } catch (err) {
      console.error('Switch wallet error:', err);
      setError(err.message);
      return { success: false, error: err.message };
    } finally {
      setLoading(false);
    }
  };

  const logout = () => {
    setSessionLogin(null);
    setActiveWallet(null);
    setUserSessionWalletList([]);
    setUserId(null);
    
    // Очищаем localStorage
    localStorage.removeItem('sessionLogin');
    localStorage.removeItem('userPassword');
    localStorage.removeItem('userMnemonic');
    
    // Очищаем sessionStorage
    const sessionLoginValue = sessionLogin;
    if (sessionLoginValue) {
      sessionStorage.removeItem(`password_${sessionLoginValue}`);
      sessionStorage.removeItem(`mnemonic_${sessionLoginValue}`);
    }
    
    // Очищаем все sessionStorage ключи, связанные с сессиями
    Object.keys(sessionStorage).forEach(key => {
      if (key.startsWith('password_') || key.startsWith('mnemonic_')) {
        sessionStorage.removeItem(key);
      }
    });
  };

  const refreshSession = useCallback(async () => {
    if (sessionLogin) {
      await loadSession(sessionLogin);
    }
  }, [sessionLogin, loadSession]);

  const addWalletToCurrentSession = async (mnemonic, password, isImport = false) => {
    try {
      setLoading(true);
      setError(null);
      const data = await walletAPI.initSession(mnemonic, password, sessionLogin, isImport);
      
      if (data.success) {
        await loadSession(sessionLogin);
        return { success: true };
      }
      return { success: false, error: 'Failed to add wallet' };
    } catch (err) {
      console.error('Add wallet error:', err);
      setError(err.message);
      return { success: false, error: err.message };
    } finally {
      setLoading(false);
    }
  };

  const deleteWallet = async (mnemonic) => {
    try {
      setLoading(true);
      setError(null);
      const data = await walletAPI.deleteWalletFromSession(sessionLogin, mnemonic);
      
      if (data.ok || data.success) {
        await loadSession(sessionLogin);
        return { success: true };
      }
      return { success: false, error: 'Failed to delete wallet' };
    } catch (err) {
      console.error('Delete wallet error:', err);
      setError(err.message);
      return { success: false, error: err.message };
    } finally {
      setLoading(false);
    }
  };

  const value = {
    sessionLogin,
    activeWallet,
    userSessionWalletList,
    userId,
    loading,
    error,
    login,
    logout,
    createNewWallet,
    switchWallet,
    refreshSession,
    addWalletToCurrentSession,
    deleteWallet,
    isAuthenticated: !!sessionLogin
  };

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

export default WalletContext;
