'use client';

/**
 * Firebase Auth Context Provider
 * 
 * 앱 전체에서 인증 상태를 관리합니다.
 */

import { createContext, useContext, useEffect, useState, useRef, ReactNode } from 'react';
import {
    User,
    onAuthStateChanged,
    signInWithPopup,
    signOut as firebaseSignOut
} from 'firebase/auth';
import { doc, getDoc, setDoc, serverTimestamp, onSnapshot } from 'firebase/firestore';
import { auth, googleProvider, db } from '@/lib/firebase';
import type { UserRole } from '@/shared/types/roles';

export type { UserRole } from '@/shared/types/roles';

interface AuthContextType {
    user: User | null;
    userRole: UserRole | null;
    customName: string | null;
    loading: boolean;
    signInWithGoogle: () => Promise<void>;
    signOut: () => Promise<void>;
}

const AuthContext = createContext<AuthContextType | undefined>(undefined);

export function AuthProvider({ children }: { children: ReactNode }) {
    const [user, setUser] = useState<User | null>(null);
    const [userRole, setUserRole] = useState<UserRole | null>(null);
    const userRoleRef = useRef<UserRole | null>(null);
    const [customName, setCustomName] = useState<string | null>(null);
    const [loading, setLoading] = useState(true);

    useEffect(() => {
        let unsubscribeUserDoc: (() => void) | undefined;

        const unsubscribeAuth = onAuthStateChanged(auth, async (firebaseUser) => {
            setUser(firebaseUser);

            if (firebaseUser) {
                // 1. Check if user doc exists in Firestore
                const userDocRef = doc(db, 'users', firebaseUser.uid);

                try {
                    const docSnap = await getDoc(userDocRef);

                    if (!docSnap.exists()) {
                        // 2. Create new user doc if not exists (Default: guest)
                        await setDoc(userDocRef, {
                            email: firebaseUser.email,
                            name: firebaseUser.displayName,       // ADD: canonical field for User interface
                            displayName: firebaseUser.displayName, // KEEP: backward compat
                            photoURL: firebaseUser.photoURL,
                            role: 'guest',
                            customName: null,
                            createdAt: serverTimestamp(),
                            lastLoginAt: serverTimestamp(),
                        });
                        setUserRole('guest');
                        setCustomName(null);
                        setLoading(false); // Set loading false after creation
                    } else {
                        // Update last login
                        await setDoc(userDocRef, { lastLoginAt: serverTimestamp() }, { merge: true });
                    }

                    // 3. Real-time listener for Role changes
                    unsubscribeUserDoc = onSnapshot(userDocRef, async (snapshot) => {
                        const data = snapshot.data();
                        if (data) {
                            const newRole = data.role as UserRole;
                            if (newRole && newRole !== userRoleRef.current) {
                                userRoleRef.current = newRole;
                                setUserRole(newRole);
                                if (firebaseUser) {
                                    await firebaseUser.getIdToken(true);
                                }
                            }
                            if (data.customName !== undefined) setCustomName(data.customName);
                        }
                        setLoading(false); // Set loading false after fetching role
                    }, (error) => {
                        console.error("Error in user snapshot listener:", error);
                        setLoading(false);
                    });

                } catch (error) {
                    console.error("Error fetching user role:", error);
                    // Fallback to guest on error
                    setUserRole('guest');
                    setLoading(false);
                }
            } else {
                setUserRole(null);
                setCustomName(null);
                if (unsubscribeUserDoc) unsubscribeUserDoc();
                setLoading(false);
            }
        });

        return () => {
            unsubscribeAuth();
            if (unsubscribeUserDoc) unsubscribeUserDoc();
        };
    }, []);

    const signInWithGoogle = async () => {
        try {
            googleProvider.setCustomParameters({
                prompt: 'select_account'
            });
            await signInWithPopup(auth, googleProvider);
        } catch (error) {
            console.error('Google 로그인 실패:', error);
            throw error;
        }
    };

    const signOut = async () => {
        try {
            await firebaseSignOut(auth);
            setUserRole(null);
            setCustomName(null);
        } catch (error) {
            console.error('로그아웃 실패:', error);
            throw error;
        }
    };

    return (
        <AuthContext.Provider value={{ user, userRole, customName, loading, signInWithGoogle, signOut }}>
            {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;
}
