---
interface Props {
    id?: string;
    title?: string;
    className?: string;
}

const {
    id = "filePreviewModal",
    title = "File Preview",
    className = "",
} = Astro.props;
---

<dialog id={id} class={`modal ${className}`}>
    <!-- Single File Preview -->
    <div id={`${id}-single`} class="modal-box w-11/12 max-w-5xl h-[80vh]">
        <div class="flex justify-between items-center mb-4">
            <h3 class="font-bold text-lg" id={`${id}-title`}>{title}</h3>
            <div class="flex items-center gap-2">
                <a
                    id={`${id}-external-link`}
                    href="#"
                    target="_blank"
                    class="btn btn-sm btn-ghost"
                >
                    <svg
                        xmlns="http://www.w3.org/2000/svg"
                        class="h-4 w-4 mr-1"
                        viewBox="0 0 20 20"
                        fill="currentColor"
                    >
                        <path
                            d="M11 3a1 1 0 100 2h2.586l-6.293 6.293a1 1 0 101.414 1.414L15 6.414V9a1 1 0 102 0V4a1 1 0 00-1-1h-5z"
                        ></path>
                        <path
                            d="M5 5a2 2 0 00-2 2v8a2 2 0 002 2h8a2 2 0 002-2v-3a1 1 0 10-2 0v3H5V7h3a1 1 0 000-2H5z"
                        ></path>
                    </svg>
                    Open in New Tab
                </a>
                <form method="dialog">
                    <button class="btn btn-sm btn-circle btn-ghost">✕</button>
                </form>
            </div>
        </div>
        <div class="h-[calc(100%-4rem)] bg-base-200 rounded-lg">
            <!-- Loading Skeleton -->
            <div id={`${id}-loading`} class="w-full h-full hidden">
                <div class="flex flex-col items-center justify-center h-full">
                    <div
                        class="loading loading-spinner loading-lg text-primary"
                    >
                    </div>
                    <p class="mt-4 text-base-content/70">Loading preview...</p>
                </div>
            </div>

            <!-- Preview Container -->
            <div id={`${id}-preview-container`} class="w-full h-full"></div>
        </div>
    </div>

    <!-- Multiple Files Selection -->
    <div id={`${id}-multiple`} class="modal-box w-11/12 max-w-5xl hidden">
        <div class="flex justify-between items-center mb-4">
            <h3 class="font-bold text-lg">Select File to Preview</h3>
            <form method="dialog">
                <button class="btn btn-sm btn-circle btn-ghost">✕</button>
            </form>
        </div>

        <!-- Multiple Files Loading Skeleton -->
        <div id={`${id}-multiple-loading`} class="hidden">
            <div class="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-3 gap-4">
                {
                    Array(6)
                        .fill(0)
                        .map(() => (
                            <div class="card bg-base-200 animate-pulse">
                                <div class="aspect-video bg-base-300 rounded-t-lg" />
                                <div class="card-body p-4">
                                    <div class="h-4 bg-base-300 rounded w-3/4" />
                                    <div class="h-3 bg-base-300 rounded w-1/2 mt-2 opacity-70" />
                                </div>
                            </div>
                        ))
                }
            </div>
        </div>

        <!-- Files Grid -->
        <div
            class="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-3 gap-4"
            id={`${id}-file-grid`}
        >
            <!-- Files will be dynamically inserted here -->
        </div>
    </div>

    <form method="dialog" class="modal-backdrop">
        <button>close</button>
    </form>
</dialog>

<script define:vars={{ id }}>
    class FilePreviewModal {
        constructor(modalId) {
            this.modal = document.getElementById(modalId);
            this.singleView = document.getElementById(`${modalId}-single`);
            this.multipleView = document.getElementById(`${modalId}-multiple`);
            this.previewContainer = document.getElementById(
                `${modalId}-preview-container`
            );
            this.fileGrid = document.getElementById(`${modalId}-file-grid`);
            this.titleElement = document.getElementById(`${modalId}-title`);
            this.externalLink = document.getElementById(
                `${modalId}-external-link`
            );
            this.loadingElement = document.getElementById(`${modalId}-loading`);
            this.multipleLoadingElement = document.getElementById(
                `${modalId}-multiple-loading`
            );

            // Close modal when clicking backdrop
            this.modal.addEventListener("click", (e) => {
                const dialogDimensions = this.modal.getBoundingClientRect();
                if (
                    e.clientX < dialogDimensions.left ||
                    e.clientX > dialogDimensions.right ||
                    e.clientY < dialogDimensions.top ||
                    e.clientY > dialogDimensions.bottom
                ) {
                    this.modal.close();
                }
            });
        }

        getFileType(fileName) {
            const ext = fileName.split(".").pop()?.toLowerCase() || "";
            // Images
            if (
                ["jpg", "jpeg", "png", "gif", "webp", "svg", "bmp"].includes(
                    ext
                )
            )
                return "image";
            // Videos
            if (["mp4", "webm", "ogg", "mov", "avi"].includes(ext))
                return "video";
            // Audio
            if (["mp3", "wav", "ogg", "m4a", "aac"].includes(ext))
                return "audio";
            // Documents
            if (["pdf"].includes(ext)) return "pdf";
            if (["doc", "docx"].includes(ext)) return "word";
            if (["xls", "xlsx"].includes(ext)) return "excel";
            if (["ppt", "pptx"].includes(ext)) return "powerpoint";
            if (["txt", "rtf", "md"].includes(ext)) return "text";
            // Archives
            if (["zip", "rar", "7z", "tar", "gz"].includes(ext))
                return "archive";
            // Code
            if (
                [
                    "js",
                    "ts",
                    "py",
                    "java",
                    "cpp",
                    "c",
                    "cs",
                    "html",
                    "css",
                    "php",
                    "rb",
                ].includes(ext)
            )
                return "code";
            return "other";
        }

        createPreviewElement(file) {
            const fileType = this.getFileType(file.name);
            let element;

            switch (fileType) {
                case "image":
                    element = document.createElement("img");
                    element.className = "w-full h-full object-contain";
                    element.src = file.url;
                    element.alt = file.name;
                    break;

                case "video":
                    element = document.createElement("video");
                    element.className = "w-full h-full";
                    element.setAttribute("controls", "");
                    element.setAttribute("controlsList", "nodownload");
                    element.setAttribute("preload", "metadata");
                    element.src = file.url;
                    break;

                case "audio":
                    element = document.createElement("div");
                    element.className =
                        "w-full h-full flex flex-col items-center justify-center p-8 gap-4";
                    // Add audio icon
                    element.innerHTML = `
                        <svg xmlns="http://www.w3.org/2000/svg" class="h-24 w-24 text-base-content/50" viewBox="0 0 20 20" fill="currentColor">
                            <path fill-rule="evenodd" d="M9.383 3.076A1 1 0 0110 4v12a1 1 0 01-1.707.707L4.586 13H2a1 1 0 01-1-1V8a1 1 0 011-1h2.586l3.707-3.707a1 1 0 011.09-.217zM14.657 2.929a1 1 0 011.414 0A9.972 9.972 0 0119 10a9.972 9.972 0 01-2.929 7.071 1 1 0 01-1.414-1.414A7.971 7.971 0 0017 10c0-2.21-.894-4.208-2.343-5.657a1 1 0 010-1.414zm-2.829 2.828a1 1 0 011.415 0A5.983 5.983 0 0115 10a5.984 5.984 0 01-1.757 4.243 1 1 0 01-1.415-1.415A3.984 3.984 0 0013 10a3.983 3.983 0 00-1.172-2.828 1 1 0 010-1.415z" clip-rule="evenodd" />
                        </svg>`;
                    const audio = document.createElement("audio");
                    audio.className = "w-full max-w-md";
                    audio.setAttribute("controls", "");
                    audio.setAttribute("controlsList", "nodownload");
                    audio.src = file.url;
                    element.appendChild(audio);
                    break;

                case "pdf":
                    element = document.createElement("embed");
                    element.className = "w-full h-full";
                    element.type = "application/pdf";
                    element.src = file.url + "#toolbar=0&navpanes=0";
                    break;

                case "word":
                case "excel":
                case "powerpoint":
                case "text":
                case "code":
                    // For documents that might be previewable, offer both preview and download
                    element = document.createElement("div");
                    element.className =
                        "w-full h-full flex flex-col items-center justify-center p-8 gap-4";
                    const icon = this.getFileTypeIcon(fileType);
                    element.innerHTML = `
                        <div class="text-center">
                            ${icon}
                            <p class="mt-4 font-medium">${file.name}</p>
                            <p class="text-base-content/70 mb-4">This file type may not be previewable in the browser</p>
                            <div class="flex gap-2">
                                <a href="${file.url}" target="_blank" class="btn btn-primary btn-sm">
                                    <svg xmlns="http://www.w3.org/2000/svg" class="h-4 w-4 mr-2" viewBox="0 0 20 20" fill="currentColor">
                                        <path d="M11 3a1 1 0 100 2h2.586l-6.293 6.293a1 1 0 101.414 1.414L15 6.414V9a1 1 0 102 0V4a1 1 0 00-1-1h-5z" />
                                    </svg>
                                    Open in New Tab
                                </a>
                                <a href="${file.url}" download class="btn btn-ghost btn-sm">
                                    <svg xmlns="http://www.w3.org/2000/svg" class="h-4 w-4 mr-2" viewBox="0 0 20 20" fill="currentColor">
                                        <path fill-rule="evenodd" d="M3 17a1 1 0 011-1h12a1 1 0 110 2H4a1 1 0 01-1-1zm3.293-7.707a1 1 0 011.414 0L9 10.586V3a1 1 0 112 0v7.586l1.293-1.293a1 1 0 111.414 1.414l-3 3a1 1 0 01-1.414 0l-3-3a1 1 0 010-1.414z" clip-rule="evenodd" />
                                    </svg>
                                    Download
                                </a>
                            </div>
                        </div>
                    `;
                    break;

                default:
                    // For other file types, show a download option
                    element = document.createElement("div");
                    element.className =
                        "w-full h-full flex items-center justify-center";
                    element.innerHTML = `
                        <div class="text-center">
                            <svg xmlns="http://www.w3.org/2000/svg" class="h-16 w-16 mx-auto mb-4 text-base-content/50" viewBox="0 0 20 20" fill="currentColor">
                                <path fill-rule="evenodd" d="M4 4a2 2 0 012-2h4.586A2 2 0 0112 2.586L15.414 6A2 2 0 0116 7.414V16a2 2 0 01-2 2H6a2 2 0 01-2-2V4z" clip-rule="evenodd" />
                            </svg>
                            <p class="mb-4">${file.name}</p>
                            <a href="${file.url}" download class="btn btn-primary btn-sm">
                                <svg xmlns="http://www.w3.org/2000/svg" class="h-4 w-4 mr-2" viewBox="0 0 20 20" fill="currentColor">
                                    <path fill-rule="evenodd" d="M3 17a1 1 0 011-1h12a1 1 0 110 2H4a1 1 0 01-1-1zm3.293-7.707a1 1 0 011.414 0L9 10.586V3a1 1 0 112 0v7.586l1.293-1.293a1 1 0 111.414 1.414l-3 3a1 1 0 01-1.414 0l-3-3a1 1 0 010-1.414z" clip-rule="evenodd" />
                                </svg>
                                Download File
                            </a>
                        </div>
                    `;
            }

            return element;
        }

        getFileTypeIcon(fileType) {
            const iconClasses = "h-24 w-24 mx-auto text-base-content/50";
            switch (fileType) {
                case "word":
                    return `<svg xmlns="http://www.w3.org/2000/svg" class="${iconClasses}" viewBox="0 0 384 512">
                        <path fill="currentColor" d="M48 448V64c0-8.8 7.2-16 16-16h256c8.8 0 16 7.2 16 16v384c0 8.8-7.2 16-16 16H64c-8.8 0-16-7.2-16-16zm16-64h256V80H64v304zm48-208h160c8.8 0 16 7.2 16 16s-7.2 16-16 16H112c-8.8 0-16-7.2-16-16s7.2-16 16-16zm0 64h160c8.8 0 16 7.2 16 16s-7.2 16-16 16H112c-8.8 0-16-7.2-16-16s7.2-16 16-16zm0 64h160c8.8 0 16 7.2 16 16s-7.2 16-16 16H112c-8.8 0-16-7.2-16-16s7.2-16 16-16z"/>
                    </svg>`;
                case "excel":
                    return `<svg xmlns="http://www.w3.org/2000/svg" class="${iconClasses}" viewBox="0 0 384 512">
                        <path fill="currentColor" d="M48 448V64c0-8.8 7.2-16 16-16h256c8.8 0 16 7.2 16 16v384c0 8.8-7.2 16-16 16H64c-8.8 0-16-7.2-16-16zm16-64h256V80H64v304zm48-208h160c8.8 0 16 7.2 16 16s-7.2 16-16 16H112c-8.8 0-16-7.2-16-16s7.2-16 16-16zm0 128h160c8.8 0 16 7.2 16 16s-7.2 16-16 16H112c-8.8 0-16-7.2-16-16s7.2-16 16-16z"/>
                    </svg>`;
                case "powerpoint":
                    return `<svg xmlns="http://www.w3.org/2000/svg" class="${iconClasses}" viewBox="0 0 384 512">
                        <path fill="currentColor" d="M48 448V64c0-8.8 7.2-16 16-16h256c8.8 0 16 7.2 16 16v384c0 8.8-7.2 16-16 16H64c-8.8 0-16-7.2-16-16zm16-64h256V80H64v304zm144-208c35.3 0 64 28.7 64 64s-28.7 64-64 64h-48v48c0 8.8-7.2 16-16 16s-16-7.2-16-16V192c0-8.8 7.2-16 16-16h64zm0 96c17.7 0 32-14.3 32-32s-14.3-32-32-32h-48v64h48z"/>
                    </svg>`;
                case "text":
                case "code":
                    return `<svg xmlns="http://www.w3.org/2000/svg" class="${iconClasses}" viewBox="0 0 384 512">
                        <path fill="currentColor" d="M48 448V64c0-8.8 7.2-16 16-16h256c8.8 0 16 7.2 16 16v384c0 8.8-7.2 16-16 16H64c-8.8 0-16-7.2-16-16zm16-64h256V80H64v304zm48-208h160c8.8 0 16 7.2 16 16s-7.2 16-16 16H112c-8.8 0-16-7.2-16-16s7.2-16 16-16zm0 64h160c8.8 0 16 7.2 16 16s-7.2 16-16 16H112c-8.8 0-16-7.2-16-16s7.2-16 16-16z"/>
                    </svg>`;
                default:
                    return `<svg xmlns="http://www.w3.org/2000/svg" class="${iconClasses}" viewBox="0 0 20 20" fill="currentColor">
                        <path fill-rule="evenodd" d="M4 4a2 2 0 012-2h4.586A2 2 0 0112 2.586L15.414 6A2 2 0 0116 7.414V16a2 2 0 01-2 2H6a2 2 0 01-2-2V4z" clip-rule="evenodd" />
                    </svg>`;
            }
        }

        showLoading(isMultiple = false) {
            if (isMultiple) {
                if (this.multipleLoadingElement) {
                    this.multipleLoadingElement.classList.remove("hidden");
                }
                if (this.fileGrid) {
                    this.fileGrid.classList.add("hidden");
                }
            } else {
                if (this.loadingElement) {
                    this.loadingElement.classList.remove("hidden");
                }
                if (this.previewContainer) {
                    this.previewContainer.classList.add("hidden");
                }
            }
        }

        hideLoading(isMultiple = false) {
            if (isMultiple) {
                if (this.multipleLoadingElement) {
                    this.multipleLoadingElement.classList.add("hidden");
                }
                if (this.fileGrid) {
                    this.fileGrid.classList.remove("hidden");
                }
            } else {
                if (this.loadingElement) {
                    this.loadingElement.classList.add("hidden");
                }
                if (this.previewContainer) {
                    this.previewContainer.classList.remove("hidden");
                }
            }
        }

        async showFile(file) {
            this.titleElement.textContent = file.name;
            this.externalLink.href = file.url;

            // Show loading state
            this.showLoading(false);

            try {
                // Clear previous preview
                this.previewContainer.innerHTML = "";

                // Create and append new preview
                const previewElement = this.createPreviewElement(file);

                // Only wait for images to load, PDFs and other files load in their own context
                if (previewElement instanceof HTMLImageElement) {
                    await new Promise((resolve, reject) => {
                        previewElement.onload = resolve;
                        previewElement.onerror = reject;
                        // Add a timeout to prevent infinite loading
                        setTimeout(reject, 10000); // 10 second timeout
                    }).catch((error) => {
                        console.warn("Image load timeout or error:", error);
                        // Continue anyway, the image might still load
                    });
                }

                this.previewContainer.appendChild(previewElement);
            } catch (error) {
                console.error("Error loading file:", error);
                this.previewContainer.innerHTML = `
                    <div class="flex items-center justify-center h-full">
                        <div class="text-center text-error">
                            <svg xmlns="http://www.w3.org/2000/svg" class="h-12 w-12 mx-auto mb-4" viewBox="0 0 20 20" fill="currentColor">
                                <path fill-rule="evenodd" d="M18 10a8 8 0 11-16 0 8 8 0 0116 0zm-7 4a1 1 0 11-2 0 1 1 0 012 0zm-1-9a1 1 0 00-1 1v4a1 1 0 102 0V6a1 1 0 00-1-1z" clip-rule="evenodd" />
                            </svg>
                            <p>Failed to load preview</p>
                            <a href="${file.url}" target="_blank" class="btn btn-primary btn-sm mt-4">Open in New Tab</a>
                        </div>
                    </div>
                `;
            } finally {
                // Hide loading state after a short delay to ensure UI elements are ready
                setTimeout(() => {
                    this.hideLoading(false);
                }, 500);
            }

            // Show single view
            this.singleView.classList.remove("hidden");
            this.multipleView.classList.add("hidden");
        }

        createFileCard(file) {
            const card = document.createElement("div");
            card.className =
                "card bg-base-200 hover:bg-base-300 cursor-pointer transition-colors";

            const fileType = this.getFileType(file.name);
            let preview = "";

            if (fileType === "image") {
                preview = `
                    <div class="aspect-video bg-base-300 rounded-t-lg overflow-hidden">
                        <img src="${file.url}" alt="${file.name}" class="w-full h-full object-cover" loading="lazy">
                    </div>
                `;
            } else {
                const icon = this.getFileTypeIcon(fileType);
                preview = `
                    <div class="aspect-video bg-base-300 rounded-t-lg flex items-center justify-center">
                        ${icon}
                    </div>
                `;
            }

            card.innerHTML = `
                ${preview}
                <div class="card-body p-4">
                    <h3 class="card-title text-sm" title="${file.name}">
                        <span class="truncate">${file.name}</span>
                    </h3>
                    <p class="text-xs opacity-70">${this.getFileTypeLabel(fileType)}</p>
                </div>
            `;

            return card;
        }

        getFileTypeLabel(fileType) {
            switch (fileType) {
                case "image":
                    return "Image";
                case "video":
                    return "Video";
                case "audio":
                    return "Audio";
                case "pdf":
                    return "PDF Document";
                case "word":
                    return "Word Document";
                case "excel":
                    return "Excel Spreadsheet";
                case "powerpoint":
                    return "PowerPoint Presentation";
                case "text":
                    return "Text Document";
                case "code":
                    return "Code File";
                case "archive":
                    return "Archive";
                default:
                    return "File";
            }
        }

        async show(files) {
            this.modal.showModal();

            // Show loading state immediately
            this.showLoading(false);
            this.showLoading(true);

            try {
                // Normalize input to array
                const fileArray = Array.isArray(files) ? files : [files];

                // Handle empty files
                if (fileArray.length === 0) {
                    this.previewContainer.innerHTML = `
                        <div class="flex items-center justify-center h-full">
                            <div class="text-center text-base-content/70">
                                <p>No files available</p>
                            </div>
                        </div>
                    `;
                    this.hideLoading(false);
                    return;
                }

                // Single file view
                if (fileArray.length === 1) {
                    this.singleView.classList.remove("hidden");
                    this.multipleView.classList.add("hidden");
                    await this.showFile(fileArray[0]);
                }
                // Multiple files view
                else {
                    this.singleView.classList.add("hidden");
                    this.multipleView.classList.remove("hidden");

                    // Clear and populate file grid
                    this.fileGrid.innerHTML = "";

                    // Create all file cards and handle their loading
                    const loadingPromises = fileArray.map(async (file) => {
                        const card = this.createFileCard(file);
                        this.fileGrid.appendChild(card);

                        // If it's an image, wait for it to load
                        if (this.getFileType(file.name) === "image") {
                            const img = card.querySelector("img");
                            if (img) {
                                await new Promise((resolve, reject) => {
                                    img.onload = resolve;
                                    img.onerror = reject;
                                    // Add a timeout to prevent infinite loading
                                    setTimeout(resolve, 5000); // 5 second timeout
                                }).catch(console.warn); // Log but don't fail if image fails to load
                            }
                        }
                        return card;
                    });

                    // Wait for all cards to be processed
                    await Promise.all(loadingPromises);

                    // Add click handlers after all cards are loaded
                    const cards = this.fileGrid.querySelectorAll(".card");
                    cards.forEach((card, index) => {
                        card.addEventListener("click", () => {
                            this.showFile(fileArray[index]);
                            this.singleView.classList.remove("hidden");
                            this.multipleView.classList.add("hidden");
                        });
                    });
                }
            } catch (error) {
                console.error("Error showing files:", error);
                this.previewContainer.innerHTML = `
                    <div class="flex items-center justify-center h-full">
                        <div class="text-center text-error">
                            <p>Failed to load files</p>
                            <p class="text-sm mt-2 opacity-70">${error instanceof Error ? error.message : "Unknown error"}</p>
                        </div>
                    </div>
                `;
            } finally {
                // Hide both loading states
                this.hideLoading(false);
                this.hideLoading(true);
            }
        }

        close() {
            this.modal.close();
        }
    }

    // Initialize the modal
    const filePreviewModal = new FilePreviewModal(id);

    // Make it available globally
    window.filePreviewModal = filePreviewModal;
</script>

<style>
    .hidden {
        display: none !important;
    }
</style>
