import React, { useState, useEffect, useCallback } from 'react';
import { Button } from "@/components/ui/button";
import { Input } from "@/components/ui/input";
import { Label } from "@/components/ui/label";
import { Progress } from "@/components/ui/progress";
import { Dialog, DialogContent, DialogHeader, DialogTitle, DialogDescription, DialogFooter } from "@/components/ui/dialog";
import { PlusIcon, XIcon } from "lucide-react";
import { __, sprintf } from '@wordpress/i18n';
import { preparePdfOcrImages, buildOcrBundle, MAX_OCR_PAGES } from '@/lib/pdfOcrPages';

const AISK_API = (window.AiskSettings?.apiUrl || '/wp-json/aisk/v1').replace(/\/+$/, '');

const PdfProcessing = ({ settings, updateSettings, isActiveConfigTab }) => {
    const [processMessage, setProcessMessage] = useState('');

    // PDF processing states
    const [openPdfDialog, setOpenPdfDialog] = useState(false);
    const [pdfProcessing, setPdfProcessing] = useState(false);
    const [pdfProgress, setPdfProgress] = useState(0);
    const [pdfFile, setPdfFile] = useState(null);
    const [pdfError, setPdfError] = useState(null);
    const [pdfMessage, setPdfMessage] = useState('');
    // PDFs from the server's processing queue
    const [pdfs, setPdfs] = useState([]);

    // Delete confirmation modal state
    const [openDeleteDialog, setOpenDeleteDialog] = useState(false);
    const [pdfToDelete, setPdfToDelete] = useState(null);

    // Store polling intervals for each PDF
    const pollingIntervals = React.useRef({});

    // Helper function to get max upload size
    const getMaxUploadSize = () => {
        if (window.AiskSettings && window.AiskSettings.maxUploadSize) {
            return (window.AiskSettings.maxUploadSize / (1024 * 1024)).toFixed(1) + ' MB';
        }
        return '2 MB'; // Default fallback
    };

    // Helper function to validate file size
    const validateFileSize = (file) => {
        const maxSize = window.AiskSettings?.maxUploadSize || 2 * 1024 * 1024; // Default 2MB
        if (file.size > maxSize) {
            setPdfError(sprintf(
                __('File size exceeds the maximum allowed size of %s. This is limited by your server configuration.', 'aisk-ai-chat'),
                getMaxUploadSize()
            ));
            return false;
        }
        return true;
    };

    // Helper function to validate PDF file
    const validatePdfFile = (file) => {
        // Check file extension
        if (!file.name.toLowerCase().endsWith('.pdf')) {
            setPdfError(__('Please upload a PDF file with .pdf extension', 'aisk-ai-chat'));
            return false;
        }

        // Check MIME type
        if (file.type && file.type !== 'application/pdf') {
            setPdfError(__('Invalid file type. Please upload a valid PDF file', 'aisk-ai-chat'));
            return false;
        }

        // Check if file is a valid PDF by checking the header
        return new Promise((resolve) => {
            const reader = new FileReader();
            reader.onload = (e) => {
                const uint8Array = new Uint8Array(e.target.result);
                const header = Array.from(uint8Array.slice(0, 5))
                    .map(byte => String.fromCharCode(byte))
                    .join('');

                if (header === '%PDF-') {
                    resolve(true);
                } else {
                    setPdfError(__('Invalid PDF file. The file does not appear to be a valid PDF document', 'aisk-ai-chat'));
                    resolve(false);
                }
            };
            reader.readAsArrayBuffer(file);
        });
    };

    const addNewPdf = () => {
        setPdfFile(null);
        setPdfError(null);
        setPdfProgress(0);
        setPdfMessage('');
        setOpenPdfDialog(true);
    };

    const processPdf = async () => {
        if (!pdfFile) {
            setPdfError(__('No PDF file selected', 'aisk-ai-chat'));
            return;
        }

        // Validate file size before processing
        if (!validateFileSize(pdfFile)) {
            return;
        }

        // Set processing state immediately - this will affect button text/state
        setPdfProcessing(true);
        setPdfError(null);

        // Image-only PDFs (scans, designs with outlined text) have no text layer.
        // Render their pages here so the server can read them with OCR.
        let ocrBundle = null;
        try {
            setPdfMessage(__('Checking PDF text...', 'aisk-ai-chat'));
            const ocr = await preparePdfOcrImages(pdfFile, (done, total) => {
                setPdfMessage(sprintf(
                    /* translators: 1: rendered page number, 2: total pages */
                    __('No text layer found. Preparing page %1$d of %2$d for OCR...', 'aisk-ai-chat'),
                    done,
                    total
                ));
            });

            if (ocr.imageOnly) {
                ocrBundle = buildOcrBundle(ocr.tiles);
                const maxSize = window.AiskSettings?.maxUploadSize || 2 * 1024 * 1024;
                if (pdfFile.size + ocrBundle.size > maxSize) {
                    setPdfError(sprintf(
                        /* translators: %s: maximum upload size */
                        __('This PDF contains only images, and its pages are too large to upload for OCR (limit %s). Split it into smaller PDFs and try again.', 'aisk-ai-chat'),
                        getMaxUploadSize()
                    ));
                    setPdfMessage('');
                    setPdfProcessing(false);
                    return;
                }
            }
            setPdfMessage('');
        } catch (ocrError) {
            setPdfMessage('');
            if (ocrError.message === 'too_many_pages') {
                setPdfError(sprintf(
                    /* translators: 1: number of pages in the PDF, 2: maximum pages */
                    __('This PDF contains only images (%1$d pages). OCR supports up to %2$d pages; split it into smaller PDFs and try again.', 'aisk-ai-chat'),
                    ocrError.pages,
                    MAX_OCR_PAGES
                ));
                setPdfProcessing(false);
                return;
            }
            console.error('PDF OCR preparation failed:', ocrError);
            setPdfError(ocrError.message === 'timeout'
                ? __('Reading the PDF in your browser took too long. Please try again.', 'aisk-ai-chat')
                : sprintf(
                    /* translators: %s: error message */
                    __('Could not read this PDF in your browser: %s', 'aisk-ai-chat'),
                    ocrError.message || String(ocrError)
                ));
            setPdfProcessing(false);
            return;
        }

        try {
            // Close the dialog and show progress in the main UI
            setOpenPdfDialog(false);
            setPdfProgress(10);
            setProcessMessage(__('Uploading PDF...', 'aisk-ai-chat'));

            const formData = new FormData();
            formData.append('pdf_file', pdfFile);
            if (ocrBundle) {
                formData.append('ocr_pages', ocrBundle, 'ocr-pages.json');
            }

            const response = await fetch(`${AISK_API}/process-pdf`, {
                method: 'POST',
                headers: {
                    'X-WP-Nonce': window.AiskData.nonce
                },
                body: formData
            });

            setPdfProgress(60);

            let result;
            const contentType = response.headers.get('content-type');
            if (contentType && contentType.includes('application/json')) {
                result = await response.json();
            } else {
                const text = await response.text();
                console.error('Invalid response:', text);
                throw new Error(__('Server returned an invalid response. Please try again.', 'aisk-ai-chat'));
            }

            if (!response.ok || !result.success) {
                throw new Error(result.message || __('Failed to process PDF', 'aisk-ai-chat'));
            }

            setPdfProgress(100);
            setProcessMessage(ocrBundle
                ? __('PDF uploaded. Reading its pages with OCR, this can take a minute...', 'aisk-ai-chat')
                : __('PDF uploaded and queued for processing.', 'aisk-ai-chat'));
            setPdfFile(null);
            await loadPdfs();
        } catch (error) {
            console.error('Error processing PDF:', error);
            setProcessMessage(error.message || __('Failed to process PDF. Please try again.', 'aisk-ai-chat'));
        } finally {
            setPdfProcessing(false);
            setTimeout(() => setPdfProgress(0), 1000);
        }
    };

    // The server's PDF queue is the source of truth for this list
    const loadPdfs = useCallback(async () => {
        try {
            const response = await fetch(`${AISK_API}/pdf-queue-list`, {
                headers: { 'X-WP-Nonce': window.AiskData.nonce }
            });
            if (!response.ok) {
                return;
            }
            const list = await response.json();
            setPdfs(Array.isArray(list) ? list : []);
        } catch (error) {
            console.error('Error loading PDFs:', error);
        }
    }, []);

    useEffect(() => {
        loadPdfs();
    }, [loadPdfs]);

    // While a PDF is queued or processing, refresh the list every 5 seconds
    const hasPendingPdf = pdfs.some(pdf => pdf.status === 'pending' || pdf.status === 'processing');
    useEffect(() => {
        if (!hasPendingPdf) {
            return undefined;
        }
        const timer = setInterval(loadPdfs, 5000);
        return () => clearInterval(timer);
    }, [hasPendingPdf, loadPdfs]);

    // Announce the result when a PDF finishes processing
    const previousStatuses = React.useRef({});
    useEffect(() => {
        pdfs.forEach(pdf => {
            const before = previousStatuses.current[pdf.job_id];
            if (before && before !== pdf.status) {
                if (pdf.status === 'completed') {
                    /* translators: %s: PDF file name */
                    setProcessMessage(sprintf(__('%s processed successfully!', 'aisk-ai-chat'), pdf.name));
                } else if (pdf.status === 'failed') {
                    /* translators: 1: PDF file name, 2: error message */
                    setProcessMessage(sprintf(__('Failed to process %1$s: %2$s', 'aisk-ai-chat'), pdf.name, pdf.error_message || ''));
                }
            }
            previousStatuses.current[pdf.job_id] = pdf.status;
        });
    }, [pdfs]);

    const confirmDeletePdf = (index) => {
        setPdfToDelete(index);
        setOpenDeleteDialog(true);
    };

    // Cancel PDF deletion
    const cancelDelete = () => {
        setPdfToDelete(null);
        setOpenDeleteDialog(false);
    };

    // Delete the PDF, its embeddings and its queue job on the server
    const confirmDelete = async () => {
        const pdf = pdfToDelete !== null ? pdfs[pdfToDelete] : null;
        setOpenDeleteDialog(false);
        setPdfToDelete(null);
        if (!pdf) {
            return;
        }

        setProcessMessage(__('Deleting PDF...', 'aisk-ai-chat'));
        try {
            const response = await fetch(`${AISK_API}/delete-pdf`, {
                method: 'POST',
                headers: {
                    'Content-Type': 'application/json',
                    'X-WP-Nonce': window.AiskData.nonce
                },
                body: JSON.stringify({
                    attachment_id: pdf.attachment_id,
                    job_id: pdf.job_id
                })
            });
            const data = await response.json().catch(() => ({}));
            if (!response.ok || !data.success) {
                throw new Error(data.message || sprintf(
                    /* translators: %d: HTTP status code */
                    __('Server returned %d', 'aisk-ai-chat'),
                    response.status
                ));
            }

            setPdfs(prev => prev.filter(item => item.job_id !== pdf.job_id));
            setProcessMessage(__('PDF deleted successfully.', 'aisk-ai-chat'));
        } catch (error) {
            console.error('Error removing PDF:', error);
            /* translators: %s: error message */
            setProcessMessage(sprintf(__('Error deleting PDF: %s', 'aisk-ai-chat'), error.message));
        } finally {
            loadPdfs();
            setTimeout(() => setProcessMessage(''), 4000);
        }
    };

    return (
        <div className="space-y-4 mt-6">
            <div className="flex items-center justify-between mb-4">
                <Label>{__('PDF Sources', 'aisk-ai-chat')}</Label>
                <div className="flex gap-2">
                    <Button
                        variant="outline"
                        size="sm"
                        onClick={addNewPdf}
                        className="flex items-center gap-2"
                    >
                        <PlusIcon className="h-4 w-4" />
                        {__('Add PDF', 'aisk-ai-chat')}
                    </Button>
                </div>
            </div>

            {/* Status message */}
            {processMessage && (
                <div className={`p-2 rounded-md ${processMessage.includes('Error') || processMessage.includes('Failed') ? 'bg-red-50 text-red-500' : 'bg-green-50 text-green-500'}`}>
                    {processMessage}
                </div>
            )}

            {/* Progress bar */}
            {pdfProcessing && (
                <div className="space-y-2">
                    <Progress value={pdfProgress} className="w-full" />
                    <p className="text-sm text-center text-gray-500">
                        {__('Processing... This may take a few minutes for larger files.', 'aisk-ai-chat')}
                    </p>
                </div>
            )}

            {pdfs.length === 0 ? (
                <div className="text-center py-4 border rounded-lg bg-gray-50">
                    <p className="text-sm text-gray-500">
                        {__('No PDF sources added yet', 'aisk-ai-chat')}
                    </p>
                </div>
            ) : (
                <div className="space-y-2">
                    {pdfs.map((pdfConfig, index) => (
                        <div
                            key={pdfConfig.job_id || index}
                            className="flex items-center justify-between p-3 border rounded-lg hover:bg-gray-50 transition-colors"
                        >
                            <div className="flex items-center gap-2 w-full">
                                <span className="font-medium">
                                    {pdfConfig.name || __('Unnamed PDF', 'aisk-ai-chat')}
                                </span>
                                {/* Status badge with color and error message for failed */}
                                {pdfConfig.status && (
                                    <>
                                        <span className={`text-xs px-2 py-1 rounded-full ${pdfConfig.status === 'processed' || pdfConfig.status === 'completed'
                                            ? 'text-green-700 bg-green-100'
                                            : (pdfConfig.status === 'processing' || pdfConfig.status === 'pending')
                                                ? 'text-yellow-700 bg-yellow-100'
                                                : pdfConfig.status === 'failed'
                                                    ? 'text-red-700 bg-red-100'
                                                    : 'text-gray-700 bg-gray-100'
                                            }`}>
                                            {({ pending: __('Queued', 'aisk-ai-chat'), processing: __('Processing', 'aisk-ai-chat'), completed: __('Processed', 'aisk-ai-chat'), failed: __('Failed', 'aisk-ai-chat') })[pdfConfig.status] || pdfConfig.status}
                                        </span>
                                        {pdfConfig.status === 'failed' && pdfConfig.error_message && (
                                            <span className="text-xs text-red-600">
                                                {pdfConfig.error_message}
                                            </span>
                                        )}
                                    </>
                                )}
                                {pdfConfig.status === 'completed' && pdfConfig.chunks > 0 && (
                                    <span className="text-xs text-gray-500">
                                        {pdfConfig.chunks} {__('chunks', 'aisk-ai-chat')}
                                    </span>
                                )}

                                {pdfConfig.size && (
                                    <span className="text-xs text-gray-500">
                                        {(Number(pdfConfig.size) / (1024 * 1024)).toFixed(2)} MB
                                    </span>
                                )}
                                {/* Show error message within the row for failed PDFs */}

                                {pdfConfig.status === 'failed' && pdfConfig.user_message && (
                                    <span className="text-xs text-red-600 bg-red-100 px-2 py-0.5 rounded ml-2">
                                        <strong>{__('Error:', 'aisk-ai-chat')}</strong> {pdfConfig.user_message}
                                    </span>
                                )}
                            </div>
                            <Button
                                variant="ghost"
                                size="sm"
                                onClick={() => confirmDeletePdf(index)}
                                className="hover:bg-red-50"
                            >
                                <XIcon className="h-4 w-4 text-red-500" />
                            </Button>
                        </div>
                    ))}
                </div>
            )}

            {/* PDF Upload Dialog */}
            <Dialog open={openPdfDialog} onOpenChange={setOpenPdfDialog}>
                <DialogContent className="sm:max-w-md">
                    <DialogHeader>
                        <DialogTitle>{__('Add PDF Document', 'aisk-ai-chat')}</DialogTitle>
                        <DialogDescription>
                            {__('Upload a PDF document to process and include in the knowledge base', 'aisk-ai-chat')}
                        </DialogDescription>
                    </DialogHeader>
                    <div className="space-y-4 py-2">
                        <div className="space-y-2">
                            <Label htmlFor="pdf-upload">{__('PDF Document', 'aisk-ai-chat')}</Label>
                            <Input
                                id="pdf-upload"
                                type="file"
                                accept=".pdf"
                                onChange={(e) => {
                                    const file = e.target.files[0];
                                    if (file) {
                                        // Check file size on client side
                                        // const maxSize = window.AiskSettings?.maxUploadSize || 2 * 1024 * 1024; // Default 2MB
                                        const maxSize = getMaxUploadSize();

                                        if (file.size > maxSize) {
                                            setPdfError(
                                                __(`The file is too large. Maximum allowed size is ${getMaxUploadSize()}. This is limited by your server configuration.`, 'aisk-ai-chat')
                                            );
                                            e.target.value = ''; // Clear the input
                                        } else {
                                            // Validate PDF file
                                            validatePdfFile(file).then((isValid) => {
                                                if (isValid) {
                                                    setPdfFile(file);
                                                    setPdfError(null); // Clear any previous errors
                                                } else {
                                                    e.target.value = ''; // Clear the input
                                                }
                                            });
                                        }
                                    }
                                }}
                            />
                            <p className="text-xs text-gray-500">
                                {__(`Maximum file size: ${getMaxUploadSize()} (server limit)`, 'aisk-ai-chat')}
                            </p>
                            {pdfFile && (
                                <p className="text-sm text-gray-500">
                                    {__('Selected file:', 'aisk-ai-chat')} {pdfFile.name} ({(pdfFile.size / (1024 * 1024)).toFixed(2)} MB)
                                </p>
                            )}
                        </div>

                        {pdfError && (
                            <div className="bg-red-50 border border-red-200 text-red-700 px-4 py-3 rounded-md">
                                <p className="text-sm">{pdfError}</p>
                            </div>
                        )}

                        {pdfMessage && !pdfError && (
                            <div className="bg-green-50 border border-green-200 text-green-700 px-4 py-3 rounded-md">
                                <p className="text-sm">{pdfMessage}</p>
                            </div>
                        )}
                    </div>
                    <DialogFooter className="flex justify-between items-center">
                        <Button
                            variant="secondary"
                            onClick={() => {
                                setOpenPdfDialog(false);
                                setPdfFile(null);
                                setPdfError(null);
                                setPdfMessage('');
                                setPdfProcessing(false); // Reset processing state when canceling
                            }}
                            disabled={pdfProcessing}
                        >
                            {__('Cancel', 'aisk-ai-chat')}
                        </Button>
                        <Button
                            variant="default"
                            className="bg-green-600 hover:bg-green-700"
                            onClick={processPdf}
                            disabled={!pdfFile || pdfProcessing || pdfError}
                        >
                            {pdfProcessing ? __('Processing...', 'aisk-ai-chat') : __('Process Now', 'aisk-ai-chat')}
                        </Button>
                    </DialogFooter>
                </DialogContent>
            </Dialog>

            {/* Delete Confirmation Dialog */}
            <Dialog open={openDeleteDialog} onOpenChange={setOpenDeleteDialog}>
                <DialogContent className="sm:max-w-md">
                    <DialogHeader>
                        <DialogTitle>{__('Confirm Deletion', 'aisk-ai-chat')}</DialogTitle>
                        <DialogDescription>
                            {__('Are you sure you want to delete this PDF? This will remove it from your knowledge base.', 'aisk-ai-chat')}
                        </DialogDescription>
                    </DialogHeader>
                    {pdfToDelete !== null && pdfs[pdfToDelete] && (
                        <div className="py-3">
                            <p className="font-medium text-center">
                                {pdfs[pdfToDelete].name || __('Unnamed PDF', 'aisk-ai-chat')}
                            </p>
                        </div>
                    )}
                    <DialogFooter className="flex justify-between items-center">
                        <Button
                            variant="secondary"
                            onClick={cancelDelete}
                        >
                            {__('Cancel', 'aisk-ai-chat')}
                        </Button>
                        <Button
                            variant="destructive"
                            onClick={confirmDelete}
                        >
                            {__('Delete', 'aisk-ai-chat')}
                        </Button>
                    </DialogFooter>
                </DialogContent>
            </Dialog>
        </div>
    );
};

export default PdfProcessing;
