import React, { useEffect, useMemo, useState } from 'react';

import PDFModal from './components/PDFModal';
import PDFLightbox from './components/PDFLightbox';
import DocsSlideover from './components/DocsSlideover';
import { Table, TableHeader, TableBody, TableRow, TableHead, TableCell } from './components/Table';
import Pagination from './components/Pagination';
import { BookOpen, ChevronDown, ChevronUp, ChevronsUpDown, LayoutGrid } from 'lucide-react';
import Toolbar from './components/Toolbar';
import PDFTableRow from './components/PDFTableRow';
import PDFItem from './components/PDFItem';
import { fetchPDFs, updatePDF, deletePDF, bulkDeletePDFs, uploadPDF, fetchCategories, fetchTags, uploadThumbnail } from './api/pdfs';
import { generatePDFThumbnail } from './utils/thumbnail';

const ITEMS_PER_PAGE = 10;

const App = () => {

    const [pdfs, setPdfs] = useState([]);
    const [view, setView] = useState('grid');
    const [loading, setLoading] = useState(true);
    const [error, setError] = useState(null);
    const [selectedPdf, setSelectedPdf] = useState(null);
    const [selectedPdfs, setSelectedPdfs] = useState(new Set());
    const [currentPage, setCurrentPage] = useState(1);
    const [sortConfig, setSortConfig] = useState({ key: 'uploaded', direction: 'desc' });
    const [searchQuery, setSearchQuery] = useState('');
    const [filterCategory, setFilterCategory] = useState('');
    const [filterTag, setFilterTag] = useState('');
    const [availableCategories, setAvailableCategories] = useState([]);
    const [availableTags, setAvailableTags] = useState([]);
    const [quickViewPdf, setQuickViewPdf] = useState(null);
    const [showDocs, setShowDocs] = useState(false);

    // Combined Filtering Logic
    const filteredPdfs = useMemo(() => {
        let result = pdfs;

        // Search Filter
        if (searchQuery) {
            const query = searchQuery.toLowerCase();
            result = result.filter(pdf =>
                pdf.name.toLowerCase().includes(query) ||
                pdf.title?.toLowerCase().includes(query)
            );
        }

        // Category Filter
        if (filterCategory) {
            result = result.filter(pdf =>
                pdf.categories?.some(cat => cat.id === parseInt(filterCategory))
            );
        }

        // Tag Filter
        if (filterTag) {
            result = result.filter(pdf =>
                pdf.tags?.some(tag => tag.id === parseInt(filterTag))
            );
        }

        return result;
    }, [pdfs, searchQuery, filterCategory, filterTag]);

    const handleSort = (key, direction = null) => {
        setSortConfig(current => ({
            key,
            direction: direction || (current.key === key && current.direction === 'asc' ? 'desc' : 'asc')
        }));
    };

    const getSortIcon = (key) => {
        if (sortConfig.key !== key) return <ChevronsUpDown className="size-4 text-slate-400" />;
        return sortConfig.direction === 'asc' ?
            <ChevronUp className="size-4 text-indigo-500" /> :
            <ChevronDown className="size-4 text-indigo-500" />;
    };

    const sortedPdfs = useMemo(() => {
        const sorted = [...filteredPdfs].sort((a, b) => {
            if (sortConfig.key === 'filesize') {
                return sortConfig.direction === 'asc' ?
                    a.filesize - b.filesize :
                    b.filesize - a.filesize;
            }
            // Add safety check for string properties
            const valA = a[sortConfig.key] || '';
            const valB = b[sortConfig.key] || '';

            return sortConfig.direction === 'asc' ?
                valA.localeCompare(valB) :
                valB.localeCompare(valA);
        });
        return sorted;
    }, [filteredPdfs, sortConfig]);

    const paginatedPdfs = useMemo(() => {
        const start = (currentPage - 1) * ITEMS_PER_PAGE;
        return sortedPdfs.slice(start, start + ITEMS_PER_PAGE);
    }, [sortedPdfs, currentPage]);

    const totalPages = Math.ceil(pdfs.length / ITEMS_PER_PAGE);

    const handleSelectAll = (e) => {
        if (e.target.checked) {
            setSelectedPdfs(new Set(paginatedPdfs.map(pdf => pdf.id)));
        } else {
            setSelectedPdfs(new Set());
        }
    };

    const handleSelect = (id) => {
        setSelectedPdfs(current => {
            const updated = new Set(current);
            if (updated.has(id)) {
                updated.delete(id);
            } else {
                updated.add(id);
            }
            return updated;
        });
    };

    const handlePdfUpdate = async (updatedPdfData, skipApi = false) => {
        if (skipApi) {
            setPdfs(pdfs.map(pdf =>
                pdf.id === updatedPdfData.id ? updatedPdfData : pdf
            ));
            return;
        }
        try {
            const response = await updatePDF(updatedPdfData.id, updatedPdfData);
            if (response.success && response.data.pdf) {
                const updatedPdf = response.data.pdf;
                setPdfs(pdfs.map(pdf =>
                    pdf.id === updatedPdf.id ? updatedPdf : pdf
                ));
            }
        } catch (err) {
            console.error(err);
            alert(err.message);
        }
    };

    const handlePdfDelete = async (pdfId) => {
        if (!window.confirm('Are you sure you want to delete this PDF?')) return;
        try {
            await deletePDF(pdfId);
            setPdfs(pdfs.filter(pdf => pdf.id !== pdfId));
            setSelectedPdf(null); // Close modal if open
        } catch (err) {
            console.error(err);
            alert(err.message);
        }
    };

    const handleBulkDelete = async () => {
        if (!window.confirm(`Are you sure you want to delete ${selectedPdfs.size} PDFs permanently?`)) {
            return;
        }

        try {
            await bulkDeletePDFs(Array.from(selectedPdfs));
            setPdfs(pdfs.filter(pdf => !selectedPdfs.has(pdf.id)));
            setSelectedPdfs(new Set());
        } catch (error) {
            console.error('Error deleting PDFs:', error);
            alert(error.message);
        }
    };

    const handleUpload = () => {
        // Create the media frame.
        const frame = wp.media({
            title: 'Select PDF',
            button: {
                text: 'Use this PDF'
            },
            library: {
                type: 'application/pdf'
            },
            multiple: false
        });

        // When an image is selected, run a callback.
        frame.on('select', async () => {
            const attachment = frame.state().get('selection').first().toJSON();

            // Map WP attachment to our PDF structure locally to update state immediately
            // Note: We might want to re-fetch to ensure we have the exact format, 
            // but mapping here avoids a network call if the WP return is sufficient.
            // Based on PDFController::prepare_item_for_response, we need specific fields.

            const newPdf = {
                id: attachment.id,
                name: attachment.filename,
                url: attachment.url,
                uploaded: new Date(attachment.date).toISOString(), // WP returns date string or timestamp
                title: attachment.title,
                caption: attachment.caption,
                description: attachment.description,
                filesize: attachment.filesizeInBytes, // WP JS object usually has filesizeInBytes or human readable 'filesize'
                mime_type: attachment.mime,
                thumbnail: attachment.icon // or check sizes
            };

            // Re-fetch to be safe and get consistent server-side formatting
            try {
                setLoading(true);
                const data = await fetchPDFs();
                if (data.success && data.data.pdfs) {
                    setPdfs(data.data.pdfs);

                    // Auto-generate cover for the new upload
                    const newPdfId = attachment.id;
                    const pdfObj = data.data.pdfs.find(p => p.id === newPdfId);
                    if (pdfObj && !pdfObj.thumbnail) {
                        try {
                            const blob = await generatePDFThumbnail(pdfObj.url);
                            await uploadThumbnail(newPdfId, blob);
                            // Refresh again to show the thumbnail or update local state
                            const updatedData = await fetchPDFs();
                            if (updatedData.success) setPdfs(updatedData.data.pdfs);
                        } catch (thumbErr) {
                            console.error("Auto-thumbnail failed:", thumbErr);
                        }
                    }
                }
            } catch (error) {
                console.error("Error refreshing list:", error);
            } finally {
                setLoading(false);
            }
        });

        // Finally, open the modal.
        frame.open();
    };

    useEffect(() => {
        const loadInitialData = async () => {
            try {
                setLoading(true);
                const [pdfData, catData, tagData] = await Promise.all([
                    fetchPDFs(),
                    fetchCategories(),
                    fetchTags()
                ]);

                if (pdfData.success) setPdfs(pdfData.data.pdfs || pdfData.pdfs || []);
                if (catData.success) setAvailableCategories(catData.data.categories || []);
                if (tagData.success) setAvailableTags(tagData.data.tags || []);

            } catch (error) {
                setError(error.message);
            } finally {
                setLoading(false);
            }
        };

        loadInitialData();
    }, []);

    const renderListView = () => (
        <div className="space-y-4">
            <div className="bg-white rounded-xl shadow-sm border border-slate-200 overflow-hidden">
                <Table>
                    <TableHeader>
                        <TableRow className="bg-slate-50 border-b border-slate-200">
                            <TableHead className="w-[40px] px-4 py-3">
                                <input
                                    type="checkbox"
                                    onChange={handleSelectAll}
                                    checked={paginatedPdfs.length > 0 && selectedPdfs.size === paginatedPdfs.length}
                                    className="rounded border-slate-300 text-indigo-600 focus:ring-indigo-500 cursor-pointer"
                                />
                            </TableHead>
                            <TableHead
                                className="w-[400px] cursor-pointer hover:bg-slate-100 px-4 py-3 transition-colors"
                                onClick={() => handleSort('title')}
                            >
                                <div className="flex items-center gap-1 font-semibold text-slate-700">
                                    Name
                                    {getSortIcon('title')}
                                </div>
                            </TableHead>
                            <TableHead
                                className="w-[120px] cursor-pointer hover:bg-slate-100 px-4 py-3 transition-colors"
                                onClick={() => handleSort('filesize')}
                            >
                                <div className="flex items-center gap-1 font-semibold text-slate-700">
                                    Size
                                    {getSortIcon('filesize')}
                                </div>
                            </TableHead>
                            <TableHead
                                className="w-[150px] cursor-pointer hover:bg-slate-100 px-4 py-3 transition-colors"
                                onClick={() => handleSort('uploaded')}
                            >
                                <div className="flex items-center gap-1 font-semibold text-slate-700">
                                    Upload Date
                                    {getSortIcon('uploaded')}
                                </div>
                            </TableHead>
                            <TableHead className="w-[200px] px-4 py-3 font-semibold text-slate-700">Actions</TableHead>
                        </TableRow>
                    </TableHeader>
                    <TableBody>
                        {paginatedPdfs.map((pdf) => (
                            <PDFTableRow
                                key={pdf.id}
                                pdf={pdf}
                                onOpenModal={setSelectedPdf}
                                selected={selectedPdfs.has(pdf.id)}
                                onSelect={handleSelect}
                            />
                        ))}
                    </TableBody>
                </Table>
            </div>

            <Pagination
                currentPage={currentPage}
                totalPages={totalPages}
                onPageChange={setCurrentPage}
            />
        </div>
    );

    return (
        <div className="pdfrack-wrap min-h-screen bg-slate-50 font-sans text-slate-600">
            {/* Main Header */}
            <header className='bg-white border-b border-slate-200 sticky top-0 z-[60]'>
                <div className="max-w-7xl mx-auto px-4 sm:px-6 lg:px-8 h-16 flex items-center justify-between">
                    <a href="/" className="flex items-center gap-2">
                        {window.pdfRack?.logo && (
                            <img src={window.pdfRack.logo} alt="Logo" className='h-8 w-auto' />
                        )}
                        <span className="font-bold text-lg text-slate-800 hidden sm:inline-block tracking-tight">PDF Rack</span>
                    </a>

                    <div className="flex items-center gap-4">
                        <span className="text-xs font-medium px-2 py-1 bg-slate-100 rounded text-slate-500">v1.0.4</span>
                        <button
                            onClick={() => setShowDocs(true)}
                            title='Read Documentation'
                            className='size-9 flex items-center justify-center text-slate-500 hover:text-indigo-600 hover:bg-indigo-50 rounded-full transition-colors'
                        >
                            <BookOpen className="size-5" />
                        </button>
                    </div>
                </div>
            </header>

            {/* Toolbar */}
            <Toolbar
                view={view}
                onViewChange={setView}
                selectedCount={selectedPdfs.size}
                onBulkDelete={handleBulkDelete}
                onSearch={setSearchQuery}
                onUpload={handleUpload}
                categories={availableCategories}
                tags={availableTags}
                selectedCategory={filterCategory}
                onCategoryChange={setFilterCategory}
                selectedTag={filterTag}
                onTagChange={setFilterTag}
                onSort={handleSort}
                sortConfig={sortConfig}
            />

            {/* Main Content */}
            <main className="max-w-7xl mx-auto px-4 sm:px-6 lg:px-8 py-8">
                {loading ? (
                    <div className="flex flex-col justify-center items-center h-64 gap-4">
                        <div className="animate-spin rounded-full h-10 w-10 border-2 border-indigo-500 border-t-transparent"></div>
                        <p className="text-slate-400 text-sm">Loading your documents...</p>
                    </div>
                ) : error ? (
                    <div className="bg-red-50 border border-red-200 rounded-lg p-6 text-center">
                        <p className="text-red-600 font-medium mb-1">Error Loading PDFs</p>
                        <p className="text-red-500 text-sm">{error}</p>
                    </div>
                ) : filteredPdfs.length === 0 ? (
                    <div className="flex flex-col items-center justify-center py-20 bg-white rounded-2xl border border-dashed border-slate-300">
                        <div className="bg-slate-50 p-4 rounded-full mb-4">
                            <LayoutGrid className="size-8 text-slate-300" />
                        </div>
                        <h3 className="text-lg font-semibold text-slate-900 mb-1">No PDFs Found</h3>
                        <p className="text-slate-500 mb-6 text-center max-w-xs">
                            {searchQuery
                                ? `No results found for "${searchQuery}". Try a different search term.`
                                : "Get started by uploading your first PDF document."
                            }
                        </p>
                        {!searchQuery && (
                            <button
                                onClick={handleUpload}
                                className="px-5 py-2.5 bg-indigo-600 text-white font-medium rounded-lg hover:bg-indigo-700 transition-colors shadow-sm"
                            >
                                Upload PDF
                            </button>
                        )}
                    </div>
                ) : (
                    view === 'grid' ? (
                        <>
                            <div className="grid grid-cols-1 sm:grid-cols-2 md:grid-cols-3 lg:grid-cols-4 xl:grid-cols-5 gap-6">
                                {paginatedPdfs.map((pdf) => (
                                    <PDFItem
                                        key={pdf.id}
                                        pdf={pdf}
                                        view={view}
                                        onOpenModal={setSelectedPdf}
                                        onQuickView={setQuickViewPdf}
                                    />
                                ))}
                            </div>
                            <div className="mt-8">
                                <Pagination
                                    currentPage={currentPage}
                                    totalPages={totalPages}
                                    onPageChange={setCurrentPage}
                                />
                            </div>
                        </>
                    ) : (
                        renderListView()
                    )
                )}
            </main>

            {selectedPdf && (
                <PDFModal
                    pdf={selectedPdf}
                    isOpen={!!selectedPdf}
                    onClose={() => setSelectedPdf(null)}
                    onUpdate={handlePdfUpdate}
                    onDelete={handlePdfDelete}
                />
            )}

            {quickViewPdf && (
                <PDFLightbox
                    pdf={quickViewPdf}
                    onClose={() => setQuickViewPdf(null)}
                />
            )}

            <DocsSlideover
                isOpen={showDocs}
                onClose={() => setShowDocs(false)}
            />
        </div>
    );
}

export default App;