import React, { createContext, useContext, useEffect, ReactNode, useState } from 'react';
import { useAuthStore, User } from '../stores/auth.store';
import { authService } from '../api/services/auth';

interface AuthContextType {
  user: User | null;
  isAuthenticated: boolean;
  isLoading: boolean;
  error: string | null;
  login: (email: string, password: string) => Promise<void>;
  logout: () => void;
  refreshAuth: () => Promise<void>;
  clearError: () => void;
  hasPermission: (permission: string) => boolean;
  hasRole: (role: string) => boolean;
  canAccess: (resource: string, action: string) => boolean;
}

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 authStore = useAuthStore();
  const [isInitializing, setIsInitializing] = useState(true);

  // Initialize auth on mount
  useEffect(() => {
    const initializeAuth = async () => {
      setIsInitializing(true);

      // Check if zustand has already rehydrated
      if (!(useAuthStore.persist as any).hasHydrated?.()) {
        // Wait for rehydration event with minimal timeout fallback
        await Promise.race([
          new Promise<void>(resolve => {
            const unsubscribe = useAuthStore.persist.onFinishHydration(() => {
              unsubscribe();
              resolve();
            });
          }),
          new Promise(resolve => setTimeout(resolve, 50))
        ]);
      }

      // Check if we have stored auth data
      if (authStore.token && authStore.refreshToken) {
        try {
          // Validate current token by trying to verify it
          await authService.verifyToken();
          console.log('Token is valid, user authenticated');
        } catch (error) {
          console.log('Token expired, attempting refresh...');
          // Token is invalid, try to refresh
          try {
            await authStore.refreshAuth();
            console.log('Token refreshed successfully');
          } catch (refreshError) {
            console.log('Token refresh failed, logging out:', refreshError);
            // Refresh failed, clear auth
            authStore.logout();
          }
        }
      } else if (authStore.isAuthenticated) {
        // User is marked as authenticated but no tokens
        // Check if this is a demo session - demo sessions don't use JWT tokens
        const isDemoMode = localStorage.getItem('demo_mode') === 'true';
        const demoSessionId = localStorage.getItem('demo_session_id');

        if (isDemoMode && demoSessionId) {
          // Demo session: authentication is valid via X-Demo-Session-Id header
          console.log('Demo session detected, maintaining authentication state');
        } else {
          // Regular user without tokens - logout
          console.log('No tokens found but user marked as authenticated, logging out');
          authStore.logout();
        }
      } else {
        console.log('No stored auth data found');
      }

      setIsInitializing(false);
    };

    initializeAuth();
  }, []);


  const contextValue: AuthContextType = {
    user: authStore.user,
    isAuthenticated: authStore.isAuthenticated,
    isLoading: authStore.isLoading || isInitializing,
    error: authStore.error,
    login: authStore.login,
    logout: authStore.logout,
    refreshAuth: authStore.refreshAuth,
    clearError: authStore.clearError,
    hasPermission: authStore.hasPermission,
    hasRole: authStore.hasRole,
    canAccess: authStore.canAccess,
  };

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