﻿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 [userGroups, setUserGroups] = useState([]);
    const [isAuthorized, setIsAuthorized] = useState(false);
    const [isLoading, setIsLoading] = useState(true);
    const [isMsalInitialized, setIsMsalInitialized] = useState(false);

    const getApiUrl = (endpoint) => `http://localhost:3000/${endpoint}`;

    // --- Vérifie l'autorisation de l'utilisateur via groupes
    const checkUserAuthorization = async (userPrincipalName, accessToken) => {
        try {
            const response = await fetch(getApiUrl('check-user-groups'), {
                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: [] };
        }
    };

    // --- Synchronisation utilisateur connecté
    const syncUserToDatabase = async (entraUser, accessToken) => {
        try {
            const response = await fetch(getApiUrl('initial-sync'), {
                method: 'POST',
                headers: {
                    'Content-Type': 'application/json',
                    'Authorization': `Bearer ${accessToken}`
                },
                body: JSON.stringify(entraUser)
            });

            if (response.ok) {
                const data = await response.json();
                console.log('Utilisateur synchronisé:', entraUser.userPrincipalName);
                return data;
            }
        } catch (error) {
            console.error('Erreur synchronisation utilisateur:', error);
        }
        return null;
    };

    // --- Full sync admin
    const fullSyncDatabase = async (accessToken) => {
        try {
            const response = await fetch(getApiUrl('initial-sync'), {
                method: 'POST',
                headers: { 'Authorization': `Bearer ${accessToken}` }
            });

            if (response.ok) {
                const data = await response.json();
                console.log('Full sync terminée:', data);
                return data;
            }
        } catch (error) {
            console.error('Erreur full sync:', error);
        }
        return null;
    };

    // --- S'assurer que MSAL est initialisé avant tout appel
    const ensureMsalInitialized = async () => {
        if (!isMsalInitialized) {
            try {
                await msalInstance.initialize();
                setIsMsalInitialized(true);
                console.log('MSAL initialisé');
            } catch (error) {
                console.error('Erreur initialisation MSAL:', error);
                throw error;
            }
        }
    };

    // --- Initialisation au chargement
    useEffect(() => {
        const initializeMsal = async () => {
            try {
                await ensureMsalInitialized();

                const accounts = msalInstance.getAllAccounts();
                if (accounts.length > 0) {
                    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();
    }, []);

    // --- Gestion login réussi
    const handleSuccessfulAuth = async (authResponse) => {
        try {
            const account = authResponse.account;
            const accessToken = authResponse.accessToken;

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

            const graphResponse = await fetch('https://graph.microsoft.com/v1.0/me', {
                headers: { 'Authorization': `Bearer ${accessToken}` }
            });

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

            // 1️⃣ Synchroniser l’utilisateur connecté
            const syncResult = await syncUserToDatabase(entraUser, accessToken);

            // 2️⃣ Full sync si admin
            if (syncResult?.role === 'Admin') {
                console.log('Admin détecté → lancement full sync...');
                await fullSyncDatabase(accessToken);
            }

            // 3️⃣ Vérifier groupes
            const authResult = await checkUserAuthorization(entraUser.userPrincipalName, accessToken);

            if (authResult.authorized) {
                setUser({
                    id: syncResult?.localUserId || entraUser.id,
                    CollaborateurADId: syncResult?.localUserId, // ⭐ AJOUT
                    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',
                    service: syncResult?.service || entraUser.department || 'Non défini',
                    jobTitle: entraUser.jobTitle,
                    department: entraUser.department,
                    officeLocation: entraUser.officeLocation,
                    typeContrat: syncResult?.typeContrat || '37h', // ⭐ AJOUT
                    dateEntree: syncResult?.dateEntree || null, // ⭐ AJOUT
                    groups: authResult.groups
                });
                setIsAuthorized(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
    const login = async (email, password) => {
        try {
            const response = await fetch(getApiUrl('login'), {
                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 data = await response.json();
            if (data.success) {
                setUser({
                    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'
                });
                setIsAuthorized(true);
                return true;
            }
            return false;
        } catch (error) {
            console.error("Erreur de connexion:", error);
            return false;
        }
    };

    // --- Connexion Office 365
    const loginWithO365 = async () => {
        try {
            await ensureMsalInitialized();
            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 token API
    const getAccessToken = async () => {
        try {
            await ensureMsalInitialized();
            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;
