import { CommandLine } from "treehouse/command-line.js";

class PictureUpload extends HTMLElement {
    constructor() {
        super();
    }

    connectedCallback() {
        this.gotoInit();

        this.preview = this.querySelector("img[name='preview']");

        this.addEventListener("click", (event) => {
            if (event.target == this || event.target.parentElement == this) {
                event.preventDefault();
                this.focus();
            }
        });

        this.addEventListener("paste", async (event) => {
            if (event.clipboardData.items.length != 1) {
                console.error("only one item is supported");
                return;
            }

            let item = event.clipboardData.items[0];
            await this.paste(item);
        });
    }

    gotoInit() {
        this.setState("init");
        this.innerHTML = `
            <div class="nothing-pasted" tabindex="0">
                paste or drop an image here to make a picture out of it
            </div>
        `;
        this.querySelector(".nothing-pasted").focus();
    }

    async gotoHavePicture(imageType, imageFile) {
        this.setState("have-picture");
        this.innerHTML = `
            <form name="upload" class="have-picture">
                <img name="preview" class="pic" alt="preview">
                <p>
                    <span name="preview-width"></span> × <span name="preview-height"></span> px (<span name="file-size"></span>)
                </p>

                <p>
                    <label for="label">label</label>
                    <input name="label" type="text" placeholder="untitled"></input>
                </p>

                <p>
                    <label for="compression">compression</label>
                    <select name="compression">
                        <option value="Lossless">lossless</option>
                        <option value="GameScreenshot">game screenshot</option>
                    </select>
                </p>

                <button type="submit" name="upload">upload</button>
            </div>
        `;

        let uploadForm = this.querySelector("form[name='upload']");
        let preview = this.querySelector("img[name='preview']");
        let previewWidth = this.querySelector("[name='preview-width']");
        let previewHeight = this.querySelector("[name='preview-height']");
        let fileSize = this.querySelector("[name='file-size']");
        let label = this.querySelector("[name='label']");
        let compression = this.querySelector("[name='compression']");

        fileSize.textContent = formatSizeSI(imageFile.size);
        label.focus();

        let url = URL.createObjectURL(imageFile);
        preview.src = url;

        createImageBitmap(imageFile).then((bitmap) => {
            console.log(bitmap);
            previewWidth.textContent = bitmap.width.toString();
            previewHeight.textContent = bitmap.height.toString();
        });

        uploadForm.addEventListener("submit", async (event) => {
            event.preventDefault();

            let params = new URLSearchParams({
                label: label.value,
                format: imageType,
                compression: compression.value,
            });
            let response = await fetch(`/dev/picture-upload?${params}`, {
                method: "POST",
                body: imageFile,
            });
            let json = await response.json();
            if (json.error != null) {
                console.error(json.error);
            } else {
                await navigator.clipboard.writeText(json.ulid);
                await this.gotoCopiedToClipboard();
            }
        });
    }

    async gotoCopiedToClipboard() {
        this.setState("copied-to-clipboard");
        this.innerHTML = `
            <div class="copied-to-clipboard">ulid copied to clipboard; the window will now refresh</div>
        `;
    }

    setState(name) {
        this.setAttribute("data-state", name);
    }

    async paste(item) {
        console.log(item);
        if (!isSupportedImageType(item.type)) {
            console.error("unsupported mime type", item.type);
            return;
        }

        let file = item.getAsFile();
        if (file == null) {
            console.error("data transfer does not contain a file");
            return;
        }

        await this.gotoHavePicture(item.type, file);
    }
}

customElements.define("th-picture-upload", PictureUpload);

function isSupportedImageType(mime) {
    return (
        mime == "image/png" ||
        mime == "image/jpeg" ||
        mime == "image/svg+xml" ||
        mime == "image/webp"
    );
}

function formatSizeSI(bytes) {
    return new Intl.NumberFormat(undefined, {
        style: "unit",
        unit: "byte",
        notation: "compact",
        unitDisplay: "narrow",
    }).format(bytes);
}

if (TREEHOUSE_DEV) {
    CommandLine.registerCommand({
        aliases: ["add-pic"],
        description: "add a picture interactively and copy its ulid",
        immediate: true,

        run() {
            let dialog = document.body.appendChild(document.createElement("dialog"));
            dialog.addEventListener("keydown", (event) => {
                if (event.key == "Escape") dialog.close();
            });
            dialog.addEventListener("close", () => {
                dialog.remove();
            });
            dialog.appendChild(new PictureUpload());
            dialog.show();
        },
    });
}
