/**
 * PDF Upload Handler for Research Form
 * Handles drag-and-drop PDF uploads and text extraction
 */

class PDFUploadHandler {
    constructor() {
        SafeLogger.log('PDF Upload Handler: Initializing...');
        this.queryTextarea = null;
        this.isDragOver = false;
        this.uploadedPDFs = [];
        // Default fallback values (used if API is unavailable)
        this.maxFileSize = 50 * 1024 * 1024; // 50MB limit
        this.maxFiles = 200; // Maximum PDFs at once
        this.statusTimers = []; // Track setTimeout IDs to prevent timer leaks
        this.limitsLoaded = false;
        this.init();
    }

    /**
     * Fetch upload limits from the backend API
     * This ensures frontend and backend stay in sync
     */
    async fetchUploadLimits() {
        try {
            const limitsUrl = URLS?.API?.CONFIG_LIMITS || '/api/config/limits';
            const response = await fetch(limitsUrl);
            if (response.ok) {
                const limits = await response.json();
                this.maxFileSize = limits.max_file_size;
                this.maxFiles = limits.max_files;
                this.limitsLoaded = true;
                SafeLogger.log(`PDF Upload Handler: Loaded limits from API - maxFileSize: ${this.formatFileSize(this.maxFileSize)}, maxFiles: ${this.maxFiles}`);
            } else {
                SafeLogger.warn('PDF Upload Handler: Could not fetch limits from API, using defaults');
            }
        } catch (error) {
            SafeLogger.warn('PDF Upload Handler: Error fetching limits, using defaults:', error.message);
        }
    }

    /**
     * Initialize the PDF upload handler
     */
    async init() {
        SafeLogger.log('PDF Upload Handler: Starting initialization...');

        // Wait a bit longer for DOM to be ready
        if (document.readyState === 'loading') {
            document.addEventListener('DOMContentLoaded', () => this.init());
            return;
        }

        // Fetch upload limits from backend (non-blocking, uses defaults as fallback)
        await this.fetchUploadLimits();

        this.queryTextarea = document.getElementById('query');
        if (!this.queryTextarea) {
            SafeLogger.error('PDF Upload Handler: Query textarea not found!');
            return;
        }

        SafeLogger.log('PDF Upload Handler: Found query textarea, setting up drag-and-drop...');
        this.setupDragAndDrop();
        this.setupFileInput();
        this.updatePlaceholder();
        SafeLogger.log('PDF Upload Handler: Initialization complete!');
    }

    /**
     * Setup drag and drop events for the textarea
     */
    setupDragAndDrop() {
        SafeLogger.log('PDF Upload Handler: Setting up drag-and-drop events...');

        // Prevent default drag behaviors
        ['dragenter', 'dragover', 'dragleave', 'drop'].forEach(eventName => {
            this.queryTextarea.addEventListener(eventName, (e) => {
                SafeLogger.log(`PDF Upload Handler: ${eventName} event detected`);
                this.preventDefaults(e);
            }, false);
            document.body.addEventListener(eventName, this.preventDefaults, false);
        });

        // Highlight drop area when item is dragged over it
        ['dragenter', 'dragover'].forEach(eventName => {
            this.queryTextarea.addEventListener(eventName, (e) => {
                SafeLogger.log(`PDF Upload Handler: Highlighting for ${eventName}`);
                this.highlight();
            }, false);
        });

        ['dragleave', 'drop'].forEach(eventName => {
            this.queryTextarea.addEventListener(eventName, (e) => {
                SafeLogger.log(`PDF Upload Handler: Unhighlighting for ${eventName}`);
                this.unhighlight();
            }, false);
        });

        // Handle dropped files
        this.queryTextarea.addEventListener('drop', (e) => {
            SafeLogger.log('PDF Upload Handler: Drop event detected, handling files...');
            this.handleDrop(e);
        }, false);

        // Handle paste events
        this.queryTextarea.addEventListener('paste', (e) => this.handlePaste(e), false);

        SafeLogger.log('PDF Upload Handler: Drag-and-drop events setup complete');
    }

    /**
     * Setup a hidden file input as fallback
     */
    setupFileInput() {
        // Prevent duplicate buttons if init() runs more than once
        if (document.getElementById('pdf-upload-btn')) {
            return;
        }

        // Create file input button
        const fileInput = document.createElement('input');
        fileInput.type = 'file';
        fileInput.multiple = true;
        fileInput.accept = '.pdf';
        fileInput.style.display = 'none';
        fileInput.id = 'pdf-file-input';
        fileInput.setAttribute('aria-label', 'Upload PDF files');

        // Add upload button near the textarea with proper styling
        const uploadButton = document.createElement('button');
        uploadButton.type = 'button';
        uploadButton.className = 'btn btn-sm ldr-btn-outline ldr-pdf-upload-btn';
        uploadButton.id = 'pdf-upload-btn';
        uploadButton.setAttribute('aria-label', 'Upload PDF files');

        // Create button content safely (XSS prevention)
        const icon = document.createElement('i');
        icon.className = 'fas fa-file-pdf';
        const text = document.createTextNode(' Add PDFs');
        uploadButton.appendChild(icon);
        uploadButton.appendChild(text);

        // Find the search hints container to add PDF button inline
        const searchHints = this.queryTextarea.parentNode.querySelector('.ldr-search-hints');
        const hintRow = searchHints?.querySelector('.ldr-hint-row');

        if (hintRow) {
            // Add PDF button as a hint item to existing shortcuts row
            const pdfHintItem = document.createElement('span');
            pdfHintItem.className = 'ldr-hint-item';
            pdfHintItem.style.cssText = `
                margin-left: auto;
                padding-left: 1rem;
                border-left: 1px solid var(--border-color);
            `;

            // Wrap button in hint item structure
            pdfHintItem.appendChild(uploadButton);
            pdfHintItem.appendChild(fileInput);

            // Add to the existing hint row
            hintRow.appendChild(pdfHintItem);
        } else {
            // Fallback: create container if hints not found
            const pdfContainer = document.createElement('div');
            pdfContainer.className = 'ldr-pdf-upload-container';
            pdfContainer.style.cssText = `
                margin-top: 0.25rem;
                display: flex;
                align-items: center;
                gap: 0.5rem;
                flex-wrap: wrap;
            `;
            pdfContainer.appendChild(uploadButton);
            pdfContainer.appendChild(fileInput);
            this.queryTextarea.parentNode.insertBefore(pdfContainer, this.queryTextarea.nextSibling);
        }

        // Handle button click
        uploadButton.addEventListener('click', () => fileInput.click());
        fileInput.addEventListener('change', (e) => this.handleFileSelect(e));
    }

    /**
     * Prevent default drag behaviors
     */
    preventDefaults(e) {
        e.preventDefault();
        e.stopPropagation();
    }

    /**
     * Highlight the drop area
     */
    highlight() {
        if (!this.isDragOver) {
            this.queryTextarea.style.backgroundColor = 'rgba(var(--accent-primary-rgb), 0.1)';
            this.queryTextarea.style.border = '2px dashed var(--accent-primary)';
            this.queryTextarea.style.transition = 'all 0.2s ease';
            this.isDragOver = true;
        }
    }

    /**
     * Remove highlight from the drop area
     */
    unhighlight() {
        if (this.isDragOver) {
            this.queryTextarea.style.backgroundColor = '';
            this.queryTextarea.style.border = '';
            this.isDragOver = false;
        }
    }

    /**
     * Handle file drops
     */
    async handleDrop(e) {
        const dt = e.dataTransfer;
        const files = dt.files;
        this.handleFiles(files);
    }

    /**
     * Handle file paste events
     */
    async handlePaste(e) {
        const items = e.clipboardData.items;
        for (let item of items) {
            if (item.type === 'application/pdf') {
                e.preventDefault();
                const file = item.getAsFile();
                this.handleFiles([file]);
                break;
            }
        }
    }

    /**
     * Handle file selection from input
     */
    async handleFileSelect(e) {
        const files = e.target.files;
        this.handleFiles(files);
        // Clear the input so the same files can be selected again if needed
        e.target.value = '';
    }

    /**
     * Process files
     */
    async handleFiles(files) {
        const pdfFiles = Array.from(files).filter(file =>
            file.type === 'application/pdf' || file.name.toLowerCase().endsWith('.pdf')
        );

        if (pdfFiles.length === 0) {
            this.showError('Please select PDF files only');
            return;
        }

        // Check file count limit
        if (pdfFiles.length > this.maxFiles) {
            this.showError(`Maximum ${this.maxFiles} PDF files allowed at once`);
            return;
        }

        // Check file sizes
        const oversizedFiles = pdfFiles.filter(file => file.size > this.maxFileSize);
        if (oversizedFiles.length > 0) {
            this.showError(`PDF files must be smaller than ${this.formatFileSize(this.maxFileSize)}`);
            return;
        }

        await this.uploadAndExtractPDFs(pdfFiles);
    }

    /**
     * Upload PDFs and extract text
     */
    async uploadAndExtractPDFs(files) {
        this.showProcessing(files.length);

        try {
            const formData = new FormData();
            files.forEach(file => {
                formData.append('files', file);
            });

            // Get CSRF token
            const csrfToken = window.api ? window.api.getCsrfToken() : '';

            const headers = {};
            if (csrfToken) {
                headers['X-CSRFToken'] = csrfToken;
            }

            // Validate URL before making request
            const uploadUrl = URLS.API.UPLOAD_PDF;
            if (!URLValidator.isSafeUrl(uploadUrl)) {
                throw new Error('Invalid upload URL detected');
            }

            const response = await fetch(uploadUrl, {
                method: 'POST',
                body: formData,
                headers: headers
            });

            if (!response.ok) {
                throw new Error(`HTTP ${response.status}: ${response.statusText}`);
            }

            const result = await response.json();

            if (result.status === 'success') {
                this.addPDFsToUploaded(files, result.extracted_texts);
                this.appendExtractedTextToQuery(result.combined_text);
                this.showSuccess(result.processed_files, result.errors);
                this.updatePlaceholder();
            } else {
                this.showError(result.message || 'Failed to process PDFs');
            }
        } catch (error) {
            SafeLogger.error('Error uploading PDFs:', error);
            this.showError('Failed to upload PDFs. Please try again.');
        } finally {
            this.hideProcessing();
        }
    }

    /**
     * Add PDFs to the uploaded list
     */
    addPDFsToUploaded(files, extractedTexts) {
        files.forEach((file, index) => {
            const extractedText = extractedTexts[index];
            if (extractedText) {
                this.uploadedPDFs.push({
                    filename: file.name,
                    size: file.size,
                    text: extractedText.text,
                    pages: extractedText.pages
                });
            }
        });
    }

    /**
     * Append extracted text to the query textarea
     */
    appendExtractedTextToQuery(combinedText) {
        const currentQuery = this.queryTextarea.value.trim();
        const separator = currentQuery ? '\n\n--- PDF Content ---\n' : '';
        this.queryTextarea.value = currentQuery + separator + combinedText;

        // Focus the textarea at the end
        this.queryTextarea.focus();
        this.queryTextarea.setSelectionRange(this.queryTextarea.value.length, this.queryTextarea.value.length);

        // Trigger input event to let other components know the content changed
        this.queryTextarea.dispatchEvent(new Event('input', { bubbles: true }));
    }

    /**
     * Update the placeholder text based on upload state
     */
    updatePlaceholder() {
        if (this.uploadedPDFs.length > 0) {
            const pdfCount = this.uploadedPDFs.length;
            const totalPages = this.uploadedPDFs.reduce((sum, pdf) => sum + pdf.pages, 0);
            this.queryTextarea.placeholder =
                `Enter your research question... (${pdfCount} PDF${pdfCount > 1 ? 's' : ''} loaded, ${totalPages} pages total)`;
        } else {
            this.queryTextarea.placeholder = 'Enter your research topic or question\n\nFor example: drop a PDF paper here and ask LDR to search for similar sources';
        }
    }

    /**
     * Show processing indicator
     */
    showProcessing(fileCount) {
        const statusDiv = this.getOrCreateStatusDiv();

        // Clear existing content safely
        statusDiv.textContent = '';

        // Create elements safely (XSS prevention)
        const container = document.createElement('div');
        container.style.cssText = 'display: flex; align-items: center; gap: 8px; color: var(--accent-tertiary);';

        const icon = document.createElement('i');
        icon.className = 'fas fa-spinner fa-spin';

        const text = document.createElement('span');
        text.textContent = `Processing ${fileCount} PDF${fileCount > 1 ? 's' : ''}...`;

        container.appendChild(icon);
        container.appendChild(text);
        statusDiv.appendChild(container);
        statusDiv.style.display = 'block';
    }

    /**
     * Hide processing indicator
     */
    hideProcessing() {
        const statusDiv = this.getOrCreateStatusDiv();
        statusDiv.style.display = 'none';
    }

    /**
     * Clear all pending status timers to prevent timer leaks
     */
    clearStatusTimers() {
        this.statusTimers.forEach(timerId => clearTimeout(timerId));
        this.statusTimers = [];
    }

    /**
     * Show success message
     */
    showSuccess(processedFiles, errors) {
        // Clear any existing status timers to prevent timer leaks
        this.clearStatusTimers();

        const statusDiv = this.getOrCreateStatusDiv();

        // Clear existing content safely
        statusDiv.textContent = '';

        // Create elements safely (XSS prevention)
        const container = document.createElement('div');
        container.style.color = 'var(--success-color)';

        const icon = document.createElement('i');
        icon.className = 'fas fa-check-circle';

        const text = document.createTextNode(
            ` Successfully processed ${processedFiles} PDF${processedFiles > 1 ? 's' : ''}`
        );

        container.appendChild(icon);
        container.appendChild(text);

        if (errors.length > 0) {
            const br = document.createElement('br');
            const errorText = document.createElement('small');
            errorText.style.color = 'var(--text-muted)';
            errorText.textContent = `Some files had issues: ${errors.join('; ')}`;

            container.appendChild(br);
            container.appendChild(errorText);
        }

        statusDiv.appendChild(container);
        statusDiv.style.display = 'block';

        // Auto-hide after 5 seconds (store timer ID to prevent leaks)
        const timerId = setTimeout(() => {
            statusDiv.style.display = 'none';
        }, 5000);
        this.statusTimers.push(timerId);
    }

    /**
     * Show error message
     */
    showError(message) {
        // Clear any existing status timers to prevent timer leaks
        this.clearStatusTimers();

        const statusDiv = this.getOrCreateStatusDiv();

        // Clear existing content safely
        statusDiv.textContent = '';

        // Create elements safely (XSS prevention)
        const container = document.createElement('div');
        container.style.color = 'var(--error-color)';

        const icon = document.createElement('i');
        icon.className = 'fas fa-exclamation-triangle';

        const text = document.createTextNode(` ${message}`);

        container.appendChild(icon);
        container.appendChild(text);
        statusDiv.appendChild(container);
        statusDiv.style.display = 'block';

        // Auto-hide after 5 seconds (store timer ID to prevent leaks)
        const timerId = setTimeout(() => {
            statusDiv.style.display = 'none';
        }, 5000);
        this.statusTimers.push(timerId);
    }

    /**
     * Get or create status display div
     */
    getOrCreateStatusDiv() {
        let statusDiv = document.getElementById('pdf-upload-status');
        if (!statusDiv) {
            statusDiv = document.createElement('div');
            statusDiv.id = 'pdf-upload-status';
            statusDiv.className = 'ldr-upload-status';
            statusDiv.style.cssText = `
                padding: 0.25rem 0.5rem;
                border-radius: 4px;
                font-size: 0.8rem;
                background: var(--bg-tertiary);
                border: 1px solid var(--border-color);
                color: var(--text-secondary);
                flex: 1;
                min-width: 0;
                max-width: 300px;
            `;

            // Find the PDF hint item and add status div to it
            // Use parentElement traversal instead of :has() for Firefox compatibility
            const pdfBtn = document.querySelector('.ldr-pdf-upload-btn');
            const pdfHintItem = pdfBtn?.closest('.ldr-hint-item');
            if (pdfHintItem) {
                statusDiv.style.cssText += `
                    margin-left: 0.5rem;
                    max-width: 200px;
                `;
                pdfHintItem.appendChild(statusDiv);
            } else {
                // Fallback: find PDF container or insert after textarea
                const pdfContainer = document.querySelector('.ldr-pdf-upload-container');
                if (pdfContainer) {
                    pdfContainer.appendChild(statusDiv);
                } else {
                    this.queryTextarea.parentNode.insertBefore(statusDiv, this.queryTextarea.nextSibling);
                }
            }
        }
        return statusDiv;
    }

    /**
     * Clear uploaded PDFs
     */
    clearUploadedPDFs() {
        this.uploadedPDFs = [];
        this.updatePlaceholder();
    }

    /**
     * Format file size for display
     */
    formatFileSize(bytes) {
        if (bytes === 0) return '0 Bytes';
        const k = 1024;
        const sizes = ['Bytes', 'KB', 'MB', 'GB'];
        const i = Math.floor(Math.log(bytes) / Math.log(k));
        return parseFloat((bytes / Math.pow(k, i)).toFixed(2)) + ' ' + sizes[i];
    }

    /**
     * Get list of uploaded PDFs
     */
    getUploadedPDFs() {
        return [...this.uploadedPDFs];
    }
}

// Initialize the PDF upload handler when the DOM is ready
function initializePDFUploadHandler() {
    SafeLogger.log('PDF Upload Handler: DOM ready, initializing handler...');
    if (window.pdfUploadHandler) {
        SafeLogger.log('PDF Upload Handler: Already initialized');
        return;
    }

    // Try to initialize immediately
    window.pdfUploadHandler = new PDFUploadHandler();

    // If textarea not found (async init still pending), try re-init on existing instance
    if (!window.pdfUploadHandler.queryTextarea) {
        SafeLogger.log('PDF Upload Handler: Textarea not found, retrying on existing instance...');
        setTimeout(() => {
            SafeLogger.log('PDF Upload Handler: Retrying initialization...');
            window.pdfUploadHandler.init();
        }, 500);
    }
}

if (document.readyState === 'loading') {
    document.addEventListener('DOMContentLoaded', initializePDFUploadHandler);
} else {
    // DOM is already ready
    initializePDFUploadHandler();
}

// Make it available globally for other scripts
if (typeof module !== 'undefined' && module.exports) {
    module.exports = PDFUploadHandler;
}
