import ngModule from '../module';
import Section from 'salix/components/section';
import './style.scss';

class Controller extends Section {
    constructor($element, $, vnReport) {
        super($element, $);

        this.vnReport = vnReport;

        const draggable = this.element.querySelector('.travel-list');
        draggable.addEventListener('dragstart',
            event => this.dragStart(event));
        draggable.addEventListener('dragend',
            event => this.dragEnd(event));

        draggable.addEventListener('dragover',
            event => this.dragOver(event));
        draggable.addEventListener('dragenter',
            event => this.dragEnter(event));
        draggable.addEventListener('dragleave',
            event => this.dragLeave(event));

        this.draggableElement = 'tr[draggable]';
        this.droppableElement = 'tbody[vn-droppable]';

        const twoDays = 2;
        const shippedFrom = new Date();
        shippedFrom.setDate(shippedFrom.getDate() - twoDays);
        shippedFrom.setHours(0, 0, 0, 0);

        const sevenDays = 7;
        const landedTo = new Date();
        landedTo.setDate(landedTo.getDate() + sevenDays);
        landedTo.setHours(23, 59, 59, 59);

        this.defaultFilter = {
            shippedFrom: shippedFrom,
            landedTo: landedTo,
            continent: 'AM'
        };

        this.smartTableOptions = {};
    }

    get hasDateRange() {
        const userParams = this.$.model.userParams;
        const hasLanded = userParams.landedTo;
        const hasShipped = userParams.shippedFrom;
        const hasContinent = userParams.continent;
        const hasWarehouseOut = userParams.warehouseOutFk;

        return hasLanded || hasShipped || hasContinent || hasWarehouseOut;
    }

    onDragInterval() {
        if (this.dragClientY > 0 && this.dragClientY < 75)
            this.$window.scrollTo(0, this.$window.scrollY - 10);

        const maxHeight = window.screen.availHeight - (window.outerHeight - window.innerHeight);
        if (this.dragClientY > maxHeight - 75 && this.dragClientY < maxHeight)
            this.$window.scrollTo(0, this.$window.scrollY + 10);
    }

    findDraggable($event) {
        const target = $event.target;
        const draggable = target.closest(this.draggableElement);

        return draggable;
    }

    findDroppable($event) {
        const target = $event.target;
        const droppable = target.closest(this.droppableElement);

        return droppable;
    }

    dragStart($event) {
        const draggable = this.findDraggable($event);
        draggable.classList.add('dragging');

        const id = parseInt(draggable.id);
        this.entryId = id;
        this.entry = draggable;
        this.interval = setInterval(() => this.onDragInterval(), 50);
    }

    dragEnd($event) {
        const draggable = this.findDraggable($event);
        draggable.classList.remove('dragging');
        this.entryId = null;
        this.entry = null;

        clearInterval(this.interval);
    }

    onDrop($event) {
        const model = this.$.model;
        const droppable = this.findDroppable($event);
        const travelId = parseInt(droppable.id);

        const currentDroppable = this.entry.closest(this.droppableElement);

        if (currentDroppable == droppable) return;

        if (this.entryId && travelId) {
            const path = `Entries/${this.entryId}`;
            this.$http.patch(path, {travelFk: travelId})
                .then(() => model.refresh())
                .then(() => this.vnApp.showSuccess(this.$t('Data saved!')));
        }
    }

    undrop() {
        if (!this.dropping) return;
        this.dropping.classList.remove('dropping');
        this.dropping = null;
    }

    dragOver($event) {
        this.dragClientY = $event.clientY;
        $event.preventDefault();
    }

    dragEnter($event) {
        let element = this.findDroppable($event);
        if (element) this.dropCount++;

        if (element != this.dropping) {
            this.undrop();
            if (element) element.classList.add('dropping');
            this.dropping = element;
        }
    }

    dragLeave($event) {
        let element = this.findDroppable($event);

        if (element) {
            this.dropCount--;
            if (this.dropCount == 0) this.undrop();
        }
    }

    save(id, data) {
        const endpoint = `Travels/${id}`;
        this.$http.patch(endpoint, data)
            .then(() => this.vnApp.showSuccess(this.$t('Data saved!')));
    }

    get reportParams() {
        const userParams = this.$.model.userParams;
        return Object.assign({
            authorization: this.vnToken.token
        }, userParams);
    }

    showReport() {
        this.vnReport.show(`Travels/extra-community-pdf`, this.reportParams);
    }
}

Controller.$inject = ['$element', '$scope', 'vnReport'];

ngModule.vnComponent('vnTravelExtraCommunity', {
    template: require('./index.html'),
    controller: Controller
});