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

// ── TYPES ──────────────────────────────────────────────
interface User {
    id: number;
    name: string;
    email: string;
    role: string;      // chaîne brute ex: "Collaboratrice,Finance"
    roles: string[];   // tableau ex: ["Collaboratrice", "Finance"]
}

interface AuthContextType {
    user: User | null;
    activeRole: string | null;
    allRoles: string[];
    isMultiRole: boolean;
    needsRoleSelection: boolean;

    handleCallback: (token: string) => void;
    logout: () => void;
    selectRole: (role: string) => void;
    switchRole: (role: string) => void;

    hasRole: (...roles: string[]) => boolean;
    isCollaborateur: boolean;
    isValidateur: boolean;
    isFinance: boolean;
    isSuperUser: boolean;
    isVerificateurFinance: boolean;
    isValidateurFinance: boolean;
    isPresident: boolean;
}

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

const API = 'myndf.ensup-adm.net';

const VALID_ROLES = [
    'Collaborateur', 'Collaboratrice',
    'Validateur', 'Validatrice',
    'Finance', 'VerificateurFinance', 'ValidateurFinance',
    'superUtilisateur','President'
];

function parseRoles(input: string | string[]): string[] {
    // ✅ Gère les deux cas : tableau JWT ou chaîne BDD
    if (Array.isArray(input)) {
        return input.filter(r => VALID_ROLES.includes(r));
    }
    if (!input) return [];
    return input
        .split(',')
        .map(r => r.trim())
        .filter(r => VALID_ROLES.includes(r));
}

// ── PROVIDER ───────────────────────────────────────────
export const AuthProvider = ({ children }: { children: ReactNode }) => {

    const [user, setUser] = useState<User | null>(() => {
        const saved = localStorage.getItem('user');
        if (!saved) return null;
        const u = JSON.parse(saved);
        if (!u.roles || !u.roles.length) u.roles = parseRoles(u.role || '');
        return u;
    });

    const [activeRole, setActiveRole] = useState<string | null>(() => {
        return localStorage.getItem('activeRole');
    });

    const [needsRoleSelection, setNeedsRoleSelection] = useState<boolean>(() => {
        const saved = localStorage.getItem('user');
        const savedRole = localStorage.getItem('activeRole');
        if (!saved) return false;
        const u = JSON.parse(saved);
        const roles = parseRoles(u.roles || u.role || '');
        return roles.length > 1 && !savedRole;
    });

    // ── Revalidation du profil au démarrage ───────────
    useEffect(() => {
        const token = localStorage.getItem('token');
        if (!token) return;

        try {
            const payload = JSON.parse(atob(token.split('.')[1]));
            if (payload.exp * 1000 < Date.now()) {
                _clearSession();
                return;
            }
        } catch {
            _clearSession();
            return;
        }

        fetch(`${API}/api/profile`, {
            headers: { Authorization: `Bearer ${token}` }
        })
            .then(r => r.ok ? r.json() : null)
            .then(profile => {
                if (!profile) return;

                // ✅ On lit profile.roles (tableau depuis UtilisateurRoles)
                //    avec fallback sur profile.role (ancienne colonne)
                const roles = parseRoles(profile.roles || profile.role || '');
                const rawRole = roles.join(',');

                const refreshed: User = {
                    id: profile.id,
                    name: `${profile.prenom} ${profile.nom}`.trim(),
                    email: profile.email,
                    role: rawRole,
                    roles,
                };
                setUser(refreshed);
                localStorage.setItem('user', JSON.stringify(refreshed));

                const savedRole = localStorage.getItem('activeRole');
                if (savedRole && !roles.includes(savedRole)) {
                    localStorage.removeItem('activeRole');
                    setActiveRole(null);
                    setNeedsRoleSelection(roles.length > 1);
                }
            })
            .catch(() => { });
    }, []);

    // ── handleCallback ────────────────────────────────
    const handleCallback = (token: string) => {
        localStorage.setItem('token', token);

        const payload = JSON.parse(atob(token.split('.')[1]));

        // ✅ Le JWT contient `roles` (tableau), pas `role` (chaîne)
        const roles = parseRoles(payload.roles || payload.role || '');
        const rawRole = roles.join(',');

        const newUser: User = {
            id: payload.id,
            name: `${payload.prenom} ${payload.nom}`.trim(),
            email: payload.email,
            role: rawRole,
            roles,
        };

        setUser(newUser);
        localStorage.setItem('user', JSON.stringify(newUser));

        if (roles.length > 1) {
            localStorage.removeItem('activeRole');
            setActiveRole(null);
            setNeedsRoleSelection(true);
        } else {
            const single = roles[0] ?? 'Collaborateur';
            setActiveRole(single);
            localStorage.setItem('activeRole', single);
            setNeedsRoleSelection(false);
        }
    };

    // ── selectRole ────────────────────────────────────
    const selectRole = (role: string) => {
        setActiveRole(role);
        localStorage.setItem('activeRole', role);
        setNeedsRoleSelection(false);
        setUser(prev => prev ? { ...prev, role } : prev);
    };

    // ── switchRole ────────────────────────────────────
    const switchRole = (role: string) => {
        selectRole(role);
    };

    // ── logout ────────────────────────────────────────
    const logout = () => {
        _clearSession();
        window.location.href = '/login';
    };

    const _clearSession = () => {
        localStorage.removeItem('token');
        localStorage.removeItem('user');
        localStorage.removeItem('activeRole');
        setUser(null);
        setActiveRole(null);
        setNeedsRoleSelection(false);
    };

    // ── Dérivés ───────────────────────────────────────
    const allRoles = user?.roles ?? [];
    const isMultiRole = allRoles.length > 1;

    const hasRole = (...roles: string[]): boolean =>
        !!activeRole && roles.includes(activeRole);

    const isCollaborateur = hasRole('Collaborateur', 'Collaboratrice');
    const isValidateur = hasRole('Validateur', 'Validatrice');
    const isFinance = hasRole('Finance');
    const isSuperUser = hasRole('superUtilisateur');
    const isVerificateurFinance = hasRole('VerificateurFinance');
    const isValidateurFinance = hasRole('ValidateurFinance');
    const isPresident = hasRole('President');


    return (
        <AuthContext.Provider value={{
            user,
            activeRole,
            allRoles,
            isMultiRole,
            needsRoleSelection,
            handleCallback,
            logout,
            selectRole,
            switchRole,
            hasRole,
            isCollaborateur,
            isValidateur,
            isFinance,
            isSuperUser,
            isVerificateurFinance,
            isValidateurFinance,
            isPresident
        }}>
            {children}
        </AuthContext.Provider>
    );
};

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