/**
 * Note: URLValidator is available globally via /static/js/security/url-validator.js
 * Subscription Manager Component
 * Handles subscription UI in the news page modal
 */

class SubscriptionManager {
    constructor() {
        this.subscriptions = {};
        this.folders = [];
        this.currentFolder = 'all';
        this.initialized = false;
    }

    async initialize() {
        if (this.initialized) return;

        // Set up event listeners
        this.setupEventListeners();

        // Load data when modal opens
        const modal = document.getElementById('subscriptionsModal');
        if (modal) {
            modal.addEventListener('shown.bs.modal', () => {
                this.loadSubscriptionData();
            });
        }

        this.initialized = true;
    }

    setupEventListeners() {
        // Folder tab clicks
        document.addEventListener('click', (e) => {
            if (e.target.matches('#folderTabs .nav-link')) {
                e.preventDefault();
                this.switchFolder(e.target.dataset.folder);
            }
        });

        // Create folder button
        const createFolderBtn = document.getElementById('create-folder-btn');
        if (createFolderBtn) {
            createFolderBtn.addEventListener('click', () => this.showCreateFolderDialog());
        }

        // Subscription actions via delegation
        document.addEventListener('click', (e) => {
            if (e.target.matches('.edit-subscription-btn')) {
                this.editSubscription(e.target.dataset.subscriptionId);
            } else if (e.target.matches('.delete-subscription-btn')) {
                this.deleteSubscription(e.target.dataset.subscriptionId);
            } else if (e.target.matches('.pause-subscription-btn')) {
                this.toggleSubscriptionStatus(e.target.dataset.subscriptionId);
            }
        });
    }

    async loadSubscriptionData() {
        try {
            // Show loading state
            this.showLoading();

            // Load stats
            const statsResponse = await fetch('/news/api/subscription/stats');
            if (statsResponse.ok) {
                const stats = await statsResponse.json();
                this.updateStats(stats);
            }

            // Load folders
            const foldersResponse = await fetch('/news/api/subscription/folders');
            if (foldersResponse.ok) {
                this.folders = await foldersResponse.json();
                this.renderFolderTabs();
            }

            // Load organized subscriptions
            const subsResponse = await fetch('/news/api/subscription/subscriptions/organized');
            if (subsResponse.ok) {
                this.subscriptions = await subsResponse.json();
                this.renderSubscriptions();
            }

        } catch (error) {
            SafeLogger.error('Error loading subscription data:', error);
            this.showError('Failed to load subscriptions');
        }
    }

    updateStats(stats) {
        document.getElementById('total-subscriptions').textContent = stats.total_subscriptions || 0;
        document.getElementById('active-subscriptions').textContent = stats.active_subscriptions || 0;
        document.getElementById('total-folders').textContent = stats.total_folders || 0;

        if (stats.next_refresh) {
            const nextRefresh = new Date(stats.next_refresh);
            const now = new Date();
            const diff = nextRefresh - now;

            if (diff > 0) {
                const hours = Math.floor(diff / (1000 * 60 * 60));
                const minutes = Math.floor((diff % (1000 * 60 * 60)) / (1000 * 60));
                document.getElementById('next-refresh-time').textContent =
                    hours > 0 ? `${hours}h ${minutes}m` : `${minutes}m`;
            } else {
                document.getElementById('next-refresh-time').textContent = 'Soon';
            }
        }
    }

    renderFolderTabs() {
        const tabsContainer = document.getElementById('folderTabs');
        const existingTabs = tabsContainer.querySelectorAll('[data-folder]:not([data-folder="all"]):not([data-folder="Unfiled"])');

        // Remove existing dynamic tabs
        existingTabs.forEach(tab => tab.parentElement.remove());

        // Add folder tabs before the create button
        const createBtn = tabsContainer.querySelector('#create-folder-btn').parentElement;

        this.folders.forEach(folder => {
            const li = document.createElement('li');
            li.className = 'nav-item';
            // bearer:disable javascript_lang_dangerous_insert_html
            // eslint-disable-next-line no-unsanitized/property -- audited 2026-03-28: all interpolations use escapeHtml/esc, numeric coercion, or hardcoded strings
            li.innerHTML = `
                <button class="nav-link" data-folder="${this.escapeHtml(folder.name)}" type="button">
                    ${this.escapeHtml(folder.icon || '📁')} ${this.escapeHtml(folder.name)}
                    <span class="ldr-badge ldr-badge-secondary ms-1">${folder.item_count || 0}</span>
                </button>
            `;
            tabsContainer.insertBefore(li, createBtn);
        });
    }

    switchFolder(folderName) {
        this.currentFolder = folderName;

        // Update active tab
        document.querySelectorAll('#folderTabs .nav-link').forEach(link => {
            link.classList.toggle('active', link.dataset.folder === folderName);
        });

        // Render subscriptions for this folder
        this.renderSubscriptions();
    }

    renderSubscriptions() {
        const container = document.getElementById('subscriptions-list');

        // Get subscriptions for current folder
        let subsToShow = [];
        if (this.currentFolder === 'all') {
            // Show all subscriptions
            Object.values(this.subscriptions).forEach(folderSubs => {
                subsToShow = subsToShow.concat(folderSubs);
            });
        } else {
            subsToShow = this.subscriptions[this.currentFolder] || [];
        }

        if (subsToShow.length === 0) {
            container.innerHTML = `
                <div class="text-center p-4 text-muted">
                    <i class="bi bi-inbox fs-1"></i>
                    <p>No subscriptions in this folder</p>
                </div>
            `;
            return;
        }

        // Render subscription cards
        // eslint-disable-next-line no-unsanitized/property -- audited 2026-03-28: all interpolations use escapeHtml/esc, numeric coercion, or hardcoded strings
        container.innerHTML = subsToShow.map(sub => this.renderSubscriptionCard(sub)).join('');
    }

    renderSubscriptionCard(subscription) {
        const nextRefresh = new Date(subscription.next_refresh);
        const now = new Date();
        const timeUntil = this.formatTimeUntil(nextRefresh - now);

        return `
            <div class="ldr-subscription-card mb-3" data-subscription-id="${this.escapeHtml(subscription.id)}">
                <div class="d-flex justify-content-between align-items-start">
                    <div class="flex-grow-1">
                        <h6 class="mb-1">${this.escapeHtml(subscription.query_or_topic)}</h6>
                        <div class="text-muted small">
                            <span><i class="bi bi-clock"></i> Every ${subscription.refresh_interval_minutes} min</span>
                            <span class="ms-3"><i class="bi bi-arrow-clockwise"></i> Next: ${timeUntil}</span>
                            ${subscription.folder ? `<span class="ms-3"><i class="bi bi-folder"></i> ${this.escapeHtml(subscription.folder)}</span>` : ''}
                        </div>
                        ${subscription.notes ? `<p class="mb-0 mt-2 small">${this.escapeHtml(subscription.notes)}</p>` : ''}
                    </div>
                    <div class="ldr-subscription-actions">
                        <button class="btn btn-sm btn-outline-primary edit-subscription-btn"
                                data-subscription-id="${this.escapeHtml(subscription.id)}" title="Edit">
                            <i class="bi bi-pencil"></i>
                        </button>
                        <button class="btn btn-sm btn-outline-warning pause-subscription-btn"
                                data-subscription-id="${this.escapeHtml(subscription.id)}" title="${subscription.status === 'active' ? 'Pause' : 'Resume'}">
                            <i class="bi bi-${subscription.status === 'active' ? 'pause' : 'play'}"></i>
                        </button>
                        <button class="btn btn-sm btn-outline-danger delete-subscription-btn"
                                data-subscription-id="${this.escapeHtml(subscription.id)}" title="Delete">
                            <i class="bi bi-trash"></i>
                        </button>
                    </div>
                </div>
            </div>
        `;
    }

    async editSubscription(subscriptionId) {
        // Find the subscription
        let subscription = null;
        for (const folderSubs of Object.values(this.subscriptions)) {
            subscription = folderSubs.find(s => s.id === subscriptionId);
            if (subscription) break;
        }

        if (!subscription) return;

        // Create edit modal
        const modalHtml = `
            <div class="modal fade" id="editSubscriptionModal" tabindex="-1">
                <div class="modal-dialog">
                    <div class="modal-content">
                        <div class="modal-header">
                            <h5 class="modal-title">Edit Subscription</h5>
                            <button type="button" class="btn-close" data-bs-dismiss="modal"></button>
                        </div>
                        <div class="modal-body">
                            <div class="mb-3">
                                <label class="form-label">Update Frequency</label>
                                <select class="form-select" id="edit-frequency">
                                    <option value="60" ${subscription.refresh_interval_minutes === 60 ? 'selected' : ''}>Every hour</option>
                                    <option value="180" ${subscription.refresh_interval_minutes === 180 ? 'selected' : ''}>Every 3 hours</option>
                                    <option value="360" ${subscription.refresh_interval_minutes === 360 ? 'selected' : ''}>Every 6 hours</option>
                                    <option value="720" ${subscription.refresh_interval_minutes === 720 ? 'selected' : ''}>Every 12 hours</option>
                                    <option value="1440" ${subscription.refresh_interval_minutes === 1440 ? 'selected' : ''}>Daily</option>
                                    <option value="10080" ${subscription.refresh_interval_minutes === 10080 ? 'selected' : ''}>Weekly</option>
                                </select>
                            </div>
                            <div class="mb-3">
                                <label class="form-label">Folder</label>
                                <select class="form-select" id="edit-folder">
                                    <option value="">No folder</option>
                                    ${this.folders.map(f =>
            // Security: escapeHtml applied to folder name in option value and text
            `<option value="${this.escapeHtml(f.name)}" ${subscription.folder === f.name ? 'selected' : ''}>${this.escapeHtml(f.name)}</option>`
        ).join('')}
                                </select>
                            </div>
                            <div class="mb-3">
                                <label class="form-label">Notes</label>
                                <textarea class="ldr-form-control" id="edit-notes" rows="2"></textarea>
                            </div>
                        </div>
                        <div class="modal-footer">
                            <button type="button" class="btn btn-secondary" data-bs-dismiss="modal">Cancel</button>
                            <button type="button" class="btn btn-primary" id="save-subscription-edit">Save Changes</button>
                        </div>
                    </div>
                </div>
            </div>
        `;

        // Remove existing modal if any
        const existingModal = document.getElementById('editSubscriptionModal');
        if (existingModal) existingModal.remove();

        // bearer:disable javascript_lang_dangerous_insert_html
        // eslint-disable-next-line no-unsanitized/method -- audited 2026-03-28: variable built from escaped/numeric values above
        document.body.insertAdjacentHTML('beforeend', modalHtml);
        // Set textarea value via DOM property (not innerHTML) to avoid entity encoding issues
        document.getElementById('edit-notes').value = subscription.notes || '';
        const modal = new bootstrap.Modal(document.getElementById('editSubscriptionModal'));

        // Handle save
        document.getElementById('save-subscription-edit').addEventListener('click', async () => {
            const updates = {
                refresh_interval_minutes: parseInt(document.getElementById('edit-frequency').value, 10),
                folder: document.getElementById('edit-folder').value,
                notes: document.getElementById('edit-notes').value
            };

            await this.updateSubscription(subscriptionId, updates);
            modal.hide();
        });

        modal.show();
    }

    async updateSubscription(subscriptionId, updates) {
        try {
            const response = await fetch(`/news/api/subscription/subscriptions/${subscriptionId}`, {
                method: 'PUT',
                headers: {
                    'Content-Type': 'application/json',
                    'X-CSRFToken': this.getCSRFToken()
                },
                body: JSON.stringify(updates)
            });

            if (response.ok) {
                this.showSuccess('Subscription updated');
                await this.loadSubscriptionData();
            } else {
                this.showError('Failed to update subscription');
            }
        } catch (error) {
            SafeLogger.error('Error updating subscription:', error);
            this.showError('Error updating subscription');
        }
    }

    async deleteSubscription(subscriptionId) {
        if (!confirm('Are you sure you want to delete this subscription?')) return;

        try {
            const response = await fetch(`/news/api/subscription/subscriptions/${subscriptionId}`, {
                method: 'DELETE',
                headers: {
                    'X-CSRFToken': this.getCSRFToken()
                }
            });

            if (response.ok) {
                this.showSuccess('Subscription deleted');
                await this.loadSubscriptionData();
            } else {
                this.showError('Failed to delete subscription');
            }
        } catch (error) {
            SafeLogger.error('Error deleting subscription:', error);
            this.showError('Error deleting subscription');
        }
    }

    async toggleSubscriptionStatus(subscriptionId) {
        // Find the subscription
        let subscription = null;
        for (const folderSubs of Object.values(this.subscriptions)) {
            subscription = folderSubs.find(s => s.id === subscriptionId);
            if (subscription) break;
        }

        if (!subscription) return;

        const newStatus = subscription.status === 'active' ? 'paused' : 'active';
        await this.updateSubscription(subscriptionId, { status: newStatus });
    }

    showCreateFolderDialog() {
        const name = prompt('Enter folder name:');
        if (!name) return;

        this.createFolder(name);
    }

    async createFolder(name, color = null, icon = null) {
        try {
            const response = await fetch('/news/api/subscription/folders', {
                method: 'POST',
                headers: {
                    'Content-Type': 'application/json',
                    'X-CSRFToken': this.getCSRFToken()
                },
                body: JSON.stringify({ name, color, icon })
            });

            if (response.ok) {
                this.showSuccess('Folder created');
                await this.loadSubscriptionData();
            } else {
                const error = await response.json();
                this.showError(error.error || 'Failed to create folder');
            }
        } catch (error) {
            SafeLogger.error('Error creating folder:', error);
            this.showError('Error creating folder');
        }
    }

    // Utility methods
    formatTimeUntil(milliseconds) {
        if (milliseconds <= 0) return 'Now';

        const hours = Math.floor(milliseconds / (1000 * 60 * 60));
        const days = Math.floor(hours / 24);

        if (days > 0) return `${days}d`;
        if (hours > 0) return `${hours}h`;

        const minutes = Math.floor(milliseconds / (1000 * 60));
        return `${minutes}m`;
    }

    escapeHtml(text) {
        const div = document.createElement('div');
        div.textContent = text;
        return div.innerHTML;
    }

    getCSRFToken() {
        return window.api ? window.api.getCsrfToken() : '';
    }

    showLoading() {
        const container = document.getElementById('subscriptions-list');
        container.innerHTML = `
            <div class="text-center p-4">
                <div class="spinner-border" role="status">
                    <span class="visually-hidden">Loading...</span>
                </div>
            </div>
        `;
    }

    showError(message) {
        // Use existing alert system if available
        if (window.showAlert) {
            window.showAlert(message, 'error');
        } else {
            alert(message);
        }
    }

    showSuccess(message) {
        if (window.showAlert) {
            window.showAlert(message, 'success');
        } else {
            SafeLogger.log(message);
        }
    }
}

// Initialize when DOM is ready
document.addEventListener('DOMContentLoaded', () => {
    window.subscriptionManager = new SubscriptionManager();
    window.subscriptionManager.initialize();
});
