import React, { createContext, useContext, useState, ReactNode, useEffect } from 'react';
import { AuthUser, USER_ROLES, hasPermission, hasAnyPermission, hasAllPermissions } from '../types';
import { authApi, tokenManager } from '../services/api';

interface AuthContextType {
  user: AuthUser | null;
  login: (email: string, password: string) => Promise<boolean>;
  logout: () => void;
  isAuthenticated: boolean;
  hasRole: (requiredRole: string) => boolean;
  isSuperAdmin: () => boolean;
  isAdmin: () => boolean;
  isUser: () => boolean;
  hasPermission: (permission: string) => boolean;
  hasAnyPermission: (permissions: string[]) => boolean;
  hasAllPermissions: (permissions: string[]) => boolean;
  isLoading: boolean;
  error: string | null;
}

const AuthContext = createContext<AuthContextType | undefined>(undefined);

export const useAuth = () => {
  const context = useContext(AuthContext);
  if (context === undefined) {
    throw new Error('useAuth must be used within an AuthProvider');
  }
  return context;
};

interface AuthProviderProps {
  children: ReactNode;
}

export const AuthProvider: React.FC<AuthProviderProps> = ({ children }) => {
  const [user, setUser] = useState<AuthUser | null>(null);
  const [isLoading, setIsLoading] = useState(true); // Start with loading true
  const [error, setError] = useState<string | null>(null);

  // Check for existing token on mount
  useEffect(() => {
    const initializeAuth = async () => {
      const token = tokenManager.getToken();
      if (token && !tokenManager.isTokenExpired(token)) {
        // Token exists and is valid, fetch user profile
        await fetchUserProfile();
      } else {
        // Token is expired or doesn't exist, clear it
        tokenManager.clearTokens();
        setUser(null);
      }
      setIsLoading(false); // Set loading to false after initialization
    };
    
    initializeAuth();
  }, []);

  const fetchUserProfile = async () => {
    try {
      const response = await authApi.getProfile();
      if (response.status === 'success' && response.data) {
        console.log('🔍 AuthContext: User profile fetched:', {
          name: response.data.user.name,
          role: response.data.user.role,
          permissions: response.data.user.permissions,
          permissionCount: response.data.user.permissions.length
        });
        setUser(response.data.user);
      }
    } catch (error) {
      console.error('Failed to fetch user profile:', error);
      tokenManager.clearTokens();
      setUser(null);
    }
  };

  const login = async (loginId: string, password: string): Promise<boolean> => {
    setIsLoading(true);
    setError(null);

    try {
      const response = await authApi.login({ login_id: loginId, password });
      
      if (response.status === 'success' && response.data) {
        // Store tokens
        tokenManager.setTokens(response.data.token, response.data.refreshToken);
        
        console.log('🔍 AuthContext: Login successful:', {
          name: response.data.user.name,
          role: response.data.user.role,
          permissions: response.data.user.permissions,
          permissionCount: response.data.user.permissions.length
        });
        
        // Set user data
        setUser(response.data.user);
        return true;
      } else {
        setError(response.message || 'Login failed');
        return false;
      }
    } catch (error: any) {
      setError(error.message || 'Login failed. Please try again.');
      return false;
    } finally {
      setIsLoading(false);
    }
  };

  const logout = async () => {
    try {
      // Call logout API if available
      await authApi.logout();
    } catch (error) {
      console.error('Logout API call failed:', error);
    } finally {
      // Clear local state and tokens
      setUser(null);
      tokenManager.clearTokens();
    }
  };

  // Role checking functions
  const hasRole = (requiredRole: string): boolean => {
    if (!user) return false;
    
    // Super Admin has full access to everything
    if (user?.role === 'Super Admin' || user?.role === USER_ROLES.SUPER_ADMIN || user?.email === 's_admin@gmail.com') {
      return true;
    }
    
    const roleHierarchy: { [key: string]: number } = {
      'Super Admin': 3,
      'Super_admin': 3,
      'Admin': 2,
      'User': 1,
    };
    
    // Convert requiredRole to match actual role names
    const normalizedRequiredRole = requiredRole === USER_ROLES.ADMIN ? 'Admin' : 
                                  requiredRole === USER_ROLES.SUPER_ADMIN ? 'Super Admin' :
                                  requiredRole === USER_ROLES.USER ? 'User' : requiredRole;
    
    const result = (roleHierarchy[user.role] || 0) >= (roleHierarchy[normalizedRequiredRole] || 0);
    
    return result;
  };

  const isSuperAdmin = (): boolean => {
    // Super Admin has full system access - always return true for Super Admin
    if (user?.role === 'Super Admin' || user?.role === USER_ROLES.SUPER_ADMIN || user?.email === 's_admin@gmail.com') {
      return true;
    }
    return false;
  };

  const isAdmin = (): boolean => {
    return user?.role === 'Admin' || user?.role === 'Super Admin' || user?.role === USER_ROLES.ADMIN || user?.role === USER_ROLES.SUPER_ADMIN;
  };

  const isUser = (): boolean => {
    return user?.role === USER_ROLES.USER;
  };

  // Permission checking methods
  const hasPermissionCheck = (permission: string): boolean => {
    // Super Admin has full system access
    if (user?.role === 'Super Admin' || user?.role === USER_ROLES.SUPER_ADMIN || user?.email === 's_admin@gmail.com') {
      return true;
    }
    return user ? hasPermission(user, permission) : false;
  };

  const hasAnyPermissionCheck = (permissions: string[]): boolean => {
    // Super Admin has full system access
    if (user?.role === 'Super Admin' || user?.role === USER_ROLES.SUPER_ADMIN || user?.email === 's_admin@gmail.com') {
      return true;
    }
    return user ? hasAnyPermission(user, permissions) : false;
  };

  const hasAllPermissionsCheck = (permissions: string[]): boolean => {
    // Super Admin has full system access
    if (user?.role === 'Super Admin' || user?.role === USER_ROLES.SUPER_ADMIN || user?.email === 's_admin@gmail.com') {
      return true;
    }
    return user ? hasAllPermissions(user, permissions) : false;
  };

  const value = {
    user,
    login,
    logout,
    isAuthenticated: !!user,
    hasRole,
    isSuperAdmin,
    isAdmin,
    isUser,
    hasPermission: hasPermissionCheck,
    hasAnyPermission: hasAnyPermissionCheck,
    hasAllPermissions: hasAllPermissionsCheck,
    isLoading,
    error
  };

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