/**
 * Scheduled Blogs JavaScript - Modern ES6+ OOP Implementation
 * Handles all scheduled blog AJAX operations and modal dialogs
 */

class ScheduledBlogsManager {
    constructor() {
        this.ajaxUrl = scheduledBlogsAjax.ajaxurl;
        this.nonce = scheduledBlogsAjax.nonce;
        this.modalSystem = new ModalSystem();
        this.tableManager = new TableManager();
        this.formHandler = new FormHandler(this.ajaxUrl, this.nonce, this.modalSystem);
        this.scheduleActions = new ScheduleActions(this.ajaxUrl, this.nonce, this.modalSystem);
        
        this.init();
    }
    
    init() {
        this.bindEvents();
    }
    
    bindEvents() {
        // Form submission for creating schedules
        const schedulerForm = document.getElementById('blog82ai-scheduler-form');
        if (schedulerForm) {
            schedulerForm.addEventListener('submit', (e) => {
                this.formHandler.handleScheduleCreation(e);
            });
        }
        
        // Edit form submission
        const editForm = document.getElementById('edit-schedule-form');
        if (editForm) {
            editForm.addEventListener('submit', (e) => {
                this.formHandler.handleScheduleUpdate(e);
            });
        }
        
        // Select all checkbox
        const selectAllCheckbox = document.getElementById('select-all-schedules');
        if (selectAllCheckbox) {
            selectAllCheckbox.addEventListener('change', () => {
                this.tableManager.toggleSelectAll();
            });
        }
        
        // Filter events
        this.bindFilterEvents();
        
        // Global function bindings for onclick handlers
        this.bindGlobalFunctions();
    }
    
    bindFilterEvents() {
        const categoryFilter = document.getElementById('filter-category');
        const statusFilter = document.getElementById('filter-status');
        const searchInput = document.getElementById('search-schedules');
        
        if (categoryFilter) {
            categoryFilter.addEventListener('change', () => {
                this.tableManager.filterByCategory();
            });
        }
        
        if (statusFilter) {
            statusFilter.addEventListener('change', () => {
                this.tableManager.filterByStatus();
            });
        }
        
        if (searchInput) {
            searchInput.addEventListener('input', () => {
                this.tableManager.searchSchedules();
            });
        }
    }
    
    bindGlobalFunctions() {
        // Bind functions to window for onclick handlers
        window.editSchedule = (scheduleId) => {
            this.scheduleActions.editSchedule(scheduleId);
        };
        
        window.viewScheduleDetails = (scheduleId) => {
            this.scheduleActions.viewScheduleDetails(scheduleId);
        };
        
        window.pauseSchedule = (scheduleId) => {
            this.scheduleActions.pauseSchedule(scheduleId);
        };
        
        window.resumeSchedule = (scheduleId) => {
            this.scheduleActions.resumeSchedule(scheduleId);
        };
        
        window.deleteSchedule = (scheduleId) => {
            this.scheduleActions.deleteSchedule(scheduleId);
        };
        
        window.fetchNow = (category) => {
            this.scheduleActions.fetchNow(category);
        };
        
        window.applyBulkAction = () => {
            this.scheduleActions.applyBulkAction();
        };
        
        window.closeEditModal = () => {
            this.modalSystem.closeEditModal();
        };
        
        window.closeViewModal = () => {
            this.modalSystem.closeViewModal();
        };
        // Provide global functions used by inline HTML buttons in the PHP template
        window.closeMessageModal = () => {
            this.modalSystem.closeMessageModal();
        };
        window.closeLoadingModal = () => {
            this.modalSystem.closeLoadingModal();
        };
        window.closeConfirmationModal = () => {
            this.modalSystem.closeConfirmationModal();
        };
        
        window.filterByCategory = () => {
            this.tableManager.filterByCategory();
        };
        
        window.filterByStatus = () => {
            this.tableManager.filterByStatus();
        };
        
        window.searchSchedules = () => {
            this.tableManager.searchSchedules();
        };
        
        window.clearAllFilters = () => {
            this.tableManager.clearAllFilters();
        };
    }
    
    refreshScheduleComponents() {
        this.modalSystem.showLoadingModal('Refreshing data...');
        
        fetch(this.ajaxUrl, {
            method: 'POST',
            headers: {
                'Content-Type': 'application/x-www-form-urlencoded',
            },
            body: new URLSearchParams({
                action: 'blog82ai_refresh_schedules',
                nonce: this.nonce
            })
        })
        .then(response => response.json())
        .then(data => {
            this.modalSystem.closeLoadingModal();
            if (data.success) {
                this.tableManager.updateScheduleTable(data.data.schedules);
                this.tableManager.updateCategoryDropdown(data.data.categories);
                this.tableManager.updateStats(data.data.stats);
            } else {
                console.error('Failed to refresh data:', data.data);
                this.modalSystem.showMessageModal('Error', 'Failed to refresh data: ' + data.data, '❌', false);
            }
        })
        .catch(error => {
            this.modalSystem.closeLoadingModal();
            console.error('Error refreshing schedule components:', error);
            this.modalSystem.showMessageModal('Error', 'Error refreshing components. Please refresh the page.', '❌', false);
        });
    }
}

class ModalSystem {
    constructor() {
        this.confirmationModal = document.getElementById('confirmation-modal');
        this.messageModal = document.getElementById('message-modal');
        this.loadingModal = document.getElementById('loading-modal');
        this.editModal = document.getElementById('edit-schedule-modal');
        this.viewModal = document.getElementById('view-details-modal');
    }
    // showConfirmationModal(title, message, icon, confirmText, confirmAction, confirmColor = '#dc3545', requireTyped = false)
    // If requireTyped is true, the modal will reveal an input field and require the user to type 'DELETE' before allowing the action.
    showConfirmationModal(title, message, icon, confirmText, confirmAction, confirmColor = '#dc3545', requireTyped = false) {
        document.getElementById('confirmation-title').textContent = title;
        document.getElementById('confirmation-message').textContent = message;
        document.getElementById('confirmation-icon').textContent = icon;

        const typedArea = document.getElementById('confirmation-typed-area');
        const typedInput = document.getElementById('confirmation-input');
        if (typedArea) {
            if (requireTyped) {
                typedArea.style.display = 'block';
                if (typedInput) {
                    typedInput.value = '';
                    setTimeout(() => typedInput.focus(), 50);
                }
            } else {
                typedArea.style.display = 'none';
                if (typedInput) typedInput.value = '';
            }
        }

        const confirmBtn = document.getElementById('confirmation-confirm');
        confirmBtn.textContent = confirmText;
        confirmBtn.style.background = confirmColor;
        confirmBtn.onclick = () => {
            if (requireTyped) {
                const value = typedInput ? typedInput.value.trim() : '';
                if (value !== 'DELETE') {
                    this.showMessageModal('Cancelled', 'Typed confirmation did not match. Action cancelled.', '⚠️', false);
                    return;
                }
            }
            this.closeConfirmationModal();
            confirmAction();
        };

        this.confirmationModal.style.display = 'block';
    }
    
    showMessageModal(title, message, icon, isSuccess = true) {
        document.getElementById('message-title').textContent = title;
        document.getElementById('message-text').textContent = message;
        document.getElementById('message-icon').textContent = icon;
        document.getElementById('message-title').style.color = isSuccess ? '#28a745' : '#dc3545';
        this.messageModal.style.display = 'block';
    }
    
    showLoadingModal(message = 'Please wait while we process your request.') {
        document.getElementById('loading-message').textContent = message;
        this.loadingModal.style.display = 'block';
    }

    showPreviewModal(title, htmlContent, editUrl, viewUrl) {
        // Create modal container if not present
        let preview = document.getElementById('generated-preview-modal');
        if (!preview) {
            preview = document.createElement('div');
            preview.id = 'generated-preview-modal';
            preview.style.position = 'fixed';
            preview.style.top = '0';
            preview.style.left = '0';
            preview.style.width = '100%';
            preview.style.height = '100%';
            preview.style.background = 'rgba(0,0,0,0.6)';
            preview.style.display = 'flex';
            preview.style.alignItems = 'center';
            preview.style.justifyContent = 'center';
            preview.style.zIndex = '99999';
            preview.innerHTML = `
                <div id="generated-preview-inner" style="background:#fff; max-width:900px; width:90%; padding:20px; border-radius:6px; box-shadow:0 10px 30px rgba(0,0,0,0.3);">
                    <div style="display:flex; justify-content:space-between; align-items:flex-start; margin-bottom:8px;">
                        <div>
                            <div id="generated-preview-status" style="color:#155724; background:#d4edda; display:inline-block; padding:6px 10px; border-radius:4px; font-weight:600; font-size:13px;">Blog Generated Successfully</div>
                            <h2 id="generated-preview-title" style="margin:8px 0 0 0; font-size:18px;"></h2>
                        </div>
                        <button id="generated-preview-close" class="button">Close</button>
                    </div>
                    <div id="generated-preview-content" style="max-height:60vh; overflow:auto; border-top:1px solid #eee; padding-top:12px;"></div>
                    <div style="margin-top:15px; text-align:right;">
                        <a id="generated-preview-edit" class="button button-primary" style="margin-right:8px">Edit</a>
                        <a id="generated-preview-view" class="button">View</a>
                    </div>
                </div>
            `;
            document.body.appendChild(preview);

            // Close handlers
            preview.addEventListener('click', function(e){ if (e.target === preview) preview.style.display = 'none'; });
            preview.querySelector('#generated-preview-close').addEventListener('click', function(){ preview.style.display = 'none'; });
        }

        // Set title under status header
        document.getElementById('generated-preview-title').textContent = title;

        // Ensure the preview content looks elegant:
        // - Trim leading markdown headers (e.g. "# Title") which are often duplicated
        // - Collapse long whitespace and limit initial preview length for readability
        const contentEl = document.getElementById('generated-preview-content');
        let cleaned = (htmlContent || '').toString();

        // Remove a leading markdown header line (e.g. "# Title\n") if present
        cleaned = cleaned.replace(/^\s*#{1,6}\s*.*(\r?\n)?/, '');
        // If content starts with the title, remove it (common when API returns markdown)
        const titlePrefixRegex = new RegExp('^\\s*' + escapeRegExp(title) + '\\s*', 'i');
        if (title && titlePrefixRegex.test(cleaned)) {
            cleaned = cleaned.replace(titlePrefixRegex, '');
        }

        // Collapse multiple newlines to paragraphs
        cleaned = cleaned.replace(/\n{2,}/g, '\n\n');

        // Limit preview length to 800 characters for modal display
        const maxLength = 800;
        let previewHtml = cleaned;
        if (cleaned.length > maxLength) {
            previewHtml = cleaned.substring(0, maxLength).trim() + '…';
        }

        // Simple markdown-to-HTML conversions for a nicer preview (headings, bold, italics, links)
        previewHtml = previewHtml
            .replace(/^(#{1,6})\s*(.+)$/gm, '<strong>$2</strong>')
            .replace(/\*\*(.+?)\*\*/g, '<strong>$1</strong>')
            .replace(/\*(.+?)\*/g, '<em>$1</em>')
            .replace(/\[(.+?)\]\((https?:\/\/[^)]+)\)/g, '<a href="$2" target="_blank" rel="noopener">$1</a>')
            .replace(/`(.+?)`/g, '<code>$1</code>')
            .replace(/\n/g, '<br>');

        contentEl.innerHTML = '<div style="font-size:14px; color:#333; line-height:1.6;">' + previewHtml + '</div>';

        const editEl = document.getElementById('generated-preview-edit');
        const viewEl = document.getElementById('generated-preview-view');
        if (editUrl) {
            editEl.setAttribute('href', editUrl);
            editEl.setAttribute('target', '_blank');
            editEl.style.display = '';
        } else {
            editEl.style.display = 'none';
        }
        if (viewUrl) {
            viewEl.setAttribute('href', viewUrl);
            viewEl.setAttribute('target', '_blank');
            viewEl.style.display = '';
        } else {
            viewEl.style.display = 'none';
        }

        preview.style.display = 'flex';
    }
    
    closeConfirmationModal() {
        // Clear and hide typed confirmation input when closing
        const typedArea = document.getElementById('confirmation-typed-area');
        const typedInput = document.getElementById('confirmation-input');
        if (typedInput) typedInput.value = '';
        if (typedArea) typedArea.style.display = 'none';

        this.confirmationModal.style.display = 'none';
    }
    
    closeMessageModal() {
        this.messageModal.style.display = 'none';
    }
    
    closeLoadingModal() {
        this.loadingModal.style.display = 'none';
    }
    
    closeEditModal() {
        this.editModal.style.display = 'none';
    }
    
    closeViewModal() {
        this.viewModal.style.display = 'none';
    }
}

class TableManager {
    constructor() {
        this.tableBody = document.getElementById('blog82ai-schedules-tbody');
    }
    
    updateScheduleTable(schedules) {
        if (!this.tableBody) {
            console.error('Table body not found!');
            return;
        }
        
        let html = '';
        schedules.forEach(schedule => {
            const statusClass = schedule.status.toLowerCase();
            const pauseResumeButton = schedule.status === 'paused' 
                ? `<button class="button button-small" onclick="resumeSchedule('${schedule.id}')">
                     <span class="dashicons dashicons-controls-play" style="font-size: 12px; width: 12px; height: 12px;"></span> Resume
                   </button>`
                : `<button class="button button-small" onclick="pauseSchedule('${schedule.id}')">
                     <span class="dashicons dashicons-controls-pause" style="font-size: 12px; width: 12px; height: 12px;"></span> Pause
                   </button>`;
            
            html += `
                <tr data-category="${schedule.category}" data-status="${schedule.status}">
                    <td><input type="checkbox" class="schedule-checkbox" value="${schedule.id}"></td>
                    <td>
                        <strong>${schedule.category_hierarchy}</strong>
                        <div class="row-actions">
                            <span class="edit"><a href="#" onclick="editSchedule('${schedule.id}')">Edit</a> | </span>
                            <span class="view"><a href="#" onclick="viewScheduleDetails('${schedule.id}')">View Details</a></span>
                        </div>
                    </td>
                    <td>${schedule.start_date}</td>
                    <td>${schedule.run_time}</td>
                    <td>${schedule.frequency}</td>
                    <td>${schedule.next_run}</td>
                    <td>
                        <span class="status-badge status-${statusClass}">
                            ${schedule.status.toUpperCase()}
                        </span>
                    </td>
                    <td>
                        ${pauseResumeButton}
                        <button class="button button-small" onclick="deleteSchedule('${schedule.id}')">
                            <span class="dashicons dashicons-trash" style="font-size: 12px; width: 12px; height: 12px;"></span> Delete
                        </button>
                        <button class="button button-small" onclick="fetchNow('${schedule.category}')">
                            <span class="dashicons dashicons-download" style="font-size: 12px; width: 12px; height: 12px;"></span> Fetch Now
                        </button>
                    </td>
                </tr>
            `;
        });
        
        if (schedules.length === 0) {
            html = '<tr><td colspan="8" style="text-align: center; padding: 20px;">No schedules found</td></tr>';
        }
        
        this.tableBody.innerHTML = html;
    }
    
    updateCategoryDropdown(categories) {
        const dropdown = document.getElementById('schedule-category');
        if (!dropdown) {
            console.error('Category dropdown not found!');
            return;
        }
        
        // Keep the first option (Select Category)
        dropdown.innerHTML = '<option value="">Select Category</option>';
        
        categories.forEach(category => {
            const option = document.createElement('option');
            option.value = category.value;
            option.textContent = category.label;
            dropdown.appendChild(option);
        });
    }
    
    updateStats(stats) {
        const statItems = document.querySelectorAll('.blog82ai-stat-item');
        
        if (statItems.length >= 4) {
            statItems[0].querySelector('.blog82ai-stat-value').textContent = stats.total_schedules;
            statItems[1].querySelector('.blog82ai-stat-value').textContent = stats.active_schedules;
            statItems[2].querySelector('.blog82ai-stat-value').textContent = stats.paused_schedules;
            statItems[3].querySelector('.blog82ai-stat-value').textContent = stats.blogs_this_week;
        }
    }
    
    filterByCategory() {
        const selectedCategory = document.getElementById('filter-category').value;
        const rows = document.querySelectorAll('#blog82ai-schedules-tbody tr');
        
        rows.forEach(row => {
            if (row.children.length === 1) return;
            
            if (selectedCategory === '' || row.dataset.category === selectedCategory) {
                row.style.display = '';
            } else {
                row.style.display = 'none';
            }
        });
        
        this.updateDisplayCount();
    }
    
    filterByStatus() {
        const selectedStatus = document.getElementById('filter-status').value;
        const rows = document.querySelectorAll('#blog82ai-schedules-tbody tr');
        
        rows.forEach(row => {
            if (row.children.length === 1) return;
            
            if (selectedStatus === '' || row.dataset.status === selectedStatus) {
                row.style.display = '';
            } else {
                row.style.display = 'none';
            }
        });
        
        this.updateDisplayCount();
    }
    
    searchSchedules() {
        const searchTerm = document.getElementById('search-schedules').value.toLowerCase();
        const rows = document.querySelectorAll('#blog82ai-schedules-tbody tr');
        
        rows.forEach(row => {
            if (row.children.length === 1) return;
            
            const text = row.textContent.toLowerCase();
            if (searchTerm === '' || text.includes(searchTerm)) {
                row.style.display = '';
            } else {
                row.style.display = 'none';
            }
        });
        
        this.updateDisplayCount();
    }
    
    updateDisplayCount() {
        const visibleRows = document.querySelectorAll('#blog82ai-schedules-tbody tr:not([style*="display: none"])');
        const count = Array.from(visibleRows).filter(row => row.children.length > 1).length;
        const displayElement = document.querySelector('.displaying-num');
        if (displayElement) {
            displayElement.textContent = count + ' total schedules';
        }
    }
    
    clearAllFilters() {
        document.getElementById('filter-category').value = '';
        document.getElementById('filter-status').value = '';
        document.getElementById('search-schedules').value = '';
        
        const rows = document.querySelectorAll('#blog82ai-schedules-tbody tr');
        rows.forEach(row => {
            row.style.display = '';
        });
        
        this.updateDisplayCount();
    }
    
    toggleSelectAll() {
        const selectAll = document.getElementById('select-all-schedules');
        const checkboxes = document.querySelectorAll('.schedule-checkbox');
        
        checkboxes.forEach(checkbox => {
            checkbox.checked = selectAll.checked;
        });
    }
}

// Utility: escape text to use inside RegExp
function escapeRegExp(string) {
    return String(string).replace(/[.*+?^${}()|[\]\\]/g, '\\$&');
}

class FormHandler {
    constructor(ajaxUrl, nonce, modalSystem) {
        this.ajaxUrl = ajaxUrl;
        this.nonce = nonce;
        this.modalSystem = modalSystem;
    }
    
    async handleScheduleCreation(event) {
        event.preventDefault();
        
        this.modalSystem.showLoadingModal('Creating schedule...');
        
        const formData = new FormData(event.target);
        formData.append('action', 'blog82ai_create_schedule');
        formData.append('nonce', this.nonce);
        
        try {
            const response = await fetch(this.ajaxUrl, {
                method: 'POST',
                body: formData
            });
            
            const data = await response.json();
            this.modalSystem.closeLoadingModal();
            
            if (data.success) {
                this.modalSystem.showMessageModal('Success', 'Schedule created successfully!', '✅', true);
                event.target.reset();
                setTimeout(() => {
                    this.modalSystem.closeMessageModal();
                    scheduledBlogsManager.refreshScheduleComponents();
                }, 1500);
            } else {
                this.modalSystem.showMessageModal('Error', 'Error creating schedule: ' + data.data, '❌', false);
            }
        } catch (error) {
            this.modalSystem.closeLoadingModal();
            console.error('AJAX Error creating schedule:', error);
            this.modalSystem.showMessageModal('Error', 'Error creating schedule. Please try again.', '❌', false);
        }
    }
    
    async handleScheduleUpdate(event) {
        event.preventDefault();
        
        const formData = new FormData(event.target);
        formData.append('action', 'blog82ai_update_schedule');
        formData.append('nonce', this.nonce);
        
        try {
            const response = await fetch(this.ajaxUrl, {
                method: 'POST',
                body: formData
            });
            
            const data = await response.json();
            
            if (data.success) {
                this.modalSystem.showMessageModal('Success', 'Schedule updated successfully!', '✅', true);
                this.modalSystem.closeEditModal();
                setTimeout(() => {
                    this.modalSystem.closeMessageModal();
                    scheduledBlogsManager.refreshScheduleComponents();
                }, 1500);
            } else {
                this.modalSystem.showMessageModal('Error', 'Error updating schedule: ' + data.data, '❌', false);
            }
        } catch (error) {
            console.error('AJAX Error updating schedule:', error);
            this.modalSystem.showMessageModal('Error', 'Error updating schedule. Please try again.', '❌', false);
        }
    }
}

class ScheduleActions {
    constructor(ajaxUrl, nonce, modalSystem) {
        this.ajaxUrl = ajaxUrl;
        this.nonce = nonce;
        this.modalSystem = modalSystem;
    }
    
    async editSchedule(scheduleId) {
        this.modalSystem.showLoadingModal('Loading schedule data...');
        
        try {
            const response = await fetch(this.ajaxUrl, {
                method: 'POST',
                headers: {
                    'Content-Type': 'application/x-www-form-urlencoded',
                },
                body: new URLSearchParams({
                    action: 'blog82ai_get_schedule',
                    schedule_id: scheduleId,
                    nonce: this.nonce
                })
            });
            
            const data = await response.json();
            this.modalSystem.closeLoadingModal();
            
            if (data.success) {
                const schedule = data.data;
                
                document.getElementById('edit-schedule-id').value = schedule.id;
                document.getElementById('edit-schedule-category').value = schedule.category;
                document.getElementById('edit-schedule-date').value = schedule.start_date;
                document.getElementById('edit-schedule-time').value = schedule.run_time_24 || schedule.run_time;
                document.getElementById('edit-schedule-frequency').value = schedule.frequency.toLowerCase();
                
                document.getElementById('edit-schedule-modal').style.display = 'block';
            } else {
                this.modalSystem.showMessageModal('Error', 'Error loading schedule data: ' + data.data, '❌', false);
            }
        } catch (error) {
            this.modalSystem.closeLoadingModal();
            console.error('AJAX Error loading schedule:', error);
            this.modalSystem.showMessageModal('Error', 'Error loading schedule data. Please try again.', '❌', false);
        }
    }
    
    async viewScheduleDetails(scheduleId) {
        try {
            const response = await fetch(this.ajaxUrl, {
                method: 'POST',
                headers: {
                    'Content-Type': 'application/x-www-form-urlencoded',
                },
                body: new URLSearchParams({
                    action: 'blog82ai_get_schedule',
                    schedule_id: scheduleId,
                    nonce: this.nonce
                })
            });
            
            const data = await response.json();
            
            if (data.success) {
                const schedule = data.data;
                
                const detailsHTML = `
                    <div style="margin-bottom: 15px;">
                        <strong>Category:</strong> ${schedule.category_hierarchy}
                    </div>
                    <div style="margin-bottom: 15px;">
                        <strong>Schedule ID:</strong> ${schedule.id}
                    </div>
                    <div style="margin-bottom: 15px;">
                        <strong>Start Date:</strong> ${schedule.start_date}
                    </div>
                    <div style="margin-bottom: 15px;">
                        <strong>Run Time:</strong> ${schedule.run_time}
                    </div>
                    <div style="margin-bottom: 15px;">
                        <strong>Frequency:</strong> ${schedule.frequency}
                    </div>
                    <div style="margin-bottom: 15px;">
                        <strong>Next Run:</strong> ${schedule.next_run}
                    </div>
                    <div style="margin-bottom: 15px;">
                        <strong>Status:</strong> <span style="text-transform: uppercase; color: ${schedule.status === 'active' ? 'green' : 'orange'};">${schedule.status}</span>
                    </div>
                    <div style="margin-bottom: 15px;">
                        <strong>Created:</strong> ${schedule.created_at || 'N/A'}
                    </div>
                `;
                
                document.getElementById('schedule-details-content').innerHTML = detailsHTML;
                document.getElementById('view-details-modal').style.display = 'block';
            } else {
                this.modalSystem.showMessageModal('Error', 'Error loading schedule details: ' + data.data, '❌', false);
            }
        } catch (error) {
            console.error('AJAX Error loading schedule details:', error);
            this.modalSystem.showMessageModal('Error', 'Error loading schedule details. Please try again.', '❌', false);
        }
    }
    
    pauseSchedule(scheduleId) {
        this.modalSystem.showConfirmationModal(
            'Pause Schedule',
            'Are you sure you want to pause this schedule?',
            '⏸️',
            'Pause',
            async () => {
                await this.performScheduleAction('blog82ai_pause_schedule', scheduleId, 'Pausing schedule...', 'Schedule paused successfully!');
            },
            '#ffc107'
        );
    }
    
    resumeSchedule(scheduleId) {
        this.modalSystem.showConfirmationModal(
            'Resume Schedule',
            'Are you sure you want to resume this schedule?',
            '▶️',
            'Resume',
            async () => {
                await this.performScheduleAction('blog82ai_resume_schedule', scheduleId, 'Resuming schedule...', 'Schedule resumed successfully!');
            },
            '#28a745'
        );
    }
    
    deleteSchedule(scheduleId) {
        this.modalSystem.showConfirmationModal(
            'Delete Schedule',
            'Are you sure you want to delete this schedule? This action cannot be undone.',
            '🗑️',
            'Delete',
            async () => {
                await this.performScheduleAction('blog82ai_delete_schedule', scheduleId, 'Deleting schedule...', 'Schedule deleted successfully!');
            }
        );
    }
    
    fetchNow(category) {
        this.modalSystem.showConfirmationModal(
            'Generate Blog Now',
            `This will generate a blog post immediately for the "${category}" category. Continue?`,
            '📝',
            'Generate',
            async () => {
                this.modalSystem.showLoadingModal('Generating blog post...');
                
                try {
                    const response = await fetch(this.ajaxUrl, {
                        method: 'POST',
                        headers: {
                            'Content-Type': 'application/x-www-form-urlencoded',
                        },
                        body: new URLSearchParams({
                            action: 'blog82ai_fetch_now',
                            category: category,
                            nonce: this.nonce
                        })
                    });
                    
                    const responseText = await response.text();
                    
                    // Try to parse JSON
                    let data;
                    try {
                        data = JSON.parse(responseText);
                    } catch (jsonError) {
                        console.error('Blog82AI: JSON parse error:', jsonError);
                        console.error('Blog82AI: Response was not valid JSON:', responseText);
                        throw new Error('Server returned invalid response. Check PHP error logs.');
                    }
                    
                    this.modalSystem.closeLoadingModal();
                    
                    if (data.success) {
                        // If server returned structured post data, show preview modal
                        const payload = data.data;
                        if (payload && payload.post_id) {
                            const editUrl = window.location.origin + '/wp-admin/post.php?post=' + payload.post_id + '&action=edit';
                            const viewUrl = payload.permalink || (window.location.origin + '/?p=' + payload.post_id);
                            // Close loading and show preview
                            this.modalSystem.closeLoadingModal();
                            // Use excerpt or truncated content for preview
                            const previewHtml = payload.excerpt ? '<p>' + payload.excerpt + '</p>' : '<div>' + (payload.content ? payload.content.substring(0, 1000) : '') + '</div>';
                            this.modalSystem.showPreviewModal(payload.title, previewHtml, editUrl, viewUrl);
                            // Refresh the schedule list in background
                            scheduledBlogsManager.refreshScheduleComponents();
                        } else {
                            this.modalSystem.showMessageModal('Success', 'Blog post generated successfully!', '✅');
                            setTimeout(() => {
                                this.modalSystem.closeMessageModal();
                                scheduledBlogsManager.refreshScheduleComponents();
                            }, 1500);
                        }
                    } else {
                        const errorMessage = data.data || 'Unknown error occurred';
                        this.modalSystem.showMessageModal('Error', 'Failed to generate blog post: ' + errorMessage, '❌', false);
                    }
                } catch (error) {
                    this.modalSystem.closeLoadingModal();
                    console.error('AJAX Error generating blog post:', error);
                    this.modalSystem.showMessageModal('Error', 'Error generating blog post. Please try again.', '❌', false);
                }
            },
            '#0073aa'
        );
    }
    
    async performScheduleAction(action, scheduleId, loadingMessage, successMessage) {
        this.modalSystem.showLoadingModal(loadingMessage);
        
        try {
            const response = await fetch(this.ajaxUrl, {
                method: 'POST',
                headers: {
                    'Content-Type': 'application/x-www-form-urlencoded',
                },
                body: new URLSearchParams({
                    action: action,
                    schedule_id: scheduleId,
                    nonce: this.nonce
                })
            });
            
            const data = await response.json();
            this.modalSystem.closeLoadingModal();
            
            if (data.success) {
                this.modalSystem.showMessageModal('Success', successMessage, '✅');
                setTimeout(() => {
                    this.modalSystem.closeMessageModal();
                    scheduledBlogsManager.refreshScheduleComponents();
                }, 1500);
            } else {
                this.modalSystem.showMessageModal('Error', 'Operation failed: ' + data.data, '❌', false);
            }
        } catch (error) {
            this.modalSystem.closeLoadingModal();
            console.error('AJAX Error:', error);
            this.modalSystem.showMessageModal('Error', 'Error performing action. Please try again.', '❌', false);
        }
    }
    
    applyBulkAction() {
        const actionEl = document.getElementById('bulk-action');
        const action = actionEl ? actionEl.value : '';

        // Try to find checked checkboxes. Use multiple fallbacks to be robust across DOM changes.
        let checkboxes = document.querySelectorAll('.schedule-checkbox:checked');
        if (!checkboxes || checkboxes.length === 0) {
            // Fallback: select all schedule-checkbox inputs and filter checked
            const allBoxes = document.querySelectorAll('input.schedule-checkbox');
            checkboxes = Array.from(allBoxes).filter(cb => cb.checked);
        } else {
            checkboxes = Array.from(checkboxes);
        }

        if (!action) {
            this.modalSystem.showMessageModal('Warning', 'Please select an action.', '⚠️', false);
            return;
        }

        if (!checkboxes || checkboxes.length === 0) {
            this.modalSystem.showMessageModal('Warning', 'Please select at least one schedule. Your selections may not have been registered. Try clicking each checkbox again.', '⚠️', false);
            console.warn('applyBulkAction: No checkboxes found (fallback attempt).');
            return;
        }

        const scheduleIds = checkboxes.map(cb => cb.value);
        const actionText = action === 'delete' ? 'delete' : action;
        const actionIcon = action === 'delete' ? '🗑️' : action === 'pause' ? '⏸️' : '▶️';
        const actionColor = action === 'delete' ? '#dc3545' : action === 'pause' ? '#ffc107' : '#28a745';
        
        this.modalSystem.showConfirmationModal(
            `Bulk ${actionText.charAt(0).toUpperCase() + actionText.slice(1)}`,
            `Are you sure you want to ${actionText} ${scheduleIds.length} selected schedule(s)?`,
            actionIcon,
            actionText.charAt(0).toUpperCase() + actionText.slice(1),
            async () => {
                this.modalSystem.showLoadingModal(`Processing ${scheduleIds.length} schedules...`);

                try {
                    // Build payload so PHP receives schedule_ids as an array (schedule_ids[])
                    const payload = new URLSearchParams();
                    payload.append('action', 'blog82ai_bulk_action');
                    payload.append('bulk_action', action);
                    payload.append('nonce', this.nonce);
                    scheduleIds.forEach(id => payload.append('schedule_ids[]', id));

                    const response = await fetch(this.ajaxUrl, {
                        method: 'POST',
                        headers: {
                            'Content-Type': 'application/x-www-form-urlencoded',
                        },
                        body: payload
                    });

                    const status = response.status;
                    const responseText = await response.text();

                    let data = null;
                    try {
                        data = JSON.parse(responseText);
                    } catch (jsonErr) {
                        console.warn('Bulk action: response is not valid JSON', jsonErr);
                    }

                    this.modalSystem.closeLoadingModal();

                    if (data && data.success) {
                        this.modalSystem.showMessageModal('Success', data.data, '✅');
                        setTimeout(() => {
                            this.modalSystem.closeMessageModal();
                            scheduledBlogsManager.refreshScheduleComponents();
                        }, 1500);
                    } else {
                        // Prefer server-provided message; fall back to raw response
                        const message = (data && data.data) ? data.data : `Server returned status ${status}: ${responseText}`;
                        this.modalSystem.showMessageModal('Error', message, '❌', false);
                    }
                } catch (error) {
                    this.modalSystem.closeLoadingModal();
                    console.error('AJAX Error applying bulk action:', error);
                    this.modalSystem.showMessageModal('Error', 'Error applying bulk action. See console for details.', '❌', false);
                }
            },
            actionColor,
            action === 'delete'
        );
    }
}

// Small resilience helpers migrated from inline PHP script
function setupModalResilience() {
    function closeAllScheduleModals() {
        ['message-modal','loading-modal','confirmation-modal','view-details-modal','edit-schedule-modal'].forEach(function(id){
            var el = document.getElementById(id);
            if (el) el.style.display = 'none';
        });
        // restore body scroll
        document.body.style.overflow = 'auto';
    }

    // Ensure OK button always closes modals
    var messageOk = document.querySelector('#message-modal button');
    if (messageOk) {
        messageOk.addEventListener('click', function(e){
            try { closeAllScheduleModals(); } catch(err) { console.error(err); }
        });
    }

    // Esc to close
    document.addEventListener('keydown', function(e){ if (e.key === 'Escape') { closeAllScheduleModals(); } });

    // Click outside modal to close
    ['message-modal','confirmation-modal','view-details-modal','edit-schedule-modal','loading-modal'].forEach(function(id){
        var m = document.getElementById(id);
        if (!m) return;
        m.addEventListener('click', function(ev){ if (ev.target === m) { closeAllScheduleModals(); } });
    });
}

// Initialize the application when DOM is loaded
let scheduledBlogsManager;

document.addEventListener('DOMContentLoaded', () => {
    try { setupModalResilience(); } catch (err) { console.error('setupModalResilience error', err); }
    scheduledBlogsManager = new ScheduledBlogsManager();
});
