"use strict";

const events = require("../events.js");
const views = require("../util/views.js");

const template = views.getTemplate("file-dropper");

const KEY_RETURN = 13;

class FileDropperControl extends events.EventTarget {
    constructor(target, options) {
        super();

        this._options = options;
        const source = template({
            extraText: options.extraText,
            allowMultiple: options.allowMultiple,
            allowUrls: options.allowUrls,
            lock: options.lock,
            id: "file-" + Math.random().toString(36).substring(7),
            urlPlaceholder:
                options.urlPlaceholder || "Alternatively, paste an URL here.",
        });

        this._dropperNode = source.querySelector(".file-dropper");
        this._urlInputNode = source.querySelector("input[type=text]");
        this._urlConfirmButtonNode = source.querySelector("button");
        this._fileInputNode = source.querySelector("input[type=file]");
        this._fileInputNode.style.display = "none";
        this._fileInputNode.multiple = options.allowMultiple || false;

        this._counter = 0;
        this._dropperNode.addEventListener("dragenter", (e) =>
            this._evtDragEnter(e)
        );
        this._dropperNode.addEventListener("dragleave", (e) =>
            this._evtDragLeave(e)
        );
        this._dropperNode.addEventListener("dragover", (e) =>
            this._evtDragOver(e)
        );
        this._dropperNode.addEventListener("drop", (e) => this._evtDrop(e));
        this._fileInputNode.addEventListener("change", (e) =>
            this._evtFileChange(e)
        );

        if (this._urlInputNode) {
            this._urlInputNode.addEventListener("keydown", (e) =>
                this._evtUrlInputKeyDown(e)
            );
        }
        if (this._urlConfirmButtonNode) {
            this._urlConfirmButtonNode.addEventListener("click", (e) =>
                this._evtUrlConfirmButtonClick(e)
            );
        }

        this._originalHtml = this._dropperNode.innerHTML;
        views.replaceContent(target, source);
    }

    reset() {
        this._dropperNode.innerHTML = this._originalHtml;
        this.dispatchEvent(new CustomEvent("reset"));
    }

    _emitFiles(files) {
        files = Array.from(files);
        if (this._options.lock) {
            this._dropperNode.innerText = files
                .map((file) => file.name)
                .join(", ");
        }
        this.dispatchEvent(
            new CustomEvent("fileadd", { detail: { files: files } })
        );
    }

    _emitUrls(urls) {
        urls = Array.from(urls).map((url) => url.trim());
        if (this._options.lock) {
            this._dropperNode.innerText = urls
                .map((url) => url.split(/\//).reverse()[0])
                .join(", ");
        }
        for (let url of urls) {
            if (!url) {
                return;
            }
            if (!url.match(/^https?:\/\/[^.]+\..+$/)) {
                window.alert(`"${url}" does not look like a valid URL.`);
                return;
            }
        }
        this.dispatchEvent(
            new CustomEvent("urladd", { detail: { urls: urls } })
        );
    }

    _evtDragEnter(e) {
        this._dropperNode.classList.add("active");
        this._counter++;
    }

    _evtDragLeave(e) {
        this._counter--;
        if (this._counter === 0) {
            this._dropperNode.classList.remove("active");
        }
    }

    _evtDragOver(e) {
        e.preventDefault();
    }

    _evtFileChange(e) {
        this._emitFiles(e.target.files);
    }

    _evtDrop(e) {
        e.preventDefault();
        this._dropperNode.classList.remove("active");
        if (!e.dataTransfer.files.length) {
            window.alert("Only files are supported.");
        }
        if (!this._options.allowMultiple && e.dataTransfer.files.length > 1) {
            window.alert("Cannot select multiple files.");
        }
        this._emitFiles(e.dataTransfer.files);
    }

    _evtUrlInputKeyDown(e) {
        if (e.which !== KEY_RETURN) {
            return;
        }
        e.preventDefault();
        this._dropperNode.classList.remove("active");
        this._emitUrls(this._urlInputNode.value.split(/[\r\n]/));
        this._urlInputNode.value = "";
    }

    _evtUrlConfirmButtonClick(e) {
        e.preventDefault();
        this._dropperNode.classList.remove("active");
        this._emitUrls(this._urlInputNode.value.split(/[\r\n]/));
        this._urlInputNode.value = "";
    }
}

module.exports = FileDropperControl;
