import React, { createContext, useContext, useReducer, useEffect } from 'react';
import { 
  login as apiLogin, 
  register as apiRegister, 
  logout as apiLogout, 
  getCurrentUser,
  isAuthenticated,
  setTokens,
  clearTokens,
  getAccessToken,
  getUserFeaturePreferences,
  setUserFeaturePreference,
  saveUserProject
} from '../services/api';

// Initial state
const initialState = {
  user: null,
  isAuthenticated: false,
  isLoading: true,
  error: null,
  featurePreferences: {},
  userProjects: []
};

// Action types
const actionTypes = {
  SET_LOADING: 'SET_LOADING',
  SET_USER: 'SET_USER',
  SET_ERROR: 'SET_ERROR',
  CLEAR_ERROR: 'CLEAR_ERROR',
  LOGOUT: 'LOGOUT',
  SET_FEATURE_PREFERENCES: 'SET_FEATURE_PREFERENCES',
  UPDATE_FEATURE_PREFERENCE: 'UPDATE_FEATURE_PREFERENCE',
  SET_USER_PROJECTS: 'SET_USER_PROJECTS',
  ADD_USER_PROJECT: 'ADD_USER_PROJECT'
};

// Reducer
const authReducer = (state, action) => {
  switch (action.type) {
    case actionTypes.SET_LOADING:
      return {
        ...state,
        isLoading: action.payload
      };

    case actionTypes.SET_USER:
      return {
        ...state,
        user: action.payload,
        isAuthenticated: !!action.payload,
        isLoading: false,
        error: null
      };

    case actionTypes.SET_ERROR:
      return {
        ...state,
        error: action.payload,
        isLoading: false
      };

    case actionTypes.CLEAR_ERROR:
      return {
        ...state,
        error: null
      };

    case actionTypes.LOGOUT:
      return {
        ...initialState,
        isLoading: false
      };

    case actionTypes.SET_FEATURE_PREFERENCES:
      return {
        ...state,
        featurePreferences: {
          ...state.featurePreferences,
          [action.payload.templateType]: action.payload.preferences
        }
      };

    case actionTypes.UPDATE_FEATURE_PREFERENCE:
      const { templateType, featureId, preference } = action.payload;
      const currentPrefs = state.featurePreferences[templateType] || [];
      const updatedPrefs = currentPrefs.filter(p => p.feature_id !== featureId);
      if (preference) {
        updatedPrefs.push(preference);
      }
      
      return {
        ...state,
        featurePreferences: {
          ...state.featurePreferences,
          [templateType]: updatedPrefs
        }
      };

    case actionTypes.SET_USER_PROJECTS:
      return {
        ...state,
        userProjects: action.payload
      };

    case actionTypes.ADD_USER_PROJECT:
      return {
        ...state,
        userProjects: [action.payload, ...state.userProjects]
      };

    default:
      return state;
  }
};

// Create context
const AuthContext = createContext();

// Auth provider component
export const AuthProvider = ({ children }) => {
  const [state, dispatch] = useReducer(authReducer, initialState);

  // Initialize authentication state on app load
  useEffect(() => {
    const initializeAuth = async () => {
      try {
        dispatch({ type: actionTypes.SET_LOADING, payload: true });

        if (isAuthenticated()) {
          console.log('🔑 Found existing token, verifying...');
          const userData = await getCurrentUser();
          dispatch({ type: actionTypes.SET_USER, payload: userData.user });
          console.log('✅ User authenticated:', userData.user.email);
        } else {
          console.log('🔓 No authentication token found');
          dispatch({ type: actionTypes.SET_LOADING, payload: false });
        }
      } catch (error) {
        console.error('❌ Auth initialization failed:', error);
        // Clear invalid tokens
        clearTokens();
        dispatch({ type: actionTypes.LOGOUT });
      }
    };

    initializeAuth();
  }, []);

  // Login function
  const login = async (credentials) => {
    try {
      dispatch({ type: actionTypes.SET_LOADING, payload: true });
      dispatch({ type: actionTypes.CLEAR_ERROR });

      console.log('🔑 Attempting login...');
      const result = await apiLogin(credentials);
      
      dispatch({ type: actionTypes.SET_USER, payload: result.user });
      console.log('✅ Login successful:', result.user.email);
      
      return result;
    } catch (error) {
      console.error('❌ Login failed:', error);
      dispatch({ type: actionTypes.SET_ERROR, payload: error.message });
      throw error;
    }
  };

  // Register function
  const register = async (userData) => {
    try {
      dispatch({ type: actionTypes.SET_LOADING, payload: true });
      dispatch({ type: actionTypes.CLEAR_ERROR });

      console.log('👤 Attempting registration...');
      const result = await apiRegister(userData);
      
      console.log('✅ Registration successful:', result.user.email);
      
      // Auto-login after registration
      await login({ email: userData.email, password: userData.password });
      
      return result;
    } catch (error) {
      console.error('❌ Registration failed:', error);
      dispatch({ type: actionTypes.SET_ERROR, payload: error.message });
      throw error;
    }
  };

  // Logout function
  const logout = async () => {
    try {
      console.log('🚪 Logging out...');
      await apiLogout();
      dispatch({ type: actionTypes.LOGOUT });
      console.log('✅ Logout successful');
    } catch (error) {
      console.error('❌ Logout failed:', error);
      // Force logout even if API call fails
      dispatch({ type: actionTypes.LOGOUT });
    }
  };

  // Load user feature preferences for a template
  const loadFeaturePreferences = async (templateType) => {
    try {
      if (!state.isAuthenticated) {
        console.log('🔓 Not authenticated, skipping preference load');
        return [];
      }

      console.log(`📋 Loading feature preferences for: ${templateType}`);
      const result = await getUserFeaturePreferences(templateType);
      
      dispatch({ 
        type: actionTypes.SET_FEATURE_PREFERENCES, 
        payload: {
          templateType: result.templateType,
          preferences: result.preferences
        }
      });

      return result.preferences;
    } catch (error) {
      console.error('❌ Failed to load feature preferences:', error);
      return [];
    }
  };

  // Set feature preference (remove/add/customize)
  const setFeaturePreference = async (templateType, featureId, preferenceType, customData = null) => {
    try {
      if (!state.isAuthenticated) {
        console.log('🔓 Not authenticated, preference not saved');
        return null;
      }

      console.log(`🎯 Setting preference: ${preferenceType} ${featureId} in ${templateType}`);
      const preference = await setUserFeaturePreference(templateType, featureId, preferenceType, customData);
      
      dispatch({
        type: actionTypes.UPDATE_FEATURE_PREFERENCE,
        payload: {
          templateType,
          featureId,
          preference
        }
      });

      return preference;
    } catch (error) {
      console.error('❌ Failed to set feature preference:', error);
      throw error;
    }
  };

  // Remove feature preference
  const removeFeaturePreference = async (templateType, featureId) => {
    try {
      if (!state.isAuthenticated) {
        console.log('🔓 Not authenticated, preference not removed');
        return;
      }

      console.log(`🗑️ Removing preference: ${featureId} in ${templateType}`);
      
      dispatch({
        type: actionTypes.UPDATE_FEATURE_PREFERENCE,
        payload: {
          templateType,
          featureId,
          preference: null // Remove preference
        }
      });
    } catch (error) {
      console.error('❌ Failed to remove feature preference:', error);
    }
  };

  // Save user project
  const saveProject = async (projectData) => {
    try {
      if (!state.isAuthenticated) {
        console.log('🔓 Not authenticated, project not saved');
        return null;
      }

      console.log('💾 Saving user project:', projectData.project_name);
      const project = await saveUserProject(projectData);
      
      dispatch({
        type: actionTypes.ADD_USER_PROJECT,
        payload: project
      });

      return project;
    } catch (error) {
      console.error('❌ Failed to save project:', error);
      throw error;
    }
  };

  // Get user's removed features for a template
  const getRemovedFeatures = (templateType) => {
    const preferences = state.featurePreferences[templateType] || [];
    return preferences
      .filter(pref => pref.preference_type === 'removed')
      .map(pref => pref.feature_id);
  };

  // Check if a feature is removed by the user
  const isFeatureRemoved = (templateType, featureId) => {
    const removedFeatures = getRemovedFeatures(templateType);
    return removedFeatures.includes(featureId);
  };

  // Filter features based on user preferences
  const filterFeaturesForUser = (templateType, features) => {
    if (!state.isAuthenticated) {
      return features; // Return all features for non-authenticated users
    }

    const removedFeatures = getRemovedFeatures(templateType);
    return features.filter(feature => !removedFeatures.includes(feature.id));
  };

  // Clear error
  const clearError = () => {
    dispatch({ type: actionTypes.CLEAR_ERROR });
  };

  // Context value
  const value = {
    // State
    user: state.user,
    isAuthenticated: state.isAuthenticated,
    isLoading: state.isLoading,
    error: state.error,
    featurePreferences: state.featurePreferences,
    userProjects: state.userProjects,

    // Actions
    login,
    register,
    logout,
    clearError,

    // Feature preferences
    loadFeaturePreferences,
    setFeaturePreference,
    removeFeaturePreference,
    getRemovedFeatures,
    isFeatureRemoved,
    filterFeaturesForUser,

    // Projects
    saveProject,

    // Utilities
    isAuth: state.isAuthenticated,
    currentUser: state.user
  };

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

// Custom hook to use auth context
export const useAuth = () => {
  const context = useContext(AuthContext);
  if (!context) {
    throw new Error('useAuth must be used within an AuthProvider');
  }
  return context;
};

// HOC for protected components
export const withAuth = (Component) => {
  return function AuthenticatedComponent(props) {
    const { isAuthenticated, isLoading } = useAuth();

    if (isLoading) {
      return (
        <div className="flex items-center justify-center min-h-screen">
          <div className="animate-spin rounded-full h-12 w-12 border-b-2 border-blue-600"></div>
        </div>
      );
    }

    if (!isAuthenticated) {
      return (
        <div className="flex items-center justify-center min-h-screen">
          <div className="text-center">
            <h2 className="text-xl font-semibold text-gray-900 mb-4">
              Authentication Required
            </h2>
            <p className="text-gray-600">
              Please log in to access this feature.
            </p>
          </div>
        </div>
      );
    }

    return <Component {...props} />;
  };
};

export default AuthContext;