import {DateRangePicker} from "./Daterangepicker";
import 'jquery-ui/ui/widgets/sortable';


export default class Utilities {


    static date_range_pickers(selector) {
        $('input[data-toggle="daterangepicker"]', selector).each((key, item) => {
            DateRangePicker.range_picker(item);
        })
    }

    static date_pickers(selector) {
        $('input[data-toggle="datepicker"]', selector).each((key, item) => {
            DateRangePicker.single_picker(item, $(item).is('[data-time]'));
        })
    }


    static isObject(object) {
        return typeof object === 'object' && object !== null;
    }

    static initSortable (selector) {

        $('[sortable]', selector).each(function () {
            let options = {
                cursor: 'move',
            }

            if($(this).is('[data-sortable-handle]'))
                options.handle = "."+$(this).data('sortable-handle');

            $(this).sortable(options)
        });
    }

    static tryParseJSON (jsonString){
        try {
            var o = JSON.parse(jsonString);

            // Handle non-exception-throwing cases:
            // Neither JSON.parse(false) or JSON.parse(1234) throw errors, hence the type-checking,
            // but... JSON.parse(null) returns null, and typeof null === "object",
            // so we must check for that, too. Thankfully, null is falsey, so this suffices:
            if (o && typeof o === "object") {
                return o;
            }
        }
        catch (e) { }

        return false;
    };

    static delay(fn, ms = 0) {
        let timer = 0
        return function(...args) {
            clearTimeout(timer)
            timer = setTimeout(fn.bind(this, ...args), ms)
        }
    }

    static selectAll(selector) {
        Utilities.toggleSelectAll(selector)

        $(selector).find(':input[data-select-all]').on('change keyup', function () {
            Utilities.toggleSelectAll(selector);
        })
        $(selector).find(':input[type="checkbox"]').on('change keyup', function () {
            $('[data-select-all="'+$(this).attr('name')+'"]' ,selector).prop('checked', false);
        })
    }

    static toggleSelectAll(selector) {
        $('[data-select-all]', selector).each( function () {
            let $toggle = $(this),
                parsed = $toggle.attr('data-select-all').split(',')


            if($toggle.is(':checked')){
                for (let [key, data] of Object.entries(parsed)) {
                    $(':input[name="'+data+'"]', selector).prop('checked', true);
                }
            }

        });
    }

    static loadingOverlay (loaderContainerElement, animate = true) {
        let $element = $(loaderContainerElement);
        if($element.length === 0 || $('#overlay', $element).length)
            return;

        $('<div id="overlay"><div class="loader"></div></div>').appendTo($element);

        if(animate){
            $('html, body').animate({
                scrollTop: $element.offset().top - 35
            }, 800);
        }
    }

    static removeLoadingOverlay (loaderContainerElement) {
        $('#overlay', $(loaderContainerElement)).remove()
    }


    /**
     * Shows an alert on the page to the user with the specified message.
     *
     * @param message
     * @param level
     */
    static alert(message, level) {
        let $el = $('<div class="alert alert-success" role="alert" style="display: none">').html(message);

        $('.alerts-container').prepend($el);
        $el.slideDown();

        setTimeout(() => {
            $el.slideUp(400, function () {
                $(this).remove();
            });
        }, 5000);
    }

    static passwordView(selector) {
        $('input[password-viewer]', selector).each((key, element) => {

            /** Create password viewer object */
            let passwordViewer =  $.parseHTML(
                '<div class="input-group mb-3">' +
                    element.outerHTML +
                '  <div class="input-group-append">' +
                '    <button class="btn btn-outline-secondary" type="button"><i class="far fa-eye"></i></button>' +
                '  </div>' +
                '</div>'
            )

            /** add on click event for the password viewer button */
            $(passwordViewer).find('button').on('click', function () {
                if($('input[type="password"]', $(passwordViewer)).length)
                    $('input[type="password"]', $(passwordViewer)).prop('type', 'text');
                else
                    $('input[type="text"]', $(passwordViewer)).prop('type', 'password');
            })

            /** replace password input with password viewer object */
            $(element).replaceWith($(passwordViewer));
        });
    }

    static confirmDialog(message, type, confirmCallback, cancelCallback) {

        let dialogOptions = {
            resizable: false,
            height: "auto",
            width: 400,
            modal: true,
            draggable: false,
        }

        switch (type) {
            case 'delete' :
                dialogOptions.buttons = {
                    Delete: function() {
                        if(typeof confirmCallback === 'function')
                            confirmCallback();
                        $( this ).dialog( "close" );
                    },
                    Cancel: function() {
                        if(typeof cancelCallback === 'function')
                            cancelCallback()
                        $( this ).dialog( "close" );
                    }
                }
                break;
            case 'save' :
                dialogOptions.buttons = {
                    'Close and Save': function() {
                        if(typeof confirmCallback === 'function')
                            confirmCallback();
                        $( this ).dialog( "close" );
                    },
                    "Close and Don't Save": function() {
                        if(typeof cancelCallback === 'function')
                            cancelCallback();
                        $( this ).dialog( "close" );
                    },
                    "Continue Editing": function() {
                        $( this ).dialog( "close" );
                    }
                }
                break;
            case 'confirmation' :
            default:
                dialogOptions.buttons = {
                    Cancel: function () {
                        if(typeof cancelCallback === 'function')
                            cancelCallback();
                        $(this).dialog("close");
                    },
                    Confirm: function () {
                        if(typeof confirmCallback === 'function')
                            confirmCallback();
                        $(this).dialog("close");
                    }
                }
                break;
        }

        $('<div></div>').appendTo('body').html('<div>'+message+'</div>').dialog(dialogOptions);

    }

    static copyToClipboard(element) {
        let $temp = $("<input>");
        $("body").append($temp);
        $temp.val($(element).text()).select();
        document.execCommand("copy");
        $temp.remove();
    }

    static anchors(selector){
        if(window.location.hash !== '')
            $(window.location.hash, selector).tab('show').blur();
    }

    static tagAndHtmlStrip(string){
        return $("<div>"+string+"</div>").text()
            .replace(/<\/?[^>]+(>|$)/g, "")
            .replace(new RegExp('&amp;nbsp;', 'g'), ' ')
            .replace(new RegExp('&nbsp;', 'g'), ' ');
    }

    static disableWhen (selector) {
        Utilities.toggleDisableWhen(selector);

        $(selector).find(':input').on('change keyup', function () {
            Utilities.toggleDisableWhen(selector);
        });
    }
    static toggleDisableWhen(selector) {
        $(selector).find('[data-disable-when]').each(function () {
            let $disable = $(this),
                parsed = $disable.attr('data-disable-when').split(','),
                element = $(':input[name="' + parsed[0] + '"]'),
                disable = false;

            element.each(function () {
                let $input = $(this);

                if ((['checkbox', 'radio'].includes($input.attr('type')) && $input.is(':checked') && ($input.val() === parsed[1] || parsed[1] == 'checked')) ||
                    (['checkbox', 'radio'].includes($input.attr('type')) && $input.is(':not(:checked)') &&  parsed[1] == 'unchecked') ||
                    (!['checkbox', 'radio'].includes($input.attr('type')) && $input.val() === parsed[1])
                ) {
                    disable = true;
                }
            });

            if(disable){
                $disable.prop("disabled", true);
                if($disable.is('select'))
                    $disable[0].selectize.disable();

            } else {

                $disable.prop("disabled", false);
                if($disable.is('select'))
                    $disable[0].selectize.enable();
            }
        });

    }

    static notificationRead(selector){
        $(selector).find('[data-notification_read_target]').click(function(event) {
            event.preventDefault();
            let ele = $(this);

            $.ajax({
                url: $(this).attr('href'),
                type: 'GET',
                success: function (data) {
                    $('#'+$(ele).data('notification_read_target')).remove()
                    if($('#notification-count').html(parseInt($('#notification-count').html())-1).text() === '0')
                        $('<div class="card-body"><div class="card-text">No notifications found</div></div>').insertBefore($('#viewAllNotifications'));
                }
            })
        });
    }

    static displayWhens (selector) {
        Utilities.toggleDisplays(selector);

        $(selector).find(':input').on('change keyup', function () {
            Utilities.toggleDisplays(selector);
        })
    }

    static toggleDisplays(selector) {
        $(selector).find('[data-display-when]').each(function () {
            let $display = $(this),
                parsed = $display.attr('data-display-when').split(','),
                element = $(':input[name="' + parsed[0] + '"]').length ? $(':input[name="' + parsed[0] + '"]') : $(':input[data-name="' + parsed[0] + '"]'),
                show = false;

            element.each(function () {
                let $input = $(this);

                if((['checkbox', 'radio'].includes($input.attr('type')) && $input.is(':checked') && ($input.val() === parsed[1] || parsed[1] == 'checked')) ||
                    (!['checkbox', 'radio'].includes($input.attr('type')) && $input.val() === parsed[1])
                ) {
                    show = true;
                }
            });

            if(show === true) {
                $display.show('400');
            } else {
                $display.hide('400');
            }
        });
    }

    static variableAmendments (selector) {
        if(!$('#variableAmendment', selector).length)
            return false;

        let variableAmendmentApi = $('#variableAmendment')[0].selectize, $amendmentBtn = $('#productAmendmentBtn', selector),
            url = $amendmentBtn.attr('href')


        variableAmendmentApi.on('change', function (value) {
            if(value)
                $amendmentBtn.attr('href', url.replace('999', value)).removeClass('disabled')
            else
                $amendmentBtn.attr('href', url).addClass('disabled')
        });
    }

}
