'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');
        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;
