import "../../libs/Mobiscroll/js/mobiscroll.jquery.min";
import * as moment from "moment";
import { MbscCalendarOptions } from "../../libs/Mobiscroll/js/mobiscroll.jquery.min";

/**
 * Datepicker module options
 */
export interface ICalendarModuleOptions {
    /**
     * Date format to when a date is picked
     */
    dateFormat?: string;
    /**
     * Time format to when a date is picked
     */
    timeFormat?: string;
    /**
     * Localization "da" is default, use "en" for english version
     */
    lang?: string;
    /**
     * This event is triggered when a date is selceted
     */
    onSetDate?: (event: any, inst: any) => void;
    /**
     * This event is triggered when a Set button is clicked
     */
    onSet?: (event: any, inst: any) => void;
    /**
     * This event is triggered when the datepicker is initialized
     */
    onInit?: (event: any, inst: any) => void;
    /**
     * Min date for datepicker
     */
    min?: moment.Moment;
    /**
     * Max date for datepicker
     */
    max?: moment.Moment;
    /**
     * Rendering mode, default value is "calender". Possible values: ['time', 'calendar'], ['date', 'calendar'] or [calendar]
     */
    calenderTypeOption?: DatetimePickerTypeEnum;

    /**
     * If true, the scroll wheels are circular.
     */
    circular?: boolean | boolean[];

    /**
     * If true clear button is visible on mobile devices
     */
    allowClear?: boolean;
    /**
     * Optional: Override additional mobiscroll settings. Does not override datepicker settings defined in ICalendarModuleOptions.
     */
    additionalMbscCalenderOptions?: MbscCalendarOptions;
}

interface IMobiscrollCalendarOptions extends MbscCalendarOptions {
    responsive?: IMobiscrollResponsiveOptions;
}

interface IMobiscrollResponsiveOptions {
    xsmall?: IMobiscrollResponsiveOption;
    small?: IMobiscrollResponsiveOption;
    medium?: IMobiscrollResponsiveOption;
    large?: IMobiscrollResponsiveOption;
    xlarge?: IMobiscrollResponsiveOption;
}

export enum DatetimePickerTypeEnum {
    Time = 1,
    Date = 2,
    DateAndTime = 3
}

interface IMobiscrollResponsiveOption {
    touchUi?: boolean;
    buttons?: string[];
}

export default class DatetimePickerModule {

    public $element: JQuery;

    private readonly moduleInitKey = "calendarmoduleinitialized";

     /**
      * Init the datepicker
      * @param selector Selector or HTML element for the datepicker you want to initialize
      * @param options Options for the datepicker
      */
    public init(selector: string | HTMLElement, options?: ICalendarModuleOptions) {
        this.initCalendarModule(selector, options);
    }

    public getInstance(selector: string) {
        return $(selector).mobiscroll("getInst");
    }

    public setDate(selector: string, date: moment.Moment) {
        const modules = this.getCalendarModules(selector);
        modules.forEach((m) => m.setVal(date));
    }

    private initCalendarModule(selector: string | HTMLElement, options: ICalendarModuleOptions): void {

        this.$element = $(selector as any);

        const defaultOptions: IMobiscrollCalendarOptions = {
            controls: ["calendar", "time"],
            lang: "da",
            dateFormat: "dd/mm/yy",
            setOnDayTap: false,
            timeFormat: "HH:ii",
            focusTrap: false,
            onSetDate: function(event: any, instance: any) {
                if (event.control === "calendar") {
                    instance.changeTab("time");
                }
            },
            responsive: {
                xsmall: { // xsmall = min-width: 0px
                    touchUi: true,
                    buttons: options.allowClear === true ? ["cancel", "clear", "set"] : ["cancel", "set"]
                },
                xlarge: { // xlarge = min-width: 1200px
                    touchUi: false,
                    buttons: options.allowClear === true ? ["clear"] : []
                }
            },
            circular: true,
            onShow: (event, instance) => {
                const $inputGroupParent = $(instance.element).parent(".input-group");
                $inputGroupParent.addClass("focus");
            }
        };

        let calendarOptions = defaultOptions;

        if (options !== undefined) {
            calendarOptions = $.extend(true, defaultOptions, options);

            if (options.calenderTypeOption !== undefined && options.calenderTypeOption !== null) {
                if (options.calenderTypeOption === DatetimePickerTypeEnum.Date) {
                    calendarOptions.controls = ["calendar", "date"];
                    calendarOptions.setOnDayTap = true;
                } else if (options.calenderTypeOption === DatetimePickerTypeEnum.DateAndTime) {
                    calendarOptions.controls = ["calendar", "time"];
                } else if (options.calenderTypeOption === DatetimePickerTypeEnum.Time) {
                    calendarOptions.controls = ["time"];
                }
            }
        }

        if (options.additionalMbscCalenderOptions !== undefined) {
            calendarOptions = $.extend(true, {}, calendarOptions, options.additionalMbscCalenderOptions);
        }

        this.$element.each((index, element) => {
            const $element = $(element);

            if ($element.data(this.moduleInitKey) === true) {
                return;
            }

            $element.mobiscroll().calendar(calendarOptions);
            $element.find("input").attr("autocomplete", "off");
            $element.attr("autocomplete", "off");
            $element.data(this.moduleInitKey, true);

            const $inputGroupParent = $element.parent(".input-group");
            if ($inputGroupParent !== undefined && $inputGroupParent.length > 0) {
                $inputGroupParent.find(".input-group-addon").on("click", (e) => {
                    if ($element.is(":disabled") !== true) {
                        $element.trigger("click");
                    }
                });
            }
        });
    }

    private getCalendarModules(selector: string) {
        const modules: any[] = [];

        $(selector).each(function() {
            const element = $(this);

            const instance = $(element).mobiscroll("getInst");
            if (instance === undefined) {
                return;
            }

            modules.push(instance);
        });

        return modules;
    }
}