import type { User } from '~/utils/types';

export const useAuth = () => {
  // Use useState for SSR compatibility - prevents hydration mismatches
  const user = useState<User | null>('auth.user', () => null);
  const isAuthenticated = computed(() => !!user.value);
  const loading = ref(false);
  const error = ref<string | null>(null);

  // Enhanced role checking method - supports both realm roles and legacy groups
  const hasRole = (roleName: string): boolean => {
    if (!user.value) return false;
    
    // Get roles from user token (Keycloak format)
    const userToken = user.value as any; // Cast for accessing token properties
    
    // Check realm roles first (new system)
    const realmRoles = userToken.realm_access?.roles || [];
    if (realmRoles.includes(roleName)) {
      return true;
    }
    
    // Check client roles (new system)
    const clientRoles = userToken.resource_access || {};
    for (const clientId in clientRoles) {
      const roles = clientRoles[clientId]?.roles || [];
      if (roles.includes(roleName)) {
        return true;
      }
    }
    
    // Fallback to legacy group system
    const groups = user.value.groups || [];
    return groups.includes(roleName) || groups.includes(`/${roleName}`);
  };

  // Enhanced tier-based computed properties with role support
  const isUser = computed(() => {
    // Check new realm roles first
    if (hasRole('monaco-user')) return true;
    // Fallback to legacy tier system
    return user.value?.tier === 'user';
  });
  
  // Alias for consistency with new naming convention
  const isMember = isUser;

  const isBoard = computed(() => {
    // Check new realm roles first
    if (hasRole('monaco-board')) return true;
    // Fallback to legacy tier system
    return user.value?.tier === 'board';
  });

  const isAdmin = computed(() => {
    // Check new realm roles first
    if (hasRole('monaco-admin')) return true;
    // Fallback to legacy tier system
    return user.value?.tier === 'admin';
  });

  // Enhanced tier computation with role priority
  const userTier = computed(() => {
    if (hasRole('monaco-admin')) return 'admin';
    if (hasRole('monaco-board')) return 'board';
    if (hasRole('monaco-user')) return 'user';
    // Fallback to legacy tier system
    return user.value?.tier || 'user';
  });

  const firstName = computed(() => {
    if (user.value?.firstName) return user.value.firstName;
    if (user.value?.name) return user.value.name.split(' ')[0];
    return 'User';
  });

  // Enhanced helper methods
  const hasTier = (requiredTier: 'user' | 'board' | 'admin') => {
    // Use computed userTier which handles both new and legacy systems
    return userTier.value === requiredTier;
  };

  const hasGroup = (groupName: string) => {
    return user.value?.groups?.includes(groupName) || false;
  };

  // New helper methods for realm roles
  const hasRealmRole = (roleName: string): boolean => {
    if (!user.value) return false;
    const userToken = user.value as any;
    const realmRoles = userToken.realm_access?.roles || [];
    return realmRoles.includes(roleName);
  };

  const hasClientRole = (roleName: string, clientId?: string): boolean => {
    if (!user.value) return false;
    const userToken = user.value as any;
    const clientRoles = userToken.resource_access || {};
    
    if (clientId) {
      // Check specific client
      const roles = clientRoles[clientId]?.roles || [];
      return roles.includes(roleName);
    } else {
      // Check all clients
      for (const cId in clientRoles) {
        const roles = clientRoles[cId]?.roles || [];
        if (roles.includes(roleName)) {
          return true;
        }
      }
      return false;
    }
  };

  // Get all user roles (combines realm and client roles)
  const getAllRoles = (): string[] => {
    if (!user.value) return [];
    const userToken = user.value as any;
    const roles: string[] = [];
    
    // Add realm roles
    const realmRoles = userToken.realm_access?.roles || [];
    roles.push(...realmRoles);
    
    // Add client roles
    const clientRoles = userToken.resource_access || {};
    for (const clientId in clientRoles) {
      const clientRolesList = clientRoles[clientId]?.roles || [];
      roles.push(...clientRolesList);
    }
    
    // Add legacy groups for compatibility
    const groups = user.value.groups || [];
    roles.push(...groups);
    
    return [...new Set(roles)]; // Remove duplicates
  };

  // Direct login method
  const login = async (credentials: { username: string; password: string; rememberMe?: boolean }) => {
    loading.value = true;
    error.value = null;
    
    try {
      console.log('🔄 Starting login request...');
      
      const response = await $fetch<{
        success: boolean;
        redirectTo?: string;
        user?: User;
      }>('/api/auth/direct-login', {
        method: 'POST',
        body: credentials,
        timeout: 30000 // 30 second timeout
      });
      
      console.log('✅ Login response received:', response);
      
      if (response.success) {
        // Add a small delay to ensure cookie is set before checking session
        console.log('⏳ Waiting for cookie to be set...');
        await new Promise(resolve => setTimeout(resolve, 200));
        
        // After successful login, get the user data from the session
        console.log('🔄 Getting user data from session...');
        
        // Try multiple times in case of timing issues
        let sessionSuccess = false;
        let attempts = 0;
        const maxAttempts = 3;
        
        while (!sessionSuccess && attempts < maxAttempts) {
          attempts++;
          console.log(`🔄 Session check attempt ${attempts}/${maxAttempts}`);
          
          sessionSuccess = await checkAuth();
          
          if (!sessionSuccess && attempts < maxAttempts) {
            console.log('⏳ Session not ready, waiting 500ms...');
            await new Promise(resolve => setTimeout(resolve, 500));
          }
        }
        
        if (sessionSuccess) {
          console.log('👤 User data retrieved from session:', user.value);
          
          // Return redirect URL for the component to handle
          console.log('✅ Login successful, returning redirect URL:', response.redirectTo || '/dashboard');
          return { 
            success: true, 
            redirectTo: response.redirectTo || '/dashboard' 
          };
        } else {
          console.warn('❌ Failed to get user data from session after login');
          // Still return success with redirect since login was successful on server
          return { 
            success: true, 
            redirectTo: '/dashboard' 
          };
        }
      }
      
      console.warn('❌ Login response indicates failure:', response);
      return { success: false, error: 'Login failed' };
    } catch (err: any) {
      console.error('❌ Login error caught:', err);
      
      // Handle different types of errors
      let errorMessage = 'Login failed';
      
      if (err.status === 502) {
        errorMessage = 'Server temporarily unavailable. Please try again.';
      } else if (err.status === 401) {
        errorMessage = 'Invalid username or password';
      } else if (err.status === 429) {
        errorMessage = 'Too many login attempts. Please try again later.';
      } else if (err.data?.message) {
        errorMessage = err.data.message;
      } else if (err.message) {
        errorMessage = err.message;
      }
      
      error.value = errorMessage;
      return { success: false, error: errorMessage };
    } finally {
      loading.value = false;
    }
  };

  // OAuth login method (fallback)
  const loginOAuth = () => {
    return navigateTo('/api/auth/login');
  };

  // Password reset method
  const requestPasswordReset = async (email: string) => {
    loading.value = true;
    error.value = null;
    
    try {
      const response = await $fetch<{
        success: boolean;
        message: string;
      }>('/api/auth/forgot-password', {
        method: 'POST',
        body: { email }
      });
      
      return { success: true, message: response.message };
    } catch (err: any) {
      error.value = err.data?.message || 'Password reset failed';
      return { success: false, error: error.value };
    } finally {
      loading.value = false;
    }
  };

  // Check authentication status - simple and reliable
  const checkAuth = async () => {
    try {
      console.log('🔄 Performing session check...');
      
      const response = await $fetch<{
        authenticated: boolean;
        user: User | null;
      }>('/api/auth/session');
      
      if (response.authenticated && response.user) {
        user.value = response.user;
        return true;
      } else {
        user.value = null;
        return false;
      }
    } catch (err) {
      console.error('Auth check error:', err);
      user.value = null;
      return false;
    }
  };

  // Logout method
  const logout = async () => {
    try {
      await $fetch('/api/auth/logout', { method: 'POST' });
      user.value = null;
      await navigateTo('/login');
    } catch (err) {
      console.error('Logout error:', err);
      user.value = null;
      await navigateTo('/login');
    }
  };

  return {
    // State
    user: readonly(user),
    isAuthenticated,
    loading: readonly(loading),
    error: readonly(error),
    
    // Tier-based properties
    userTier,
    isUser,
    isMember,  // Alias for isUser, better naming convention
    isBoard,
    isAdmin,
    firstName,
    
    // Helper methods
    hasTier,
    hasGroup,
    hasRole, // Enhanced with realm role support
    hasRealmRole,
    hasClientRole,
    getAllRoles,
    
    // Actions
    login,
    loginOAuth,
    logout,
    requestPasswordReset,
    checkAuth,
  };
};
