import React, { createContext, useContext, useState, useEffect } from 'react';
import * as msal from '@azure/msal-browser';
import { msalConfig, loginRequest } from '../AuthConfig';

const AuthContext = createContext();

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

const msalInstance = new msal.PublicClientApplication(msalConfig);

export const AuthProvider = ({ children }) => {
    const [user, setUser] = useState(null);
    const [isLoading, setIsLoading] = useState(true);
    const [userGroups, setUserGroups] = useState([]);
    const [isAuthorized, setIsAuthorized] = useState(false);

    // Fonction pour obtenir l'URL de l'API backend
    const getApiUrl = (endpoint) => {
        const possibleUrls = [
            'http://localhost/GTA/project/public/php/',
            'http://localhost:80/GTA/project/public/php/',
            'http://localhost/GTA/public/php/',
            'http://localhost/public/php/'
        ];
        return possibleUrls[0] + endpoint; // Utilisez votre URL préférée
    };

    // Vérifier les groupes utilisateur via l'API backend
    const checkUserAuthorization = async (userPrincipalName, accessToken) => {
        try {
            const response = await fetch(getApiUrl('check-user-groups.php'), {
                method: 'POST',
                headers: {
                    'Content-Type': 'application/json',
                    'Authorization': `Bearer ${accessToken}`
                },
                body: JSON.stringify({ userPrincipalName })
            });

            if (response.ok) {
                const data = await response.json();
                setUserGroups(data.groups || []);
                setIsAuthorized(data.authorized || false);
                return data;
            }
            return { authorized: false, groups: [] };
        } catch (error) {
            console.error('Erreur vérification groupes:', error);
            return { authorized: false, groups: [] };
        }
    };

    // Synchroniser l'utilisateur avec la base locale
    const syncUserToDatabase = async (entraUser, accessToken) => {
        try {
            const response = await fetch(getApiUrl('check-user-groups.php'), {
                method: 'POST',
                headers: {
                    'Content-Type': 'application/json',
                    'Authorization': `Bearer ${accessToken}`
                },
                body: JSON.stringify({
                    entraUserId: entraUser.id,
                    userPrincipalName: entraUser.userPrincipalName,
                    email: entraUser.mail || entraUser.userPrincipalName,
                    displayName: entraUser.displayName,
                    givenName: entraUser.givenName,
                    surname: entraUser.surname,
                    jobTitle: entraUser.jobTitle,
                    department: entraUser.department,
                    officeLocation: entraUser.officeLocation
                })
            });

            if (response.ok) {
                return await response.json();
            }
        } catch (error) {
            console.error('Erreur synchronisation utilisateur:', error);
        }
        return null;
    };

    // Initialisation MSAL
    useEffect(() => {
        const initializeMsal = async () => {
            try {
                await msalInstance.initialize();

                // Vérifier si il y a un utilisateur connecté
                const accounts = msalInstance.getAllAccounts();
                if (accounts.length > 0) {
                    // Essayer de récupérer un token silencieusement
                    try {
                        const response = await msalInstance.acquireTokenSilent({
                            ...loginRequest,
                            account: accounts[0]
                        });

                        await handleSuccessfulAuth(response);
                    } catch (error) {
                        console.log('Token silent acquisition failed:', error);
                    }
                }
            } catch (error) {
                console.error("Erreur d'initialisation MSAL:", error);
            } finally {
                setIsLoading(false);
            }
        };

        initializeMsal();
    }, []);

    // Gérer l'authentification réussie
    // Gérer l'authentification réussie
    const handleSuccessfulAuth = async (authResponse) => {
        try {
            const account = authResponse.account;
            const accessToken = authResponse.accessToken;

            // 🔹 Récupérer profil Microsoft Graph
            const graphResponse = await fetch('https://graph.microsoft.com/v1.0/me', {
                headers: { 'Authorization': `Bearer ${accessToken}` }
            });

            let entraUser = {
                id: account.homeAccountId,
                displayName: account.name,
                userPrincipalName: account.username,
                mail: account.username
            };

            if (graphResponse.ok) {
                const graphData = await graphResponse.json();
                entraUser = { ...entraUser, ...graphData };
            }

            // 🔹 Synchroniser l’utilisateur dans la DB
            const syncResult = await syncUserToDatabase(entraUser, accessToken);
            console.log("Résultat syncUserToDatabase:", syncResult);

            // 🚀 Si admin → lancer full-sync.php
            if (syncResult?.role === "Admin") {
                try {
                    const syncResp = await fetch(getApiUrl('full-sync.php'), {
                        method: "POST",
                        headers: { "Authorization": `Bearer ${accessToken}` }
                    });
                    const syncData = await syncResp.json();
                    console.log("Résultat Full Sync:", syncData);
                } catch (err) {
                    console.error("Erreur synchronisation groupes:", err);
                }
            }

            // 🔹 Vérifier autorisation via groupes DB
            const authResult = await checkUserAuthorization(entraUser.userPrincipalName, accessToken);

            if (authResult.authorized) {
                const userData = {
                    id: syncResult?.localUserId || entraUser.id,
                    entraUserId: entraUser.id,
                    name: entraUser.displayName,
                    prenom: entraUser.givenName || entraUser.displayName?.split(' ')[0] || '',
                    nom: entraUser.surname || entraUser.displayName?.split(' ')[1] || '',
                    email: entraUser.mail || entraUser.userPrincipalName,
                    userPrincipalName: entraUser.userPrincipalName,
                    role: syncResult?.role || 'Employe',

                    // ✅ Correction ici
                    service: syncResult?.service
                        || syncResult?.user?.service
                        || entraUser.department
                        || 'Non défini',

                    jobTitle: entraUser.jobTitle,
                    department: entraUser.department,
                    officeLocation: entraUser.officeLocation,
                    groups: authResult.groups
                };

                setUser(userData);
                setIsAuthorized(true);
                return true;
            } else {
                throw new Error('Utilisateur non autorisé - pas membre des groupes requis');
            }
        } catch (error) {
            console.error('Erreur lors de la gestion de l\'authentification:', error);
            throw error;
        }
    };



    // Connexion classique (email/mot de passe)
    const login = async (email, password) => {
        try {
            const response = await fetch(getApiUrl('login.php'), {
                method: 'POST',
                headers: { 'Content-Type': 'application/json' },
                body: JSON.stringify({ email, mot_de_passe: password }),
            });

            if (!response.ok) {
                throw new Error('Erreur de connexion');
            }

            const text = await response.text();
            let data;
            try {
                data = JSON.parse(text);
            } catch {
                console.error("Réponse non-JSON:", text.substring(0, 200));
                throw new Error("Le serveur PHP ne répond pas correctement.");
            }

            if (data.success) {
                const userData = {
                    id: data.user.id,
                    name: `${data.user.prenom} ${data.user.nom}`,
                    prenom: data.user.prenom,
                    nom: data.user.nom,
                    email: data.user.email,
                    role: data.user.role || 'Employe',
                    service: data.user.service || 'Non défini'
                };

                setUser(userData);
                setIsAuthorized(true);
                return true;
            }
            return false;
        } catch (error) {
            console.error("Erreur de connexion:", error);
            return false;
        }
    };

    // Connexion Office 365
    const loginWithO365 = async () => {
        try {
            const authResponse = await msalInstance.loginPopup(loginRequest);
            await handleSuccessfulAuth(authResponse);
            return true;
        } catch (error) {
            console.error('Erreur login Office 365:', error);
            if (error.message?.includes('non autorisé')) {
                throw new Error('Accès refusé: Vous n\'êtes pas membre d\'un groupe autorisé.');
            }
            throw error;
        }
    };

    // Déconnexion
    const logout = async () => {
        try {
            const accounts = msalInstance.getAllAccounts();
            if (accounts.length > 0) {
                await msalInstance.logoutPopup({
                    account: accounts[0]
                });
            }
        } catch (error) {
            console.error('Erreur lors de la déconnexion:', error);
        } finally {
            setUser(null);
            setUserGroups([]);
            setIsAuthorized(false);
        }
    };

    // Obtenir un token pour l'API
    const getAccessToken = async () => {
        try {
            const accounts = msalInstance.getAllAccounts();
            if (accounts.length === 0) {
                throw new Error('Aucun compte connecté');
            }

            const response = await msalInstance.acquireTokenSilent({
                ...loginRequest,
                account: accounts[0]
            });

            return response.accessToken;
        } catch (error) {
            console.error('Erreur obtention token:', error);
            return null;
        }
    };

    const value = {
        user,
        userGroups,
        isAuthorized,
        login,
        loginWithO365,
        logout,
        isLoading,
        getAccessToken
    };

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

export default AuthContext;