/**
 * Timeline functionality for FitPub
 * Handles loading and displaying timeline activities with preview maps
 */

const FitPubTimeline = {
    currentPage: 0,
    totalPages: 0,
    timelineType: 'public',

    /**
     * Initialize the timeline
     * @param {string} type - Timeline type: 'public', 'federated', or 'user'
     */
    init: function(type) {
        this.timelineType = type;
        this.loadTimeline(0);
    },

    /**
     * Load timeline activities
     * @param {number} page - Page number to load
     */
    loadTimeline: async function(page) {
        const loadingIndicator = document.getElementById('loadingIndicator');
        const errorAlert = document.getElementById('errorAlert');
        const errorMessage = document.getElementById('errorMessage');
        const timelineList = document.getElementById('timelineList');
        const emptyState = document.getElementById('emptyState');
        const pagination = document.getElementById('pagination');

        try {
            // Show loading
            loadingIndicator.classList.remove('d-none');
            timelineList.classList.add('d-none');
            emptyState.classList.add('d-none');
            errorAlert.classList.add('d-none');
            pagination.classList.add('d-none');

            // Determine endpoint
            let endpoint;
            let fetchOptions = {};

            switch (this.timelineType) {
                case 'public':
                    endpoint = `/api/timeline/public?page=${page}&size=20`;
                    // Public timeline is optionally authenticated
                    fetchOptions = { useAuth: FitPubAuth.isAuthenticated() };
                    break;
                case 'federated':
                    endpoint = `/api/timeline/federated?page=${page}&size=20`;
                    fetchOptions = { useAuth: true };
                    break;
                case 'user':
                    endpoint = `/api/timeline/user?page=${page}&size=20`;
                    fetchOptions = { useAuth: true };
                    break;
                default:
                    throw new Error('Invalid timeline type');
            }

            // Fetch timeline data
            const response = fetchOptions.useAuth
                ? await FitPubAuth.authenticatedFetch(endpoint)
                : await fetch(endpoint);

            if (response.ok) {
                const data = await response.json();

                // Hide loading
                loadingIndicator.classList.add('d-none');

                if (data.content && data.content.length > 0) {
                    this.renderTimeline(data.content);
                    this.renderPagination(data);
                    timelineList.classList.remove('d-none');
                    pagination.classList.remove('d-none');
                } else {
                    emptyState.classList.remove('d-none');
                }

                this.totalPages = data.totalPages;
                this.currentPage = data.number;
            } else {
                throw new Error('Failed to load timeline');
            }
        } catch (error) {
            console.error('Error loading timeline:', error);
            loadingIndicator.classList.add('d-none');
            errorMessage.textContent = 'Failed to load timeline. Please try again.';
            errorAlert.classList.remove('d-none');
        }
    },

    /**
     * Render timeline activities
     * @param {Array} activities - Array of timeline activity objects
     */
    renderTimeline: function(activities) {
        const timelineList = document.getElementById('timelineList');

        timelineList.innerHTML = activities.map((activity, index) => {
            const mapId = `map-${activity.id}`;

            return `
                <div class="timeline-card card mb-4">
                    <div class="card-body">
                        <!-- User Info -->
                        <div class="d-flex align-items-center mb-3">
                            <a href="/users/${activity.username}" class="user-avatar me-3 text-decoration-none">
                                ${activity.avatarUrl
                                    ? `<img src="${activity.avatarUrl}" alt="${this.escapeHtml(activity.displayName || activity.username)}" class="rounded-circle" width="48" height="48">`
                                    : `<div class="avatar-placeholder rounded-circle">
                                        <i class="bi bi-person-circle"></i>
                                       </div>`
                                }
                            </a>
                            <div class="flex-grow-1">
                                <a href="/users/${activity.username}" class="text-decoration-none text-dark">
                                    <div class="fw-bold">${this.escapeHtml(activity.displayName || activity.username)}</div>
                                </a>
                                <div class="text-muted small">
                                    <a href="/users/${activity.username}" class="text-decoration-none text-muted">
                                        @${this.escapeHtml(activity.username)}
                                    </a>
                                    ${!activity.isLocal ? ' <i class="bi bi-globe2" title="Federated user"></i>' : ''}
                                    • ${this.formatTimeAgo(activity.startedAt)}
                                </div>
                            </div>
                            <div>
                                <span class="activity-type-badge activity-type-${activity.activityType.toLowerCase()}">
                                    ${activity.activityType}
                                </span>
                            </div>
                        </div>

                        <!-- Activity Title and Description -->
                        <h5 class="card-title">
                            <a href="/activities/${activity.id}" class="text-decoration-none text-dark">
                                ${this.escapeHtml(activity.title || 'Untitled Activity')}
                            </a>
                        </h5>

                        ${activity.description
                            ? `<p class="card-text">${this.escapeHtml(activity.description).substring(0, 200)}${activity.description.length > 200 ? '...' : ''}</p>`
                            : ''
                        }

                        <!-- Activity Metrics -->
                        <div class="mb-2">
                            <small class="text-muted">
                                <strong>Distance:</strong> ${this.formatDistance(activity.totalDistance)} •
                                <strong>Duration:</strong> ${this.formatDuration(activity.totalDurationSeconds)} •
                                <strong>Pace:</strong> ${this.formatPace(activity.totalDurationSeconds, activity.totalDistance)} •
                                <strong>Elevation:</strong> ${activity.elevationGain ? Math.round(activity.elevationGain) + 'm' : 'N/A'}
                            </small>
                        </div>

                        <!-- Preview Map -->
                        <div class="activity-preview-map" id="${mapId}" style="height: 300px; border-radius: 8px; margin-bottom: 1rem;">
                            <!-- Map will be rendered here -->
                        </div>

                        <!-- Activity Actions -->
                        <div class="d-flex gap-2 align-items-center">
                            <button
                                class="btn btn-sm ${activity.likedByCurrentUser ? 'btn-danger' : 'btn-outline-danger'} like-btn"
                                data-activity-id="${activity.id}"
                                data-liked="${activity.likedByCurrentUser || false}"
                            >
                                <i class="bi bi-heart${activity.likedByCurrentUser ? '-fill' : ''}"></i>
                                <span class="like-count">${activity.likesCount || 0}</span>
                            </button>
                            <a href="/activities/${activity.id}" class="btn btn-sm btn-outline-primary">
                                <i class="bi bi-eye"></i> View Details
                            </a>
                            <span class="ms-auto text-muted small d-flex align-items-center gap-2">
                                ${activity.commentsCount > 0 ? `<span><i class="bi bi-chat-left-text"></i> ${activity.commentsCount}</span>` : ''}
                                <span>
                                    <i class="bi bi-${this.getVisibilityIcon(activity.visibility)}"></i>
                                    ${activity.visibility}
                                </span>
                            </span>
                        </div>
                    </div>
                </div>
            `;
        }).join('');

        // Render maps after DOM is updated
        setTimeout(() => {
            activities.forEach(activity => {
                this.renderPreviewMap(activity);
            });
        }, 100);

        // Setup like button handlers
        this.setupLikeButtons();
    },

    /**
     * Setup like button click handlers
     */
    setupLikeButtons: function() {
        const likeButtons = document.querySelectorAll('.like-btn');

        likeButtons.forEach(btn => {
            btn.addEventListener('click', async (e) => {
                e.preventDefault();

                // Check if user is authenticated
                if (!FitPubAuth.isAuthenticated()) {
                    window.location.href = '/login';
                    return;
                }

                const activityId = btn.dataset.activityId;
                const isLiked = btn.dataset.liked === 'true';
                const icon = btn.querySelector('i');
                const countSpan = btn.querySelector('.like-count');

                try {
                    // Disable button during request
                    btn.disabled = true;

                    if (isLiked) {
                        // Unlike
                        const response = await FitPubAuth.authenticatedFetch(
                            `/api/activities/${activityId}/likes`,
                            { method: 'DELETE' }
                        );

                        if (response.ok) {
                            // Update UI
                            btn.classList.remove('btn-danger');
                            btn.classList.add('btn-outline-danger');
                            icon.classList.remove('bi-heart-fill');
                            icon.classList.add('bi-heart');
                            btn.dataset.liked = 'false';

                            // Update count
                            const currentCount = parseInt(countSpan.textContent) || 0;
                            countSpan.textContent = Math.max(0, currentCount - 1);
                        }
                    } else {
                        // Like
                        const response = await FitPubAuth.authenticatedFetch(
                            `/api/activities/${activityId}/likes`,
                            { method: 'POST' }
                        );

                        if (response.ok) {
                            // Update UI
                            btn.classList.remove('btn-outline-danger');
                            btn.classList.add('btn-danger');
                            icon.classList.remove('bi-heart');
                            icon.classList.add('bi-heart-fill');
                            btn.dataset.liked = 'true';

                            // Update count
                            const currentCount = parseInt(countSpan.textContent) || 0;
                            countSpan.textContent = currentCount + 1;
                        }
                    }
                } catch (error) {
                    console.error('Error toggling like:', error);
                } finally {
                    btn.disabled = false;
                }
            });
        });
    },

    /**
     * Render preview map for an activity
     * @param {Object} activity - Activity object
     */
    renderPreviewMap: async function(activity) {
        const mapId = `map-${activity.id}`;
        const mapElement = document.getElementById(mapId);

        if (!mapElement) {
            console.warn('Map element not found:', mapId);
            return;
        }

        try {
            // Fetch track data
            const response = await fetch(`/api/activities/${activity.id}/track`);

            if (!response.ok) {
                throw new Error('Failed to load track data');
            }

            const trackData = await response.json();

            if (!trackData.features || trackData.features.length === 0) {
                mapElement.innerHTML = '<div class="d-flex align-items-center justify-content-center h-100 bg-light"><p class="text-muted">No GPS data available</p></div>';
                return;
            }

            // Initialize map
            const map = L.map(mapId, {
                zoomControl: true,
                scrollWheelZoom: false,
                dragging: true,
                touchZoom: true
            });

            // Add tile layer
            L.tileLayer('https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png', {
                attribution: '© OpenStreetMap contributors',
                maxZoom: 18
            }).addTo(map);

            // Add track to map
            const geoJsonLayer = L.geoJSON(trackData, {
                style: {
                    color: '#0d6efd',
                    weight: 3,
                    opacity: 0.8
                }
            }).addTo(map);

            // Fit map to track bounds
            map.fitBounds(geoJsonLayer.getBounds(), { padding: [20, 20] });

            // Privacy: Start/finish markers removed to protect athlete home locations

        } catch (error) {
            console.error('Error rendering map:', error);
            mapElement.innerHTML = '<div class="d-flex align-items-center justify-content-center h-100 bg-light"><p class="text-muted">Failed to load map</p></div>';
        }
    },

    /**
     * Render pagination controls
     * @param {Object} data - Pagination data from API
     */
    renderPagination: function(data) {
        const paginationList = document.getElementById('paginationList');
        let html = '';

        // Previous button
        html += `
            <li class="page-item ${data.first ? 'disabled' : ''}">
                <a class="page-link" href="#" onclick="FitPubTimeline.changePage(${data.number - 1}); return false;">
                    <i class="bi bi-chevron-left"></i>
                </a>
            </li>
        `;

        // Page numbers
        const startPage = Math.max(0, data.number - 2);
        const endPage = Math.min(data.totalPages - 1, data.number + 2);

        if (startPage > 0) {
            html += `<li class="page-item disabled"><span class="page-link">...</span></li>`;
        }

        for (let i = startPage; i <= endPage; i++) {
            html += `
                <li class="page-item ${i === data.number ? 'active' : ''}">
                    <a class="page-link" href="#" onclick="FitPubTimeline.changePage(${i}); return false;">${i + 1}</a>
                </li>
            `;
        }

        if (endPage < data.totalPages - 1) {
            html += `<li class="page-item disabled"><span class="page-link">...</span></li>`;
        }

        // Next button
        html += `
            <li class="page-item ${data.last ? 'disabled' : ''}">
                <a class="page-link" href="#" onclick="FitPubTimeline.changePage(${data.number + 1}); return false;">
                    <i class="bi bi-chevron-right"></i>
                </a>
            </li>
        `;

        paginationList.innerHTML = html;
    },

    /**
     * Change page
     * @param {number} page - Page number
     */
    changePage: function(page) {
        this.loadTimeline(page);
        window.scrollTo({ top: 0, behavior: 'smooth' });
    },

    /**
     * Format distance in meters to km
     * @param {number} meters - Distance in meters
     * @returns {string} Formatted distance
     */
    formatDistance: function(meters) {
        if (!meters) return 'N/A';
        if (meters >= 1000) {
            return (meters / 1000).toFixed(1) + ' km';
        }
        return Math.round(meters) + ' m';
    },

    /**
     * Format duration in seconds
     * @param {number} seconds - Duration in seconds
     * @returns {string} Formatted duration
     */
    formatDuration: function(seconds) {
        if (!seconds) return 'N/A';
        const hours = Math.floor(seconds / 3600);
        const minutes = Math.floor((seconds % 3600) / 60);
        const secs = Math.floor(seconds % 60);

        if (hours > 0) {
            return `${hours}h ${minutes}m`;
        }
        if (minutes > 0) {
            return `${minutes}m ${secs}s`;
        }
        return `${secs}s`;
    },

    /**
     * Format pace (min/km)
     * @param {number} seconds - Total duration in seconds
     * @param {number} meters - Total distance in meters
     * @returns {string} Formatted pace
     */
    formatPace: function(seconds, meters) {
        if (!seconds || !meters || meters === 0) return 'N/A';

        const km = meters / 1000;
        const paceSeconds = seconds / km;
        const paceMinutes = Math.floor(paceSeconds / 60);
        const paceSecs = Math.floor(paceSeconds % 60);

        return `${paceMinutes}:${paceSecs.toString().padStart(2, '0')}/km`;
    },

    /**
     * Format timestamp to "time ago" format
     * @param {string} timestamp - ISO timestamp
     * @returns {string} Time ago string
     */
    formatTimeAgo: function(timestamp) {
        const date = new Date(timestamp);
        const now = new Date();
        const secondsAgo = Math.floor((now - date) / 1000);

        if (secondsAgo < 60) return 'just now';
        if (secondsAgo < 3600) return `${Math.floor(secondsAgo / 60)}m ago`;
        if (secondsAgo < 86400) return `${Math.floor(secondsAgo / 3600)}h ago`;
        if (secondsAgo < 604800) return `${Math.floor(secondsAgo / 86400)}d ago`;

        return date.toLocaleDateString();
    },

    /**
     * Get visibility icon
     * @param {string} visibility - Visibility level
     * @returns {string} Bootstrap icon name
     */
    getVisibilityIcon: function(visibility) {
        switch (visibility) {
            case 'PUBLIC': return 'globe';
            case 'FOLLOWERS': return 'people';
            case 'PRIVATE': return 'lock';
            default: return 'question-circle';
        }
    },

    /**
     * Escape HTML to prevent XSS
     * @param {string} text - Text to escape
     * @returns {string} Escaped text
     */
    escapeHtml: function(text) {
        const div = document.createElement('div');
        div.textContent = text;
        return div.innerHTML;
    }
};
