import { __decorate } from "tslib";
/* eslint-disable max-classes-per-file */
/* eslint-disable @typescript-eslint/no-unused-vars */
/* eslint-disable class-methods-use-this */
import { html } from 'lit';
import { property } from 'lit/decorators.js';
import { dedupeMixin } from '@open-wc/dedupe-mixin';
import '../define/ui/ui-icon.js';
export const dragEnterHandler = Symbol('dragEnterHandler');
export const dragLeaveHandler = Symbol('dragLeaveHandler');
export const dragOverHandler = Symbol('dragOverHandler');
export const dropHandler = Symbol('dropHandler');
/**
 * Adds methods to accept files via drag and drop.
 * The mixin register the dnd events on the body element. When an object is dragged over the window it adds
 * this `drop-target` class to the `body` element. Additionally it sets the `dropTargetActive` property.
 *
 * The mixin also assumes that when the `drop-target` is set then the `drop-info` overlay is rendered.
 * However, it does not change the logic if the element is not in the DOM.
 * Use the provided `dropTargetTemplate()` function to generate template for the drag info.
 *
 * The class implementing this mixin should override the `processDroppedFiles(files)`  method
 * to process the incoming files.
 *
 * @mixin
 */
export const FileDropMixin = dedupeMixin((superClass) => {
    class MyMixinClass extends superClass {
        constructor(...args) {
            super(...args);
            this[dragEnterHandler] = this[dragEnterHandler].bind(this);
            this[dragLeaveHandler] = this[dragLeaveHandler].bind(this);
            this[dragOverHandler] = this[dragOverHandler].bind(this);
            this[dropHandler] = this[dropHandler].bind(this);
            this.dropTargetActive = false;
            document.body.addEventListener('dragenter', this[dragEnterHandler]);
            document.body.addEventListener('dragleave', this[dragLeaveHandler]);
            document.body.addEventListener('dragover', this[dragOverHandler]);
            document.body.addEventListener('drop', this[dropHandler]);
        }
        /**
         * Processes dropped to the page files
         * @param files The list of dropped files
         * @abstract This is to be implemented by the platform bindings
         */
        async processDroppedFiles(files) {
            // ...
        }
        /**
         * @returns The template for the drop file message
         */
        dropTargetTemplate() {
            return html `
      <div class="drop-info">
        <ui-icon icon="fileDownload" class="drop-icon"></ui-icon>
        <p class="drop-message">Drop the file here</p>
      </div>
      `;
        }
        [dragEnterHandler](e) {
            if (!e.dataTransfer) {
                return;
            }
            if (![...e.dataTransfer.types].includes('Files')) {
                return;
            }
            e.preventDefault();
            document.body.classList.add('drop-target');
            this.dropTargetActive = true;
            e.dataTransfer.effectAllowed = 'copy';
        }
        [dragLeaveHandler](e) {
            if (!e.dataTransfer) {
                return;
            }
            if (![...e.dataTransfer.types].includes('Files')) {
                return;
            }
            const node = e.target;
            if (node.nodeType !== Node.ELEMENT_NODE) {
                return;
            }
            if (node !== document.body && !node.classList.contains('drop-info')) {
                return;
            }
            e.preventDefault();
            document.body.classList.remove('drop-target');
            this.dropTargetActive = false;
        }
        [dragOverHandler](e) {
            if (!e.dataTransfer) {
                return;
            }
            if (![...e.dataTransfer.types].includes('Files')) {
                return;
            }
            const node = e.target;
            if (node.nodeType !== Node.ELEMENT_NODE) {
                return;
            }
            if (node !== document.body && !node.classList.contains('drop-info')) {
                return;
            }
            e.preventDefault();
            document.body.classList.add('drop-target');
            this.dropTargetActive = true;
        }
        [dropHandler](e) {
            if (!e.dataTransfer) {
                return;
            }
            if (![...e.dataTransfer.types].includes('Files')) {
                return;
            }
            e.preventDefault();
            document.body.classList.remove('drop-target');
            this.dropTargetActive = false;
            this.processDroppedFiles(e.dataTransfer.files);
        }
    }
    __decorate([
        property()
    ], MyMixinClass.prototype, "dropTargetActive", void 0);
    ;
    return MyMixinClass;
});
//# sourceMappingURL=FileDropMixin.js.map