/// class PD.Manage.Modules.Maintenance.MaintenanceStatus
// using PD.Web.UI.Controls.Control

PD.Manage.Modules.Maintenance.MaintenanceStatus =
PD.Web.UI.Controls.Control.extend({

    //===================================
    // FIELDS
    //===================================

    _timer: null,
    _modes: {
        0: {
            id: 0,
            label: "System Is Operational",
            timerLabel: "No maintenance pending.",
            cssClass: "no-maintenance"
        },
        1: {
            id: 1,
            label: "Maintenance Will Start In",
            timerLabel: null,
            cssClass: "scheduled"
        },
        2: {
            id: 2,
            label: "System Under Maintenance",
            timerLabel: null,
            cssClass: "in-maintenance"
        }
    },
    _mode: null,
    _startAt: null,
    _warningMins: null,
    _maintenanceModeService: null,
    
    //===================================
    // PROPERTIES
    //===================================

    get_scheduleButton: function () {
        return this.get_node().find("BUTTON[data-id=schedule]");
    },

    get_triggerButton: function () {
        return this.get_node().find("BUTTON[data-id=trigger]");
    },

    get_statusTextLabel: function () {
        return this.get_node().find("[data-id=status-text-label]");
    },

    get_statusTextTimer: function () {
        return this.get_node().find("[data-id=status-text-timer]");
    },

    startAt: function (value) {
        if (value !== undefined) {
            this._startAt = this.ensureValueIsDate(value);
        }
        return this._startAt;
    },

    warningMins: function (value) {
        if (value !== undefined) {
            this._warningMins = parseInt(value);
        }
        return this._warningMins;
    },

    //===================================
    // EVENT HANDLERS
    //===================================

    onActivate: function () {

        var options = this.get_options(),
            settings = options.settings || {};
        
        this._maintenanceModeService = new PD.Manage.Services.MaintenanceModeService();

        this.updateMaintenanceMode(settings.startAt);
    
        this.get_scheduleButton().on("click", _.bind(this._scheduleButton_onClick, this));
        this.get_triggerButton().on("click", _.bind(this._triggerButton_onClick, this));

    },

    _scheduleButton_onClick: function (e) {
        this.showScheduleMaintenanceDialog();
    },

    _triggerButton_onClick: function (e) {
    
        var $button = $(e.currentTarget),
            state = $button.data("state");

        switch (state) {
            case "start":
                this.showStartMaintenanceDialog();
                break;
            case "stop":
                this.showStopMaintenanceDialog();
                break;
            case "cancel":
                this.showCancelMaintenceDialog();
                break;
        }

    },

    //===================================
    // PROTECTED METHODS
    //===================================

    template: function () {
        return [
            "<div class='maintenance-status'>",
                "<div data-id='status'>",
                    "<div data-id='status-icon'></div>",
                    "<div data-id='status-text'>",
                        "<div data-id='status-text-label'>Maintenance Will Start In</div>",
                        "<div data-id='status-text-timer'></div>",
                    "</div>",
                "</div>",
                "<div data-id='button-deck'>",
                    "<button data-id='trigger' data-state='start'>Start</button>",
                    "<button data-id='schedule' data-state='schedule'>Reschedule</button>",
                "</div>",
            "</div>"
        ];
    },

    //===================================
    // PRIVATE METHODS
    //===================================

    startCountdown: function (startDate) {

        var that = this;

        this.stopCountdown();

        if (startDate == null) {
            return;
        }

        countdown.setLabels(
            "| sec| min| hrs| day| week| month| year|||",
            "| sec| min| hrs| days| weeks| months| years|||");

        this._timer = countdown(
            startDate,
            function (ts) {
                that.updateMaintenanceMode(ts.start, ts);
            },
            countdown.DAYS |
            countdown.HOURS |
            countdown.MINUTES |
            countdown.SECONDS);

    },

    stopCountdown: function () {
        if (this._timer != null) {
            window.clearInterval(this._timer);
        }
    },

    getMode: function (startDate) {

        var now = new Date(),
            modeId = 0;

        if (_.isDate(now)) {
            now.setSeconds(now.getSeconds() + 1);
        }
        
        switch (true) {
            case startDate == null || startDate === "":
                modeId = 0;
                break;
            case startDate > now:
                modeId = 1;
                break;
            case startDate <= now:
                modeId = 2;
                break;
        }

        return this._modes[modeId];

    },

    setModeCountdown: function (mode, startDate) {

        this.stopCountdown();

        if (mode > 0) {
            this.startCountdown(startDate);
        }

    },

    setModeUi: function (mode, startDate) {

        for (var name in this._modes) {
            this.get_node().removeClass(this._modes[name].cssClass);
        }

        if (mode != null) {
            this.get_node().addClass(this._modes[mode].cssClass);
        }

        this.get_statusTextLabel().empty();
        this.get_statusTextTimer().empty();

        switch (mode) {
            case 0:
                this.get_triggerButton().data("state", "start");
                this.get_triggerButton().text("Start Now");
                this.get_scheduleButton().text("Schedule");
                this.get_scheduleButton().show();
                break;
            case 1:
                this.get_triggerButton().data("state", "cancel");
                this.get_triggerButton().text("Cancel");
                this.get_scheduleButton().text("Reschedule");
                this.get_scheduleButton().show();
                break;
            case 2:
                this.get_triggerButton().data("state", "stop");
                this.get_triggerButton().text("Stop");
                this.get_scheduleButton().hide();
                break;
        }

    },
    
    setStatusLabels: function (timeSpan) {

        var statusLabel = this._mode.label,
            statusTimerLabel = this._mode.timerLabel,
            $statusTextLabel = this.get_statusTextLabel(),
            $statusTextTimer = this.get_statusTextTimer();

        $statusTextLabel.empty();
        if (statusLabel) {
            $statusTextLabel.html(statusLabel);
        }

        $statusTextTimer.empty();

        switch (true) {
            case statusTimerLabel == null && timeSpan != null:
                var startDate = new Date(timeSpan.start);
                $statusTextTimer.html(timeSpan.toHTML("strong") + "<br/>&nbsp;on&nbsp;<i>" + this.formatStartDate(startDate) + "</i>");
                break;
            case statusTimerLabel != null:
                $statusTextTimer.html(statusTimerLabel);
                break;
            default:
                this.get_statusTextTimer().html("<i>Calculating...</i>");
                break;
        }

    },

    ensureValueIsDate: function (value) {
        
        var result = null;

        switch (true) {
            case _.isString(value):
                result = new Date(value);
                break;
            case _.isDate(value):
                result = value;
                break;
        }

        return result;

    },

    formatStartDate: function (date) {
        return kendo.toString(date, "MMMM dd, yyyy @ h:mm tt");
    },
    
    updateMaintenanceMode: function (startAt, timeSpan) {

        var startDate = this.ensureValueIsDate(startAt);
        var mode = this._mode = this.getMode(startDate);

        this.startAt(startDate);

        if (timeSpan == null) {
            this.setModeCountdown(mode.id, startDate);
        }
        this.setModeUi(mode.id, startDate);
        this.setStatusLabels(timeSpan);

    },

    /******** Dialogs *********/

    showStartMaintenanceDialog: function () {

        Jade.UI.MessageDialog.open({
            dialogStyle: Jade.UI.MessageDialogStyle.Information,
            dialogButtons: Jade.UI.MessageDialogButtonStyle.OKCancel,
            title: "Start Maintenance Mode",
            message: "Start maintenance mode?<br/><br/>All users not in the \"Allowed Users\" list will be immediately locked out of the system.",
            select: (e) => {
                e.close();
                if (e.button === Jade.UI.MessageDialogButton.ok) {
                    this._maintenanceModeService.startMaintenance((e) => {
                        this.updateMaintenanceMode(e.startAt);
                    });
                }
            }
        });

    },

    showStopMaintenanceDialog: function () {

        Jade.UI.MessageDialog.open({
            dialogStyle: Jade.UI.MessageDialogStyle.Information,
            dialogButtons: Jade.UI.MessageDialogButtonStyle.OKCancel,
            title: "Stop Maintenance Mode",
            message: "Stop maintenance mode?<br/><br/>All users that are currently locked out of the system will immediately be granted access to the system.",
            select: (e) => {
                e.close();
                if (e.button === Jade.UI.MessageDialogButton.ok) {
                    this._maintenanceModeService.stopMaintenance((e) => {
                        this.updateMaintenanceMode(null);
                    });
                }
            }
        });

    },

    showCancelMaintenceDialog: function () {

        Jade.UI.MessageDialog.open({
            dialogStyle: Jade.UI.MessageDialogStyle.Information,
            dialogButtons: Jade.UI.MessageDialogButtonStyle.OKCancel,
            title: "Cancel Scheduled Maintenance",
            message: "Cancel the currently scheduled maintenance?<br/><br/>The scheduled maintence will be removed and the system will no longer automatically enter maintenance at the currently prescribed date and time.",
            select: (e) => {
                e.close();
                if (e.button === Jade.UI.MessageDialogButton.ok) {
                    this._maintenanceModeService.stopMaintenance((e) => {
                        this.warningMins(0);
                        this.updateMaintenanceMode(null);
                    });
                }
            }
        });

    },

    showScheduleMaintenanceDialog: function () {

        PD.Manage.Modules.Maintenance.ScheduleMaintenanceDialog.open({
            startAt: this.startAt(),
            warningMins: this.warningMins(),
            callbacks: {
                ok: (sender, e) => {
                    this.warningMins(e.warningMins);
                    this.updateMaintenanceMode(e.startAt);
                }
            }
        });

    }

});