import React, { useEffect, useRef, useState, useCallback } from 'react';
import Quill, { Op } from 'quill';
import 'quill/dist/quill.snow.css';
import katex from 'katex';
import 'katex/dist/katex.min.css';
import { Article, FileInfo } from '../types/article';
import api from '../utils/api';
import { Link } from 'react-router-dom';
import { Rating, Snackbar, Alert } from '@mui/material';
import { useUser } from '../contexts/UserContext';
import { Role } from '../types/user';
import JSZip from 'jszip';
import { saveAs } from 'file-saver';

interface DisplayerProps {
    article?: Article;
    preview?: boolean;
}

enum ArticleStatus {
    APPROVED = 'APPROVED',
    REJECTED = 'REJECTED'
}

const Displayer = (props: DisplayerProps) => {
    const { article, preview } = props;
    const { user } = useUser();

    const [zipBusy, setZipBusy] = useState(false);   // loading flag
    const viewerRef = useRef<HTMLDivElement | null>(null);
    const quillRef = useRef<Quill | null>(null);

    interface ArticleMeta {
        id: number;
        title: string;
        short_description?: string;
        time_estimate: number;
        difficulty?: string;
        topic?: string;
        type?: string;
        files?: FileInfo[];
    }

    const [articleMeta, setArticleMeta] = useState<ArticleMeta | null>(null);
    const [error, setError] = useState<string | null>(null);
    const [sourceLabel, setSourceLabel] = useState('');
    const [articleHandled, setArticleHandled] = useState(false);

    // Popup state
    const [popupOpen, setPopupOpen] = useState(false);
    const [popupMessage, setPopupMessage] = useState('');

    const acceptArticle = async () => {
        if (!articleMeta) return;
        try {
            await api.post(`/editor/setarticlestatus/${articleMeta.id}/${ArticleStatus.APPROVED}`);
            setError(null);
            setPopupMessage("Článek byl schválen.");
            setPopupOpen(true);
            setArticleHandled(true);
        } catch (e: any) {
            setError(`Failed to accept article: ${e.message}`);
        }
    };

    const downloadAllFilesAsZip = useCallback(async () => {
        if (!articleMeta?.files?.length) return;

        try {
            setZipBusy(true);

            const zip = new JSZip();

            await Promise.all(
                articleMeta.files.map(async (file) => {
                    const url = `/articles/download/${articleMeta.id}/${file.id}`;
                    const { data } = await api.get<Blob>(url, {
                        responseType: 'blob',   // axios delivers a Blob
                    });
                    zip.file(file.name, data);
                })
            );

            const zipBlob = await zip.generateAsync({ type: 'blob' });
            saveAs(zipBlob, 'Pomucky.zip');
        } catch (err: any) {
            // Show the same snackbar you already use elsewhere
            setPopupMessage(`ZIP selhal: ${err.message}`);
            setPopupOpen(true);
        } finally {
            setZipBusy(false);
        }
    }, [articleMeta]);

    const rejectArticle = async () => {
        if (!articleMeta) return;
        try {
            await api.post(`/editor/setarticlestatus/${articleMeta.id}/${ArticleStatus.REJECTED}`);
            setError(null);
            setPopupMessage("Článek byl zamítnut.");
            setPopupOpen(true);
            setArticleHandled(true);
        } catch (e: any) {
            setError(`Failed to reject article: ${e.message}`);
        }
    };

    useEffect(() => {
        if (!viewerRef.current || quillRef.current) return;

        const BlockEmbed: any = Quill.import('blots/block/embed');
        const Embed: any = Quill.import('blots/embed');

        class GeoGebraBlot extends BlockEmbed {
            static create(id) {
                const node = super.create();
                const frame = document.createElement('iframe');
                frame.src = `https://www.geogebra.org/material/iframe/id/${id}`;
                frame.width = '800';
                frame.height = '600';
                frame.allowFullscreen = true;
                frame.style.border = '1px solid #e4e4e4';
                node.appendChild(frame);
                return node;
            }
            static value(node) {
                return node.querySelector('iframe').src.split('/').pop();
            }
        }
        GeoGebraBlot.blotName = 'geogebra';
        GeoGebraBlot.tagName = 'div';
        GeoGebraBlot.className = 'ql-geogebra';

        class PDFBlot extends BlockEmbed {
            static create(v) {
                const node = super.create();
                const container = document.createElement('div');
                container.className = 'pdf-container';

                const controls = document.createElement('div');
                controls.className = 'pdf-controls';

                const name = document.createElement('span');
                name.className = 'pdf-filename';
                name.textContent = v.name ?? 'document.pdf';
                controls.appendChild(name);

                const dl = document.createElement('button');
                dl.textContent = 'Download';
                dl.className = 'pdf-download-btn';
                dl.onclick = () => {
                    const a = document.createElement('a');
                    a.href = v.url;
                    a.download = v.name ?? 'document.pdf';
                    a.click();
                };
                controls.appendChild(dl);
                container.appendChild(controls);

                const iframe = document.createElement('iframe');
                iframe.src = v.url;
                iframe.width = '60%';
                iframe.height = '500';
                iframe.style.border = 'none';
                iframe.className = 'pdf-iframe';
                container.appendChild(iframe);
                node.appendChild(container);

                node.dataset.pdfUrl = v.url;
                node.dataset.pdfName = v.name ?? '';
                return node;
            }
            static value(node) {
                return { url: node.dataset.pdfUrl, name: node.dataset.pdfName };
            }
        }
        PDFBlot.blotName = 'pdf';
        PDFBlot.tagName = 'div';
        PDFBlot.className = 'quill-pdf-blot';

        class InlineEmbed extends Embed {
            static create(value) {
                const node = super.create();
                node.setAttribute('data-value', value);
                node.innerText = value;
                return node;
            }
            static value(node) {
                return node.getAttribute('data-value');
            }
        }
        InlineEmbed.blotName = 'inlineEmbed';
        InlineEmbed.tagName = 'SPAN';
        InlineEmbed.className = 'inline-embed';

        class LatexBlot extends InlineEmbed {
            static create(value) {
                const node = super.create(value);
                node.setAttribute('data-formula', value);
                try {
                    katex.render(value, node, {
                        displayMode: false,
                        throwOnError: false,
                        errorColor: '#f00',
                        output: 'html'
                    });
                } catch (error) {
                    console.error('KaTeX inline rendering error:', error);
                    node.innerText = value;
                    node.classList.add('katex-error');
                }
                return node;
            }
            static value(node) {
                return node.getAttribute('data-formula');
            }
        }
        LatexBlot.blotName = 'latex';
        LatexBlot.tagName = 'span';
        LatexBlot.className = 'ql-formula-inline';

        Quill.register(GeoGebraBlot);
        Quill.register(PDFBlot);
        Quill.register(InlineEmbed);
        Quill.register(LatexBlot);

        quillRef.current = new Quill(viewerRef.current, {
            theme: 'snow',
            readOnly: true,
            modules: { toolbar: false }
        });

        if (viewerRef.current) {
            (viewerRef.current as HTMLElement)?.querySelector('.ql-toolbar')?.remove();
            const editor: HTMLElement | null = viewerRef.current?.querySelector('.ql-editor');
            if (editor) editor.style.border = 'none';
            (viewerRef.current as HTMLElement).style.border = 'none';
        }
    }, []);

    const feedArticle = (data: Article, label = '') => {
        if (!data || !quillRef.current) return;
        try {
            setArticleMeta({
                id: data.id,
                title: data.title,
                short_description: data.short_description,
                time_estimate: data.time_estimate,
                difficulty: data.difficulty,
                topic: data.topic,
                type: data.type,
                files: data.files
            });
            setSourceLabel(label);
            setError(null);
            const ops: Op[] = data.content.ops;
            quillRef.current.setContents(ops);
        } catch (e: any) {
            setError(`Failed to render article: ${e.message}`);
        }
    };

    useEffect(() => {
        if (article) feedArticle(article, 'props');
    }, [article]);

    const handleChooseFile = (e: React.ChangeEvent<HTMLInputElement>) => {
        const f = e.target.files?.[0];
        if (!f) return;
        const reader = new FileReader();
        reader.onload = ev => {
            try {
                if (!ev.target || typeof ev.target.result !== 'string') {
                    throw new Error("File reading failed or invalid file content.");
                }
                const json = JSON.parse(ev.target.result);
                feedArticle(json, f.name);
            } catch (err: any) {
                setError(`Unsupported file: ${err.message}`);
            }
        };
        reader.readAsText(f);
    };

    const handleLoadFromLocalStorage = () => {
        try {
            const raw = localStorage.getItem('articleData');
            if (!raw) return setError('Nothing in localStorage under “articleData”.');
            feedArticle(JSON.parse(raw), 'localStorage');
        } catch (e: any) {
            setError(`localStorage error: ${e.message}`);
        }
    };

    const getFileIcon = (fileName: string) => {
        const ext = fileName.split('.').pop()?.toLowerCase();
        switch (ext) {
            case 'jpg':
            case 'jpeg':
            case 'png':
            case 'gif':
                return '📷';
            case 'pdf':
                return '📄';
            case 'doc':
            case 'docx':
                return '📝';
            case 'xls':
            case 'xlsx':
                return '📊';
            default:
                return '📎';
        }
    };

    return (
        <div className="delta-viewer-container max-w-6xl mx-auto px-4 py-8">
            {articleMeta && (
                <header className="article-meta mb-8 border border-green-200 bg-white shadow-sm rounded-lg p-6">
                    <h1 className="text-3xl font-semibold text-green-800 mb-2">{articleMeta.title}</h1>
                    {articleMeta.short_description && (
                        <p className="text-lg text-gray-700 mb-4">{articleMeta.short_description}</p>
                    )}
                    <dl className="grid grid-cols-1 sm:grid-cols-2 md:grid-cols-4 gap-y-2 gap-x-6 text-sm text-gray-800">
                        {articleMeta.time_estimate && (
                            <div>
                                <dt className="font-medium text-green-700">Časová náročnost</dt>
                                <dd>{articleMeta.time_estimate} min</dd>
                            </div>
                        )}
                        {articleMeta.difficulty && (
                            <div>
                                <dt className="font-medium text-green-700">Obtížnost</dt>
                                <dd>{articleMeta.difficulty}</dd>
                            </div>
                        )}
                        {articleMeta.topic && (
                            <div>
                                <dt className="font-medium text-green-700">Téma</dt>
                                <dd>{articleMeta.topic}</dd>
                            </div>
                        )}
                        {articleMeta.type && (
                            <div>
                                <dt className="font-medium text-green-700">Typ obsahu</dt>
                                <dd>{articleMeta.type === 'physical' ? 'Fyzický' : 'Digitální'}</dd>
                            </div>
                        )}
                    </dl>
                </header>
            )}

            {error && (
                <div className="p-4 mb-4 bg-red-100 text-red-700 rounded">{error}</div>
            )}

            <div className="flex gap-6">
                <div className="flex-1">
                    <div className="viewer-container border rounded p-4" style={{ minHeight: 300 }}>
                        <div ref={viewerRef} />
                    </div>
                </div>

                <div className="w-64">
                    {preview && !articleHandled && user?.role === Role.SPRAVCE ? (
                        <div className="flex flex-col gap-2 mb-4 border rounded-lg shadow-md p-4 bg-white">
                            <h3 className="text-xl font-semibold text-green-800 mb-3">Správa</h3>
                            <button
                                onClick={acceptArticle}
                                className="px-4 py-2 bg-green-500 text-white rounded hover:bg-green-600 hover:scale-105 transition-transform duration-200">
                                Schválit
                            </button>
                            <button
                                onClick={rejectArticle}
                                className="px-4 py-2 bg-red-500 text-white rounded hover:bg-red-600 hover:scale-105 transition-transform duration-200">
                                Zamítnout
                            </button>
                        </div>
                    ) : preview && !articleHandled ? (
                        <div className="mb-4 border-l-4 border-yellow-400 bg-white p-4 rounded">
                            <p className="text-yellow-800 text-lg font-semibold">Článek čeká na schválení.</p>
                        </div>
                    ) : null}

                    <aside className="files-sidebar border rounded-lg shadow-md p-4 bg-white">
                        <h3 className="text-xl font-semibold text-green-800 mb-3">Pomůcky</h3>
                        {articleMeta?.files?.length ? (
                            <button
                                onClick={downloadAllFilesAsZip}
                                disabled={zipBusy}
                                className={`w-full mb-4 px-4 py-2 rounded transition
                                    ${zipBusy
                                        ? 'bg-gray-400 cursor-wait'
                                        : 'bg-green-500 hover:bg-green-600 text-white'}`}
                            >
                                {zipBusy ? 'Zpracovávám…' : 'Stáhnout všechny (ZIP)'}
                            </button>
                        ) : null}
                        {articleMeta && articleMeta.files && articleMeta.files.length > 0 ? (
                            <ul className="divide-y divide-gray-200 mb-4">
                                {articleMeta.files.map(file => (
                                    <li key={file.id} className="flex items-center justify-between py-2">
                                        <div className="flex items-center gap-2">
                                            <span className="text-lg">{getFileIcon(file.name)}</span>
                                            <span className="text-sm text-gray-700">{file.name}</span>
                                        </div>
                                        <a
                                            href={`${import.meta.env.VITE_API_URL}/articles/download/${articleMeta.id}/${file.id}`}
                                            target="_blank"
                                            rel="noopener noreferrer"
                                            className="inline-flex items-center text-green-600 hover:text-green-800 transition-colors duration-200"
                                            title="Download file">
                                            <svg xmlns="http://www.w3.org/2000/svg" className="h-5 w-5" fill="none" viewBox="0 0 24 24" stroke="currentColor">
                                                <path strokeLinecap="round" strokeLinejoin="round" strokeWidth="2" d="M4 16v1a2 2 0 002 2h12a2 2 0 002-2v-1M7 10l5 5m0 0l5-5m-5 5V4" />
                                            </svg>
                                        </a>
                                    </li>
                                ))}
                            </ul>
                        ) : (
                            <p className="text-gray-500 mb-4">Žádné soubory.</p>
                        )}
                    </aside>
                    {!preview && (
                        <div className="flex flex-col gap-2 items-center">
                            <p className="text-green-950 text-center">Hodnocení článku:</p>
                            <Rating name="rating" defaultValue={2.5} precision={0.5} />
                        </div>
                    )}
                </div>
            </div>

            <Snackbar
                open={popupOpen}
                autoHideDuration={3000}
                onClose={() => setPopupOpen(false)}
                anchorOrigin={{ vertical: 'top', horizontal: 'center' }}>
                <Alert onClose={() => setPopupOpen(false)} severity="success" sx={{ width: '100%' }}>
                    {popupMessage}
                </Alert>
            </Snackbar>
        </div>
    );
}
export default Displayer;
