export interface UserWithGroups {
  id: string;
  email: string;
  username: string;
  name: string;
  authMethod: string;
  groups: string[];
}

export interface AuthState {
  user: UserWithGroups | null;
  authenticated: boolean;
  groups: string[];
}

/**
 * Authorization composable for role-based access control
 */
export const useAuthorization = () => {
  // Get the cached auth state from middleware instead of making API calls
  const nuxtApp = useNuxtApp();
  
  // Simple reactive state that starts with safe defaults
  const authState = reactive<AuthState>({
    user: null,
    authenticated: false,
    groups: []
  });

  // Loading state
  const isLoading = ref(true);
  const hasInitialized = ref(false);

  // Initialize auth state from middleware cache (no API calls!)
  const initializeAuth = () => {
    if (hasInitialized.value) return;

    try {
      console.log('[useAuthorization] Initializing from middleware cache...');
      
      // Try to get auth from middleware's cached state first
      const cachedAuthState = nuxtApp.payload?.data?.authState;
      
      if (cachedAuthState && typeof cachedAuthState === 'object') {
        // Update reactive state from cache
        authState.user = cachedAuthState.user || null;
        authState.authenticated = cachedAuthState.authenticated || false;
        authState.groups = Array.isArray(cachedAuthState.groups) ? cachedAuthState.groups : [];
        
        console.log('[useAuthorization] Auth state loaded from cache:', {
          authenticated: authState.authenticated,
          groups: authState.groups,
          user: authState.user?.email
        });
        
        hasInitialized.value = true;
        isLoading.value = false;
        return true;
      }
      
      // Fallback: try session cache
      const sessionCache = nuxtApp.payload?.data?.['auth:session:cache'];
      if (sessionCache && typeof sessionCache === 'object') {
        authState.user = sessionCache.user || null;
        authState.authenticated = sessionCache.authenticated || false;
        authState.groups = Array.isArray(sessionCache.groups) ? sessionCache.groups : [];
        
        console.log('[useAuthorization] Auth state loaded from session cache:', {
          authenticated: authState.authenticated,
          groups: authState.groups,
          user: authState.user?.email
        });
        
        hasInitialized.value = true;
        isLoading.value = false;
        return true;
      }
      
    } catch (error) {
      console.error('[useAuthorization] Failed to load from cache:', error);
    }
    
    // Set safe defaults if no cache available
    console.log('[useAuthorization] No cache available, using defaults');
    authState.user = null;
    authState.authenticated = false;
    authState.groups = [];
    hasInitialized.value = true;
    isLoading.value = false;
    return false;
  };

  // Initialize immediately (both client and server)
  initializeAuth();
  
  // Watch for changes in payload data (optimized to prevent loops)
  if (process.client) {
    let watcherTimeout: NodeJS.Timeout | null = null;
    
    watch(
      () => nuxtApp.payload?.data?.authState,
      (newAuthState, oldAuthState) => {
        // Only update if the auth state actually changed
        if (newAuthState && typeof newAuthState === 'object' && newAuthState !== oldAuthState) {
          // Debounce to prevent rapid re-initialization
          if (watcherTimeout) clearTimeout(watcherTimeout);
          
          watcherTimeout = setTimeout(() => {
            console.log('[useAuthorization] Auth state updated, syncing...');
            
            // Direct sync instead of full re-initialization
            authState.user = newAuthState.user || null;
            authState.authenticated = newAuthState.authenticated || false;
            authState.groups = Array.isArray(newAuthState.groups) ? newAuthState.groups : [];
            
            if (!hasInitialized.value) {
              hasInitialized.value = true;
              isLoading.value = false;
            }
          }, 100); // 100ms debounce
        }
      },
      { immediate: false, deep: false }
    );
  }

  /**
   * Get current user groups from session
   */
  const getUserGroups = (): string[] => {
    try {
      return Array.isArray(authState.groups) ? authState.groups : [];
    } catch (error) {
      console.error('[useAuthorization] Error getting user groups:', error);
      return [];
    }
  };

  /**
   * Get current authenticated user
   */
  const getCurrentUser = (): UserWithGroups | null => {
    try {
      return authState.user || null;
    } catch (error) {
      console.error('[useAuthorization] Error getting current user:', error);
      return null;
    }
  };

  /**
   * Check if user has specific role/group
   */
  const hasRole = (role: string): boolean => {
    const groups = getUserGroups();
    return groups.includes(role);
  };

  /**
   * Check if user has any of the specified roles
   */
  const hasAnyRole = (roles: string[]): boolean => {
    const groups = getUserGroups();
    return roles.some(role => groups.includes(role));
  };

  /**
   * Check if user has all of the specified roles
   */
  const hasAllRoles = (roles: string[]): boolean => {
    const groups = getUserGroups();
    return roles.every(role => groups.includes(role));
  };

  /**
   * Check if user can access a specific resource/feature
   */
  const canAccess = (resource: string): boolean => {
    const groups = getUserGroups();
    
    // Define access rules for different resources
    const accessRules: Record<string, string[]> = {
      'expenses': ['sales', 'admin'],
      'admin-console': ['admin'],
      'audit-logs': ['admin'],
      'system-logs': ['admin'],
      'duplicate-management': ['admin'],
      'user-management': ['admin'],
      'interests': ['user', 'sales', 'admin'],
      'berths': ['user', 'sales', 'admin'],
      'dashboard': ['user', 'sales', 'admin'],
    };

    const requiredRoles = accessRules[resource];
    if (!requiredRoles) {
      // If no specific rules defined, allow for authenticated users
      return groups.length > 0;
    }

    return hasAnyRole(requiredRoles);
  };

  /**
   * Convenience methods for common role checks
   */
  const isAdmin = (): boolean => hasRole('admin');
  const isSales = (): boolean => hasRole('sales');
  const isUser = (): boolean => hasRole('user');
  const isSalesOrAdmin = (): boolean => hasAnyRole(['sales', 'admin']);
  const isUserOrAbove = (): boolean => hasAnyRole(['user', 'sales', 'admin']);

  /**
   * Get user's highest role (for display purposes)
   */
  const getHighestRole = (): string => {
    const groups = getUserGroups();
    if (groups.includes('admin')) return 'admin';
    if (groups.includes('sales')) return 'sales';
    if (groups.includes('user')) return 'user';
    return 'none';
  };

  /**
   * Get role display name
   */
  const getRoleDisplayName = (role: string): string => {
    const roleNames: Record<string, string> = {
      'admin': 'Administrator',
      'sales': 'Sales Team',
      'user': 'User',
      'none': 'No Access'
    };
    return roleNames[role] || role;
  };

  /**
   * Get role color for UI display
   */
  const getRoleColor = (role: string): string => {
    const roleColors: Record<string, string> = {
      'admin': 'red',
      'sales': 'purple',
      'user': 'blue',
      'none': 'grey'
    };
    return roleColors[role] || 'grey';
  };

  /**
   * Check if current route requires specific roles
   */
  const checkRouteAccess = (route: any): boolean => {
    if (!route.meta?.roles) {
      // No role requirements, allow access
      return true;
    }

    const requiredRoles = Array.isArray(route.meta.roles) ? route.meta.roles : [route.meta.roles];
    return hasAnyRole(requiredRoles);
  };

  /**
   * Get navigation items filtered by user permissions
   */
  const getFilteredNavigation = (navigationItems: any[]): any[] => {
    return navigationItems.filter(item => {
      if (!item.roles) return true; // No role restrictions
      return hasAnyRole(item.roles);
    });
  };

  /**
   * Update auth state (called by middleware)
   */
  const updateAuthState = (newAuthState: AuthState) => {
    try {
      const nuxtApp = useNuxtApp();
      if (!nuxtApp.payload.data) {
        nuxtApp.payload.data = {};
      }
      nuxtApp.payload.data.authState = newAuthState;
    } catch (error) {
      console.error('[useAuthorization] Error updating auth state:', error);
    }
  };

  return {
    // State getters
    getUserGroups,
    getCurrentUser,
    
    // Role checking
    hasRole,
    hasAnyRole,
    hasAllRoles,
    canAccess,
    
    // Convenience methods
    isAdmin,
    isSales,
    isUser,
    isSalesOrAdmin,
    isUserOrAbove,
    
    // Utility methods
    getHighestRole,
    getRoleDisplayName,
    getRoleColor,
    checkRouteAccess,
    getFilteredNavigation,
    
    // State management
    updateAuthState
  };
};
