// Firebase Authentication Context for Black Canyon Tickets React Rebuild
// This is a mock authentication context for learning purposes only

import React, { createContext, useContext, useEffect, useState } from 'react';

import {
  onAuthStateChanged,
  signOut,
  signInWithEmailAndPassword,
  GoogleAuthProvider,
  signInWithPopup,
  createUserWithEmailAndPassword
} from 'firebase/auth';

import { auth } from '@/lib/firebase';
import type { User} from '@/types/auth';
import { MOCK_USERS, ROLE_PERMISSIONS } from '@/types/auth';

import type {
  User as FirebaseUser} from 'firebase/auth';

interface FirebaseAuthContextType {
  // Authentication state
  user: User | null;
  firebaseUser: FirebaseUser | null;
  loading: boolean;
  
  // Authentication methods
  signInEmail: (email: string, password: string) => Promise<void>;
  signInGoogle: () => Promise<void>;
  signUpEmail: (email: string, password: string) => Promise<void>;
  signOut: () => Promise<void>;
  
  // Utility methods
  hasRole: (role: User['role'] | User['role'][]) => boolean;
  hasPermission: (permission: string) => boolean;
}

const FirebaseAuthContext = createContext<FirebaseAuthContextType | null>(null);

// Google Auth Provider setup
const googleProvider = new GoogleAuthProvider();
googleProvider.setCustomParameters({
  prompt: 'select_account'
});

export const FirebaseAuthProvider: React.FC<{ children: React.ReactNode }> = ({ children }) => {
  const [user, setUser] = useState<User | null>(null);
  const [firebaseUser, setFirebaseUser] = useState<FirebaseUser | null>(null);
  const [loading, setLoading] = useState(true);

  // Map Firebase user to our User type using mock data
  const mapFirebaseUserToUser = (firebaseUser: FirebaseUser): User => {
    // In a real app, this would fetch user data from Firestore
    // For learning purposes, we'll use mock data based on email
    const mockUser = MOCK_USERS[firebaseUser.email || ''] || MOCK_USERS['organizer@example.com'];
    
    if (!mockUser) {
      throw new Error('Mock user not found');
    }
    
    // Filter out problematic photo URLs that cause 404 errors
    const getValidAvatar = (photoURL: string | null, fallback?: string): string | undefined => {
      if (!photoURL) return fallback;
      
      // Block known problematic Unsplash URLs
      if (photoURL.includes('photo-1494790108755-2616b612b786')) {
        return fallback;
      }
      
      // Add other URL validations if needed
      return photoURL;
    };

    return {
      ...mockUser,
      id: firebaseUser.uid,
      email: firebaseUser.email || mockUser.email,
      name: firebaseUser.displayName || mockUser.name,
      avatar: getValidAvatar(firebaseUser.photoURL, mockUser.avatar),
      metadata: {
        ...mockUser.metadata,
        lastLogin: new Date().toISOString(),
        emailVerified: firebaseUser.emailVerified,
      },
    };
  };

  // Listen for authentication state changes
  useEffect(() => {
    const unsubscribe = onAuthStateChanged(auth, (firebaseUser) => {
      setFirebaseUser(firebaseUser);
      
      if (firebaseUser) {
        const mappedUser = mapFirebaseUserToUser(firebaseUser);
        setUser(mappedUser);
      } else {
        setUser(null);
      }
      
      setLoading(false);
    });

    return () => unsubscribe();
  }, []);

  // Sign in with email and password
  const signInEmail = async (email: string, password: string): Promise<void> => {
    setLoading(true);
    try {
      await signInWithEmailAndPassword(auth, email, password);
    } catch (error) {
      setLoading(false);
      throw error;
    }
  };

  // Sign in with Google
  const signInGoogle = async (): Promise<void> => {
    setLoading(true);
    try {
      await signInWithPopup(auth, googleProvider);
    } catch (error) {
      setLoading(false);
      throw error;
    }
  };

  // Sign up with email and password
  const signUpEmail = async (email: string, password: string): Promise<void> => {
    setLoading(true);
    try {
      await createUserWithEmailAndPassword(auth, email, password);
    } catch (error) {
      setLoading(false);
      throw error;
    }
  };

  // Sign out
  const handleSignOut = async (): Promise<void> => {
    setLoading(true);
    try {
      await signOut(auth);
    } catch (error) {
      setLoading(false);
      throw error;
    }
  };

  // Check if user has specific role(s)
  const hasRole = (role: User['role'] | User['role'][]): boolean => {
    if (!user) {return false;}
    if (Array.isArray(role)) {
      return role.includes(user.role);
    }
    return user.role === role;
  };

  // Check if user has specific permission
  const hasPermission = (permission: string): boolean => {
    if (!user) {return false;}
    const userPermissions = ROLE_PERMISSIONS[user.role] || [];
    
    // Check for wildcard permissions (admin:* grants all admin permissions)
    return userPermissions.some(userPerm => {
      if (userPerm.endsWith(':*')) {
        const prefix = userPerm.slice(0, -1); // Remove the '*'
        return permission.startsWith(prefix);
      }
      return userPerm === permission;
    });
  };

  const value: FirebaseAuthContextType = {
    user,
    firebaseUser,
    loading,
    signInEmail,
    signInGoogle,
    signUpEmail,
    signOut: handleSignOut,
    hasRole,
    hasPermission,
  };

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

// Custom hook to use Firebase Auth context
export const useFirebaseAuth = (): FirebaseAuthContextType => {
  const context = useContext(FirebaseAuthContext);
  if (!context) {
    throw new Error('useFirebaseAuth must be used within a FirebaseAuthProvider');
  }
  return context;
};

export default FirebaseAuthContext;