export class AttachmentUploader {
    constructor(form) {
        this.form = form;
        this.attachments = [];
        this.maxSize = parseInt(form.dataset.maxSize || "10", 10) * 1024 * 1024;
        this.maxFiles = parseInt(form.dataset.maxFiles || "10", 10);
        this.allowedTypes = (form.dataset.allowedTypes || "").split(",").map((t) => t.trim()).filter(Boolean);
        this.container = form.querySelector(".attachment-upload-container");
        if (!this.container) return;
        this.uploadedUidsInput = null;
        this.initZone();
    }

    initZone() {
        this.button = document.createElement("button");
        this.button.type = "button";
        this.button.className = "attachment-upload-btn";
        this.button.innerHTML = "&#x1F4CE;";
        this.button.title = "Attach files";

        const input = document.createElement("input");
        input.type = "file";
        input.multiple = true;
        input.style.display = "none";
        input.addEventListener("change", () => this.handleFiles(input.files));

        this.button.addEventListener("click", (e) => {
            e.preventDefault();
            input.click();
        });

        this.button.addEventListener("dragover", (e) => {
            e.preventDefault();
            this.button.classList.add("dragover");
        });
        this.button.addEventListener("dragleave", () => {
            this.button.classList.remove("dragover");
        });
        this.button.addEventListener("drop", (e) => {
            e.preventDefault();
            this.button.classList.remove("dragover");
            this.handleFiles(e.dataTransfer.files);
        });

        this.previewList = document.createElement("div");
        this.previewList.className = "attachment-preview-list";
        this.errorEl = document.createElement("div");
        this.errorEl.className = "attachment-upload-error";

        this.container.appendChild(this.button);
        this.container.appendChild(input);

        this.container.after(this.errorEl);
        this.container.after(this.previewList);

        this.uploadedUidsInput = document.createElement("input");
        this.uploadedUidsInput.type = "hidden";
        this.uploadedUidsInput.name = "attachment_uids";
        this.form.appendChild(this.uploadedUidsInput);
    }

    async handleFiles(files) {
        this.errorEl.textContent = "";
        const remaining = this.maxFiles - this.attachments.length;
        if (files.length > remaining) {
            this.showError(`You can only add ${remaining} more file(s).`);
            return;
        }
        for (const file of files) {
            if (file.size > this.maxSize) {
                this.showError(`"${file.name}" exceeds the ${this.form.dataset.maxSize || 10}MB limit.`);
                continue;
            }
            if (this.allowedTypes.length > 0) {
                const ext = "." + file.name.split(".").pop().toLowerCase();
                if (!this.allowedTypes.includes(ext)) {
                    this.showError(`"${file.name}" type is not allowed.`);
                    continue;
                }
            }
            await this.uploadFile(file);
        }
    }

    async uploadFile(file) {
        this.button.classList.add("uploading");
        const preview = this.createPreview(file);
        this.previewList.appendChild(preview);
        const progressBar = preview.querySelector(".attachment-progress-bar");

        const formData = new FormData();
        formData.append("file", file);

        try {
            const xhr = new XMLHttpRequest();
            xhr.open("POST", "/uploads/upload");
            xhr.upload.addEventListener("progress", (e) => {
                if (e.lengthComputable && progressBar) {
                    const pct = Math.round((e.loaded / e.total) * 100);
                    progressBar.style.width = pct + "%";
                }
            });

            const result = await new Promise((resolve, reject) => {
                xhr.onload = () => {
                    if (xhr.status >= 200 && xhr.status < 300) {
                        try { resolve(JSON.parse(xhr.responseText)); }
                        catch { reject(new Error("Invalid response")); }
                    } else {
                        reject(new Error(xhr.responseText || "Upload failed"));
                    }
                };
                xhr.onerror = () => reject(new Error("Network error"));
                xhr.send(formData);
            });

            if (result && result.uid) {
                this.attachments.push(result);
                this.updateUids();
                preview.dataset.uid = result.uid;
                if (result.thumbnail_url) {
                    const img = preview.querySelector("img");
                    if (img) img.src = result.thumbnail_url;
                }
            }
        } catch (err) {
            this.showError(err.message);
            preview.remove();
        } finally {
            this.button.classList.remove("uploading");
        }
    }

    createPreview(file) {
        const div = document.createElement("div");
        div.className = "attachment-preview";
        const isImage = file.type && file.type.startsWith("image/");
        if (isImage) {
            const img = document.createElement("img");
            img.src = URL.createObjectURL(file);
            img.alt = file.name;
            div.appendChild(img);
        } else {
            const iconDiv = document.createElement("div");
            iconDiv.className = "file-icon";
            iconDiv.innerHTML = `<span class="icon">&#x1F4CE;</span><span>${file.name}</span>`;
            div.appendChild(iconDiv);
        }
        const remove = document.createElement("button");
        remove.type = "button";
        remove.className = "attachment-remove";
        remove.innerHTML = "&times;";
        remove.addEventListener("click", () => {
            const idx = this.attachments.findIndex((a) => a.uid === div.dataset.uid);
            if (idx !== -1) {
                this.attachments.splice(idx, 1);
                this.updateUids();
            }
            div.remove();
        });
        div.appendChild(remove);
        const progress = document.createElement("div");
        progress.className = "attachment-progress";
        progress.innerHTML = '<div class="attachment-progress-bar" style="width:0%"></div>';
        div.appendChild(progress);
        return div;
    }

    updateUids() {
        const uids = this.attachments.map((a) => a.uid);
        this.uploadedUidsInput.value = uids.join(",");
    }

    showError(msg) {
        this.errorEl.textContent = msg;
        setTimeout(() => { if (this.errorEl.textContent === msg) this.errorEl.textContent = ""; }, 5000);
    }
}

window.AttachmentUploader = AttachmentUploader;
