import { attributeSelector } from '../common/selector-utilities';
import { ResultsListController } from '../common/results-list-controller.class';
import { dateToShortIsoString } from '../common/date-formatting';
import { fireEvent } from '@nimius/event-utility';

const ATTRIBUTE = Object.freeze({
    DATE_PICKER: 'data-toubiz-date-picker',
    DATE_PICKER_BUTTON: 'data-toubiz-date-picker-button',
    DATE_LINK: 'data-toubiz-events-date',
    FROM_DATE: 'data-toubiz-events-from-date',
    TO_DATE: 'data-toubiz-events-to-date',
    ACTIVE_CLASSES: 'data-toubiz-events-date.active-classes',
    INACTIVE_CLASSES: 'data-toubiz-events-date.inactive-classes',
});

export class EventsResultsListController extends ResultsListController {

    /** @protected */
    onInitialize () {
        this.initializeEventSpecificBehaviour();
    }

    /** @protected */
    onReinitialize () {
        this.initializeEventSpecificBehaviour();
    }

    /** @private */
    initializeEventSpecificBehaviour () {
        this.initializeDateLinks();
        this.initializeDatePicker();
        this.updateDateFields();

        this.isDateSelection = true;
    }

    /** @private */
    updateDateFields () {
        this.fromDate = this.select(attributeSelector(ATTRIBUTE.FROM_DATE));
        this.toDate = this.select(attributeSelector(ATTRIBUTE.TO_DATE));
    }

    /** @private */
    initializeDateLinks () {
        this.dateLinks = this.select(attributeSelector(ATTRIBUTE.DATE_LINK), true);
        for (const link of this.dateLinks) {
            link.addEventListener('click', event => {
                event.preventDefault();
                this.updateDates(
                    link.getAttribute(ATTRIBUTE.DATE_LINK),
                    link.getAttribute(ATTRIBUTE.DATE_LINK),
                    [ link ]
                );
            });
        }
    }

    /** @private */
    initializeDatePicker () {
        this.picker = this.select(attributeSelector(ATTRIBUTE.DATE_PICKER));
        if (!this.picker) {
            return;
        }

        this.pickerButton = this.select(attributeSelector(ATTRIBUTE.DATE_PICKER_BUTTON));
        this.picker.addEventListener(
            'toubiz-date-picker.change',
            event => this.updateDates(
                event.detail.range.start,
                event.detail.range.end,
                [ this.picker, this.pickerButton ]
            ),
        );
    }

    resetDateSelection () {
        this.fromDate.value = '';
        this.toDate.value = '';
        this.hasDateFiterActive = false;

        fireEvent(this.picker, 'toubiz-date-picker.set', {
            start: null,
            end: null,
        });

        this.toggleSelection();
    }

    /**
     * @private
     * @param {Date|string} fromDate
     * @param {Date|string} toDate
     * @param {HTMLElement} element
     */
    updateDates (fromDate, toDate, elementsToActivate = []) {
        this.hasDateFiterActive = true;
        const fromBefore = this.fromDate.value;
        const toBefore = this.toDate.value;

        fireEvent(this.toggleButton, 'target-enhancement.close');

        const from = (fromDate instanceof Date) ? fromDate : this.parseDateString(fromDate);
        const to = (toDate instanceof Date) ? toDate : this.parseDateString(toDate);
        this.fromDate.value = dateToShortIsoString(from);
        this.toDate.value = dateToShortIsoString(to);

        if (fromBefore !== this.fromDate.value || toBefore !== this.toDate.value) {
            const picker = this.select(attributeSelector(ATTRIBUTE.DATE_PICKER));
            fireEvent(picker, 'toubiz-date-picker.set', { start: from, end: to });
            this.formReload.reload();
            this.toggleSelection(elementsToActivate, true);
        }
    }

    /**
     * @private
     * @param {string} string
     * @returns {Date}
     */
    parseDateString (string) {
        const date = new Date();
        switch (string) {
            case 'today':
                return date;
            case 'tomorrow':
                date.setDate(date.getDate() + 1);
                return date;
            default:
                return new Date(string);
        }
    }

    toggleSelection (elements = [], state = false) {
        this.toggleElementClasses([ ...this.dateLinks, this.picker, this.pickerButton ], false);

        if (elements.length > 0) {
            this.toggleElementClasses(elements, state);
        }
    }
}
