import { ref } from 'vue';
import * as AuthRepository from '@/repositories/AuthRepository';

const userPermissions = ref(null);
const isLoading = ref(false);
let loadingPromise = null;

const DEFAULT_PERMISSIONS = {
    all: false,
    permissions: [],
};

const withTimeout = (promise, ms = 10000) => Promise.race([
    promise,
    new Promise((_, reject) => {
        setTimeout(() => reject(new Error(`Permissions timeout after ${ms}ms`)), ms);
    }),
]);

function isAuthFailure(error) {
    const status = error?.response?.status;
    return status === 401 || status === 403;
}

export const usePermissions = () => {
    const loadPermissions = async ({ force = false } = {}) => {
        if (!force && userPermissions.value !== null) {
            return userPermissions.value;
        }
        if (!force && loadingPromise) {
            return loadingPromise;
        }

        loadingPromise = (async () => {
            try {
                isLoading.value = true;
                const response = await withTimeout(AuthRepository.permissions(), 10000);

                if (response && typeof response === 'object') {
                    if (response.all !== undefined && response.permissions !== undefined) {
                        userPermissions.value = response;
                        return response;
                    }
                    if (response.roles && response.permissions) {
                        const isAdmin = response.roles.includes('Administrador');
                        userPermissions.value = {
                            all: isAdmin,
                            permissions: response.permissions || [],
                            roles: response.roles,
                        };
                        return userPermissions.value;
                    }
                }

                userPermissions.value = DEFAULT_PERMISSIONS;
                return userPermissions.value;
            } catch (error) {
                console.error('Error loading permissions:', error);
                userPermissions.value = null;
                if (isAuthFailure(error)) {
                    window.localStorage.removeItem('token');
                    throw error;
                }
                // Red / timeout: no inventar permisos vacíos como sesión válida
                throw error;
            } finally {
                isLoading.value = false;
                loadingPromise = null;
            }
        })();

        return loadingPromise;
    };

    const hasPermission = (permission) => {
        if (!userPermissions.value) {
            return false;
        }

        if (userPermissions.value.all === true) {
            return true;
        }

        return userPermissions.value.permissions?.includes(permission) || false;
    };

    const hasAnyPermission = (permissions) => {
        if (!Array.isArray(permissions)) {
            return hasPermission(permissions);
        }

        return permissions.some((permission) => hasPermission(permission));
    };

    const can = (permission) => hasPermission(permission);

    const resetPermissions = () => {
        userPermissions.value = null;
        loadingPromise = null;
    };

    const hasUsableAccess = () => {
        const p = userPermissions.value;
        if (!p) return false;
        if (p.all === true) return true;
        return Array.isArray(p.permissions) && p.permissions.length > 0;
    };

    return {
        userPermissions,
        isLoading,
        loadPermissions,
        hasPermission,
        hasAnyPermission,
        can,
        resetPermissions,
        hasUsableAccess,
    };
};
