import { ref, computed, onMounted } from 'vue';
import axios from 'axios';
import { UserTypes } from '../../utils/UserTypes.js';
import { useUserStore } from '../../stores/user.js';

// Global reactive state to persist throughout the SPA session
const globalRole = ref(sessionStorage.getItem('user_acct_type') || UserTypes.PUBLIC);
const isFetching = ref(false);

/**
 * Fetches the user account type from the server.
 * Ensures only one request is made per session.
 */
async function fetchRole() {
    if (isFetching.value) return;

    // If we already have a specialized role in sessionStorage, don't fetch again
    const cached = sessionStorage.getItem('user_acct_type');
    if (cached && cached !== UserTypes.PUBLIC) {
        return;
    }

    isFetching.value = true;
    try {
        const response = await axios.get('/get/user/acct-type');
        let acctType = response.data?.acct_type;

        // Handle case where acct_type might be an object (Enum serialization)
        if (acctType && typeof acctType === 'object' && acctType.value) {
            acctType = acctType.value;
        }

        if (acctType) {
            globalRole.value = acctType;
            sessionStorage.setItem('user_acct_type', acctType);
        }
    } catch (error) {
        // If 401, we are likely a guest
        if (error.response?.status === 401) {
            globalRole.value = UserTypes.PUBLIC;
            sessionStorage.setItem('user_acct_type', UserTypes.PUBLIC);
        } else {
            console.warn('Failed to fetch user acct type from server:', error);
        }
    } finally {
        isFetching.value = false;
    }
}

// Initial fetch attempt if we don't have a definitive role
if (!sessionStorage.getItem('user_acct_type') || sessionStorage.getItem('user_acct_type') === UserTypes.PUBLIC) {
    fetchRole();
}

export function resetRole() {
    globalRole.value = UserTypes.PUBLIC;
    isFetching.value = false;
    sessionStorage.removeItem('user_acct_type');
}

/**
 * Composable for managing user roles and permissions in the frontend.
 * @param {Object} [user] - Optional user object for legacy support or specific overrides
 */
export function useAuth(user = null) {
    const userStore = useUserStore();
    
    // Priority: Explicitly passed user prop > user store > sessionStorage fallback
    const currentUser = computed(() => {
        if (user?.value ?? user) return user?.value ?? user;
        const storeUser = userStore.user;
        if (storeUser && Object.keys(storeUser).length > 0) return storeUser;
        
        try {
            const stored = sessionStorage.getItem('currentUser');
            return stored ? JSON.parse(stored) : null;
        } catch (e) {
            return null;
        }
    });

    const role = computed(() => {
        // Priority 1: User object passed directly or from store
        const localRole = userStore.acctType || currentUser.value?.acct_type;
        if (localRole) {
            if (typeof localRole === 'object' && localRole.value) return localRole.value;
            return localRole;
        }

        // Priority 2: Global fetched role
        return globalRole.value;
    });

    const hasRole = (targetRole) => {
        if (Array.isArray(targetRole)) {
            return targetRole.some(r => role.value === r);
        }
        return role.value === targetRole;
    };

    // Role-specific helpers
    const isUltimate = computed(() => role.value === UserTypes.ULTIMATE);
    const isSuperOperator = computed(() => role.value === UserTypes.SUPER_OPERATOR);
    const isOperator = computed(() => role.value === UserTypes.OPERATOR);
    const isCoordinator = computed(() => role.value === UserTypes.COORDINATOR);
    const isStoreOwner = computed(() => role.value === UserTypes.STORE_OWNER);
    const isStoreManager = computed(() => role.value === UserTypes.STORE_MANAGER);
    const isRider = computed(() => role.value === UserTypes.RIDER);
    const isSupplier = computed(() => role.value === UserTypes.SUPPLIER);
    const isSupplierOverseer = computed(() => role.value === UserTypes.SUPPLIER_OVERSEER);
    const isWholesaleBuyer = computed(() => role.value === UserTypes.WHOLESALE_BUYER);
    const isAudit = computed(() => role.value === UserTypes.AUDIT);
    const isUser = computed(() => role.value === UserTypes.USER);
    const isCoopOfficer = computed(() => role.value === UserTypes.COOP_OFFICER);
    const isCoopMember = computed(() => role.value === UserTypes.COOP_MEMBER);
    const isPOSTerminal = computed(() => role.value === UserTypes.POS_TERMINAL);
    const isPublic = computed(() => role.value === UserTypes.PUBLIC || !userStore.isLoggedIn);
    const isLoggedIn = computed(() => userStore.isLoggedIn);

    return {
        user: currentUser,
        role,
        hasRole,
        isUltimate,
        isSuperOperator,
        isOperator,
        isCoordinator,
        isStoreOwner,
        isStoreManager,
        isRider,
        isSupplier,
        isSupplierOverseer,
        isWholesaleBuyer,
        isAudit,
        isUser,
        isCoopOfficer,
        isCoopMember,
        isPOSTerminal,
        isPublic,
        isLoggedIn,
        UserTypes,
        refreshRole: fetchRole,
        // Expose the user store for direct access to user data
        userStore
    };
}

