// FitPub - Authentication Management

/**
 * Authentication utilities for managing JWT tokens and user sessions
 */
const FitPubAuth = {
    /**
     * Get the stored JWT token
     * @returns {string|null} JWT token or null if not found
     */
    getToken: function() {
        return localStorage.getItem('jwtToken');
    },

    /**
     * Store JWT token
     * @param {string} token - JWT token to store
     */
    setToken: function(token) {
        localStorage.setItem('jwtToken', token);
    },

    /**
     * Remove stored JWT token
     */
    removeToken: function() {
        localStorage.removeItem('jwtToken');
        localStorage.removeItem('username');
    },

    /**
     * Get the stored username
     * @returns {string|null} Username or null if not found
     */
    getUsername: function() {
        return localStorage.getItem('username');
    },

    /**
     * Store username
     * @param {string} username - Username to store
     */
    setUsername: function(username) {
        localStorage.setItem('username', username);
    },

    /**
     * Check if user is authenticated
     * @returns {boolean} True if authenticated, false otherwise
     */
    isAuthenticated: function() {
        const token = this.getToken();
        if (!token) {
            return false;
        }

        // Check if token is expired
        try {
            const payload = this.parseJwt(token);
            const now = Math.floor(Date.now() / 1000);

            if (payload.exp && payload.exp < now) {
                // Token expired, remove it
                this.removeToken();
                return false;
            }

            return true;
        } catch (e) {
            console.error('Error parsing JWT:', e);
            this.removeToken();
            return false;
        }
    },

    /**
     * Parse JWT token to extract payload
     * @param {string} token - JWT token
     * @returns {object} Decoded payload
     */
    parseJwt: function(token) {
        try {
            const base64Url = token.split('.')[1];
            const base64 = base64Url.replace(/-/g, '+').replace(/_/g, '/');
            const jsonPayload = decodeURIComponent(
                atob(base64).split('').map(function(c) {
                    return '%' + ('00' + c.charCodeAt(0).toString(16)).slice(-2);
                }).join('')
            );
            return JSON.parse(jsonPayload);
        } catch (e) {
            console.error('Error parsing JWT:', e);
            throw e;
        }
    },

    /**
     * Get time until token expiration
     * @returns {number} Seconds until expiration, or 0 if expired/invalid
     */
    getTokenExpirationTime: function() {
        const token = this.getToken();
        if (!token) {
            return 0;
        }

        try {
            const payload = this.parseJwt(token);
            const now = Math.floor(Date.now() / 1000);

            if (payload.exp) {
                return Math.max(0, payload.exp - now);
            }

            return 0;
        } catch (e) {
            return 0;
        }
    },

    /**
     * Logout user
     */
    logout: function() {
        this.removeToken();
        window.location.href = '/login';
    },

    /**
     * Make an authenticated API request
     * @param {string} url - API endpoint URL
     * @param {object} options - Fetch options
     * @returns {Promise<Response>} Fetch response
     */
    authenticatedFetch: async function(url, options = {}) {
        const token = this.getToken();

        if (!token) {
            throw new Error('No authentication token found');
        }

        // Add Authorization header
        const headers = {
            ...options.headers,
            'Authorization': `Bearer ${token}`,
        };

        // If body is an object, set Content-Type to JSON
        if (options.body && typeof options.body === 'object') {
            headers['Content-Type'] = 'application/json';
            options.body = JSON.stringify(options.body);
        }

        const response = await fetch(url, {
            ...options,
            headers
        });

        // If unauthorized, redirect to login
        if (response.status === 401) {
            this.removeToken();
            window.location.href = '/login';
            throw new Error('Authentication failed');
        }

        return response;
    },

    /**
     * Initialize authentication checks and setup
     */
    init: function() {
        // Update navigation UI based on auth status
        this.updateNavigationUI();

        // Check registration status and update UI
        this.checkRegistrationStatus();

        // Check authentication status on page load
        this.checkAuthStatus();

        // Set up session expiration warning
        this.setupExpirationWarning();
    },

    /**
     * Check if registration is enabled and update navigation UI
     */
    checkRegistrationStatus: async function() {
        try {
            const response = await fetch('/api/auth/registration-status');
            const data = await response.json();

            if (!data.enabled) {
                // Hide registration link in navigation
                const registerLinks = document.querySelectorAll('a[href="/register"]');
                registerLinks.forEach(link => {
                    const parent = link.parentElement;
                    if (parent && parent.tagName === 'LI') {
                        parent.style.display = 'none';
                    }
                });
            }
        } catch (error) {
            console.error('Error checking registration status:', error);
            // Continue without hiding registration link if check fails
        }
    },

    /**
     * Update navigation UI based on authentication status
     */
    updateNavigationUI: function() {
        const authUserMenu = document.getElementById('authUserMenu');
        const guestMenu = document.getElementById('guestMenu');
        const usernameDisplay = document.getElementById('usernameDisplay');
        const myActivitiesLink = document.getElementById('myActivitiesLink');
        const uploadLink = document.getElementById('uploadLink');

        if (this.isAuthenticated()) {
            // Show authenticated menu, hide guest menu
            if (authUserMenu) {
                authUserMenu.classList.remove('d-none');
            }
            if (guestMenu) {
                guestMenu.style.display = 'none';
            }

            // Show authenticated navigation links
            if (myActivitiesLink) {
                myActivitiesLink.style.display = '';
                myActivitiesLink.parentElement.style.display = '';
            }
            if (uploadLink) {
                uploadLink.style.display = '';
                uploadLink.parentElement.style.display = '';
            }

            // Display username
            const username = this.getUsername();
            if (usernameDisplay && username) {
                usernameDisplay.textContent = username;
            }
        } else {
            // Show guest menu, hide authenticated menu
            if (authUserMenu) {
                authUserMenu.classList.add('d-none');
            }
            if (guestMenu) {
                guestMenu.style.display = '';
            }

            // Hide authenticated navigation links
            if (myActivitiesLink) {
                myActivitiesLink.style.display = 'none';
                myActivitiesLink.parentElement.style.display = 'none';
            }
            if (uploadLink) {
                uploadLink.style.display = 'none';
                uploadLink.parentElement.style.display = 'none';
            }
        }
    },

    /**
     * Check authentication status and handle accordingly
     */
    checkAuthStatus: function() {
        const currentPath = window.location.pathname;
        const publicPaths = ['/', '/login', '/timeline'];

        // Skip check for public paths
        if (publicPaths.includes(currentPath)) {
            return;
        }

        // Activity detail pages are public (for viewing public activities)
        // Pattern: /activities/{uuid}
        if (currentPath.startsWith('/activities/') && currentPath.split('/').length === 3) {
            return;
        }

        // Check if authenticated
        if (!this.isAuthenticated()) {
            // Redirect to login for protected pages
            window.location.href = '/login?redirect=' + encodeURIComponent(currentPath);
        }
    },

    /**
     * Set up warning for session expiration
     */
    setupExpirationWarning: function() {
        const token = this.getToken();
        if (!token) {
            return;
        }

        const expirationTime = this.getTokenExpirationTime();

        if (expirationTime > 0) {
            // Warn 5 minutes before expiration
            const warningTime = Math.max(0, (expirationTime - 300) * 1000);

            setTimeout(() => {
                if (this.isAuthenticated()) {
                    this.showExpirationWarning();
                }
            }, warningTime);
        }
    },

    /**
     * Show session expiration warning
     */
    showExpirationWarning: function() {
        if (window.FitPub && window.FitPub.showAlert) {
            window.FitPub.showAlert(
                'Your session will expire soon. Please save your work.',
                'warning'
            );
        } else {
            console.warn('Session expiring soon');
        }
    },

    /**
     * Refresh the current page with authentication
     */
    refreshPage: function() {
        window.location.reload();
    }
};

// Initialize authentication on page load
document.addEventListener('DOMContentLoaded', function() {
    FitPubAuth.init();
});

// Make available globally
window.FitPubAuth = FitPubAuth;
