
"use client";

import type { ReactNode } from 'react';
import { createContext, useContext, useState, useEffect } from 'react';
import { useRouter, usePathname } from 'next/navigation';
import type { User } from '@/types';
import { auth, db } from "@/lib/firebase";
import {
  createUserWithEmailAndPassword,
  signInWithEmailAndPassword,
  signOut,
  onAuthStateChanged,
  type User as FirebaseUser,
  GoogleAuthProvider,
  FacebookAuthProvider,
  signInWithPopup,
} from 'firebase/auth';
import { ref, set, get, serverTimestamp, update } from 'firebase/database';

type UserRole = 'admin' | 'creator' | null;

interface AuthContextType {
  isAuthenticated: boolean;
  userRole: UserRole;
  userId: string | null;
  user: FirebaseUser | null;
  login: (email: string, pass: string) => Promise<{ success: boolean; message?: string }>;
  signUpCreator: (email: string, pass: string, username: string) => Promise<{ success: boolean; message?: string }>;
  logout: () => void;
  // TODO: Implement social sign-ins with Firebase
  signInWithGoogle: () => boolean;
  signInWithFacebook: () => boolean;
}

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

export function AuthProvider({ children }: { children: ReactNode }) {
  const [user, setUser] = useState<FirebaseUser | null>(null);
  const [userRole, setUserRole] = useState<UserRole>(null);
  const [userId, setUserId] = useState<string | null>(null);
  const [isLoading, setIsLoading] = useState(true);

  const router = useRouter();
  const pathname = usePathname();

  useEffect(() => {
    const unsubscribe = onAuthStateChanged(auth, async (firebaseUser) => {
      if (firebaseUser) {
        setUser(firebaseUser);
        setUserId(firebaseUser.uid);
        // Fetch user role from Realtime Database
        const userProfileRef = ref(db, `users/${firebaseUser.uid}`);
        const snapshot = await get(userProfileRef);
        if (snapshot.exists()) {
          const userProfile = snapshot.val();
          setUserRole(userProfile.role);
        } else {
          // This case might happen if user is created in auth but not in DB.
          // Or for social sign-in on first login.
          setUserRole('creator'); // Default role
        }
      } else {
        setUser(null);
        setUserId(null);
        setUserRole(null);
      }
      setIsLoading(false);
    });

    return () => unsubscribe();
  }, []);
  
  const login = async (email: string, pass: string): Promise<{ success: boolean; message?: string }> => {
    try {
      const userCredential = await signInWithEmailAndPassword(auth, email, pass);
      const userProfileRef = ref(db, `users/${userCredential.user.uid}`);
      // Use `update` to change only specific fields without overwriting the whole node
      await update(userProfileRef, { lastLogin: new Date().toISOString() });

      // The onAuthStateChanged listener will handle setting state and redirection
      return { success: true };
    } catch (error: any) {
      console.error("Firebase login error:", error);
      return { success: false, message: error.message || "Failed to log in." };
    }
  };

  const signUpCreator = async (email: string, pass: string, username: string): Promise<{ success: boolean; message?: string }> => {
     try {
      const userCredential = await createUserWithEmailAndPassword(auth, email, pass);
      const newUserId = userCredential.user.uid;

      // Now, create the user profile in the Realtime Database
      const newUserProfile: Omit<User, 'id'> = {
        username,
        email,
        role: email === 'admin@runinga.co.ke' ? 'admin' : 'creator', // Assign admin role if email matches
        method: 'credentials',
        lastLogin: new Date().toISOString(),
        createdAt: serverTimestamp() as any,
      };
      
      const userProfileRef = ref(db, 'users/' + newUserId);
      await set(userProfileRef, newUserProfile);

      // onAuthStateChanged will handle the rest
      return { success: true, message: "Account created successfully!" };
    } catch (error: any) {
      console.error("Firebase signup error:", error);
      return { success: false, message: error.message || "Could not create account." };
    }
  };

  const logout = async () => {
    await signOut(auth);
    router.push('/');
  };

  const signInWithGoogle = (): boolean => {
    // TODO: Implement actual Firebase Google Sign-In
    alert("Mock Google Sign-In. This feature needs to be wired up to Firebase.");
    return false;
  };

  const signInWithFacebook = (): boolean => {
    // TODO: Implement actual Firebase Facebook Sign-In
    alert("Mock Facebook Sign-In. This feature needs to be wired up to Firebase.");
    return false;
  };
  
  // Enforce route protection
  useEffect(() => {
    if (isLoading) return; // Wait until auth state is confirmed

    const publicPaths = ['/login', '/', '/about'];
    const isAuth = !!user;

    if (pathname === '/login' && isAuth) {
        // Only redirect once the user role has been determined
        if (userRole) {
            if (userRole === 'admin') router.push('/admin');
            else router.push('/user-dashboard');
        } else {
            router.push('/'); // Fallback if role is not yet determined
        }
        return; // Return here to avoid other checks on the login page
    }
    
    if (!publicPaths.includes(pathname) && !isAuth) {
      router.push('/login');
    } else if (pathname === '/admin' && (!isAuth || userRole !== 'admin')) {
      router.push(isAuth ? '/' : '/login');
    } else if (pathname === '/user-dashboard' && (!isAuth || (userRole !== 'creator' && userRole !== 'admin'))) {
      router.push(isAuth ? '/' : '/login');
    } else if (pathname === '/invest' && (!isAuth || (userRole !== 'creator' && userRole !== 'admin'))) {
      router.push(isAuth ? '/' : '/login');
    }
  }, [user, userRole, pathname, router, isLoading]);

  const value: AuthContextType = {
    isAuthenticated: !!user,
    userRole,
    userId,
    user,
    login,
    signUpCreator,
    logout,
    signInWithGoogle,
    signInWithFacebook,
  };

  return (
    <AuthContext.Provider value={value}>
      {isLoading ? (
        <div className="min-h-screen flex items-center justify-center">
            <p>Authenticating...</p>
        </div>
      ) : children}
    </AuthContext.Provider>
  );
}

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