// (C) Copyright 2020 Hewlett-Packard Enterprise Company, L.P.

define(['fs/presenter/activity/ActivityAlertPresenter',
    'fs/view/activity/AlertAssignView',
    'fs/view/activity/AlertClearView',
    'fs/view/activity/AlertRestoreView',
    'hp/view/NotificationDetailsView',
    'hp/core/LinkTargetBuilder',
    'hp/core/StatusState',
    'hp/core/Localizer',
    'hp/model/Session',
    'text!fsPages/activity/alert_details.html',
    'jquery',
    'hp/lib/jquery.hpSelect',
    'hp/lib/jquery.hpCollapsible',
    'hp/lib/jquery.hpTimestamp',
    'hp/lib/jquery.hpSearchCombo'],
function(presenter, alertAssignView, alertClearView, alertRestoreView,
    notificationDetailsView, linkTargetBuilder, statusState,
    localizer, session, alertDetailsHtml) { "use strict";

    var ActivityAlertView = (function() {

        var ACTIVITIES = '.hp-activities';
        var STATE = '.hp-state.hp-select';
        var OWNER = '.hp-owner.hp-select';
        var DETAILS = '.hp-alert-details';
        var SPINNER = '.hp-spinner';
        var ACTIONS = '#hp-activity-actions';
        var ASSIGN_ACTION = '#hp-activity-assign';
        var CLEAR_ACTION = '#hp-activity-clear';
        var RESTORE_ACTION = '#hp-activity-restore';
        var CLEAR = 'tr.hp-alert > td > .hp-delete';
        var NOTIFICATION_CONTAINER = '.hp-alert-notification-container';
        var NOTES = '.hp-alert-notes';
        var NOTE = '.hp-alert-note';
        var NOTE_TEMPLATE = '#hp-alert-note-template';
        var WRITE_NOTE = '.hp-alert-note-write';
        var DELETE_NOTE = 'li.hp-alert-note .hp-delete';
        var EVENT = '.hp-alert-events';
        var EVENT_PROPERTY_TEMPLATE = '#hp-alert-event-property-template';
        var EVENT_PROPERTIES = '.hp-alert-event-properties';
        var ENTER = 13;
        var SELECT_IGNORE = '.hp-select-ignore';

        /**
         * Constructor
         */
        function ActivityAlertView() {

            var detailsTemplate;
            var noteTemplate;
            var eventPropertyTemplate;
            var changeStateTemplate;
            var assignTemplate;
            var renderDetailsCompletionHandler;

            function populateDetails(elem, alert) {
                $(elem).children().show();
                $(SPINNER, elem).hide();
                var height = $(elem).height();
                $(elem).css('min-height', height);

                notificationDetailsView.update($(NOTIFICATION_CONTAINER, elem),
                    alert._notification);

                $(NOTES, elem).empty();
                if (alert.changeLog) {
                    $.each(alert.changeLog, function (index, note) {
                        var elem2 = noteTemplate.clone();
                        elem2.attr('data-uri', note.uri);
                        $('.hp-owner', elem2).text(note.username);
                        $('.hp-message', elem2).text(note.notes);
                        $('.hp-timestamp', elem2).text(note.created).hpTimestamp();
                        if (note['_currentUser']) {
                            $('.hp-delete', elem2).show();
                        }
                        $(NOTES, elem).append(elem2);
                    });
                }

                $('.hp-alert-health-category', elem).text(alert.healthCategory);
                $('.hp-alert-health-category', elem).text(alert.healthCategory);

                if (session.canPerformAction('alerts', 'Update')) {
                    $(WRITE_NOTE).show();
                } else {
                    $(WRITE_NOTE).hide();
                }

                if (alert.associatedEventUris) {
                    $(EVENT, elem).attr('data-uri', alert.associatedEventUris[0]);
                }

                $(elem).css('min-height', '');
                $(elem).trigger('relayout');
            }

            function populateEventDetails(elem, event) {
                $(EVENT_PROPERTIES, elem).empty();
                $.each(event.eventDetails, function (index, prop) {
                    var elem2 = eventPropertyTemplate.clone();
                    $('.hp-name', elem2).text(prop.eventItemName);
                    $('.hp-value', elem2).text(prop.eventItemValue);
                    $(EVENT_PROPERTIES, elem).append(elem2);
                });
                $(elem).trigger('relayout');

            }

            function resetActionMenu() {
                if (session.canPerformAction('alerts', 'Update')) {
                    $(ACTIONS).show();
                } else {
                    $(ACTIONS).hide();
                }
            }

            // Cell renderers

            function renderStatus(data) {
                var status = 'unknown';
                if (data.attributes.hasOwnProperty('status')) {
                    status = data.attributes.status;
                } else if (data.attributes.hasOwnProperty('severity')) {
                    // TODO: older alert, remove when health fixes index mapping
                    status = data.attributes.severity;
                }
                return '<div class="hp-status">' +
                    localizer.getString(statusState.getHealthStatus(status)) + '</div>';
            }

            function renderName(data) {
                var result;
                if (data.name) {
                    result = data.name;
                } else {
                    result = data.description;
                }
                return result;
            }

            function renderSource(data) {
                var attributes = data.attributes;
                if (attributes.hasOwnProperty('associatedResourceUri')) {
                    return linkTargetBuilder.makeLink(
                        (attributes.associatedResourceName || '?'),
                        attributes.associatedResourceUri);
                } else if (attributes.hasOwnProperty('resourceUri')) {
                    // TODO: older alert, remove when health fixes index mapping
                    return linkTargetBuilder.makeLink(
                        (attributes.resourceName || '?'),
                        attributes.resourceUri);
                } else {
                    return '<div class="hp-unset">not set</div>';
                }
            }

            function renderOwner(data) {
                var result;
                var owner = data._notification.owner;
                if (! owner) {
                    owner = localizer.getString('fs.activity.unassigned');
                }
                if (session.canPerformAction('alerts', 'Update')) {
                    var elem = assignTemplate.clone();
                    $('.hp-value, .hp-selected', elem).text(owner).attr('data-id', owner);
                    result = elem[0].innerHTML;
                } else {
                    result = owner;
                }
                return result;
            }

            function renderState(data) {
                var result;
                var state = data._notification.state;
                if (state) {
                    var str = localizer.getString("fs.activity.filter.state." + state.toLowerCase());
                    if (state !== 'Locked' && session.canPerformAction('alerts', 'Update')) {
                        var elem = changeStateTemplate.clone();
                        $('.hp-value', elem).text(str).attr('data-id', state);
                        $('[data-id="' + state + '"]', elem).addClass('hp-selected');
                        result = elem[0].innerHTML;
                    } else {
                        result = str;
                    }
                } else {
                    result = '<div class="hp-unset">not set</div>';
                }
                return result;
            }

            function annotateRow(row, data) {
                // no-op
            }

            // Presenter events

            function onAlertChange(alert) {
                var elem = $(DETAILS + '[data-uri="' + alert.uri + '"]');
                populateDetails(elem, alert);
                //let the table know that details were updated in case it needs to adjust the scroll position
                if (renderDetailsCompletionHandler) {
                    renderDetailsCompletionHandler(alert.uri);
                }
            }

            function onEventChange(event) {
                var elem = $(EVENT + '[data-uri="' + event.uri + '"]');
                // we get there if the presenter determined that the event state
                // should be  "expanded", so make it so
                $(elem).removeClass('hp-collapsed');
                populateEventDetails(elem, event);

            }

            // DOM events

            function onExpandEventDetails() {
                var elem = $(this);
                var uri = $(elem).attr('data-uri');
                presenter.expandEvent(uri);
            }

            function onCollapseEventDetails() {
                var elem = $(this);
                var uri = $(elem).attr('data-uri');
                presenter.collapseEvent(uri);
            }

            function onWriteNoteKeyDown(ev) {
                var elem, message, uri;
                var keyCode = (ev.which ? ev.which : ev.keyCode);
                if (keyCode === ENTER) {
                    elem = $(this).parents(DETAILS);
                    uri = $(elem).attr('data-uri');
                    message = $.trim($(WRITE_NOTE, elem).val());
                    if (message.length > 0) {
                        presenter.createNote(uri, message);
                        $(WRITE_NOTE, elem).val('').blur();
                        ev.preventDefault();
                    }
                }
            }

            function onStateClick(event) {
                var elem = $(this);
                // make it hpSelect if needed
                if (elem.attr('tabindex') !== '0') {
                    elem.hpSelect({activate: true});
                }
            }

            function onChangeState(event, value) {
                var uri = $(this).parents('.hp-alert').attr('data-uri');
                presenter.changeState(uri, value);
            }

            function onOwnerClick(event) {
                var elem = $(this);
                // make it hpSelect if needed
                if (elem.attr('tabindex') !== '0') {
                    presenter.getPotentialOwners('', {
                        success: function (names) {
                            elem.hpSelect({options: names, activate: true});
                        },
                        error: function () {
                            if (handlers && handlers.error) {
                                handlers.error();
                            }
                        }
                    }, true, true); //first true to get unassigned, second true to get the ignore element
                }
            }

            function onAssign(event, value) {
                var uri = $(this).parents('.hp-alert').attr('data-uri');
                presenter.assignUserToAlertByUri(uri, value);
            }

            function onClearAlert(event) {
                if (event && $(this).parents('tr.hp-alert').hasClass('hp-selected')) {
                    event.stopPropagation(); // Do not touch selection if already selected
                }
                var uri = $(this).parents('tr.hp-alert').attr('data-uri');
                presenter.clear(uri);
            }

            function onDeleteNote(event) {
                var noteUri = $(this).parents(NOTE).attr('data-uri');
                var alertUri = $(this).parents(DETAILS).attr('data-uri');
                presenter.deleteNote(alertUri, noteUri);
            }

            function onAssignAction(event) {
                alertAssignView.show();
                return false;
            }

            function onAssignActionRow(event) {
                var uri = $(this).parents('tr.hp-alert').attr('data-uri');
                alertAssignView.show([uri]);
                return false;
            }

            function onClearAction() {
                alertClearView.clearSelected();
            }

            function onRestoreAction() {
                alertRestoreView.restoreSelected();
            }

            function registerListeners() {
                if (session.canPerformAction('alerts', 'Update')) {
                    $(ASSIGN_ACTION).on('click', onAssignAction);
                    $(ACTIVITIES).on('click', SELECT_IGNORE, onAssignActionRow);
                    $(CLEAR_ACTION).on('click', onClearAction);
                    $(RESTORE_ACTION).on('click', onRestoreAction);
                }
                $(ACTIVITIES).on('click', CLEAR, onClearAlert);
                $(ACTIVITIES).on('click', DELETE_NOTE, onDeleteNote);
                $(ACTIVITIES).on('click', STATE, onStateClick);
                $(ACTIVITIES).on('change', STATE, onChangeState);
                $(ACTIVITIES).on('click', OWNER, onOwnerClick);
                $(ACTIVITIES).on('change', OWNER, onAssign);
                $(ACTIVITIES).on('expand', EVENT, onExpandEventDetails);
                $(ACTIVITIES).on('collapse', EVENT, onCollapseEventDetails);
                $(ACTIVITIES).on('keydown', WRITE_NOTE, onWriteNoteKeyDown);
                presenter.on('alertChange', onAlertChange);
                presenter.on('eventChange', onEventChange);
            }

            function unregisterListeners() {
                if (session.canPerformAction('alerts', 'Update')) {
                    $(ASSIGN_ACTION).off('click', onAssignAction);
                    $(ACTIVITIES).off('click', SELECT_IGNORE, onAssignActionRow);
                    $(CLEAR_ACTION).off('click', onClearAction);
                    $(RESTORE_ACTION).off('click', onRestoreAction);
                }
                $(ACTIVITIES).off('click', CLEAR, onClearAlert);
                $(ACTIVITIES).off('click', DELETE_NOTE, onDeleteNote);
                $(ACTIVITIES).off('click', STATE, onStateClick);
                $(ACTIVITIES).off('change', STATE, onChangeState);
                $(ACTIVITIES).off('click', OWNER, onOwnerClick);
                $(ACTIVITIES).off('change', OWNER, onAssign);
                $(ACTIVITIES).off('expand', EVENT, onExpandEventDetails);
                $(ACTIVITIES).off('collapse', EVENT, onCollapseEventDetails);
                $(ACTIVITIES).off('keydown', WRITE_NOTE, onWriteNoteKeyDown);
                $(ACTIVITIES).off('collapse', EVENT, onCollapseEventDetails);
                presenter.off('alertChange', onAlertChange);
                presenter.off('eventChange', onEventChange);
            }

            /**
             * @public
             */
            this.renderDetails = function (indexResult, oldDetails, handler) {
                var elem;
                var uri = indexResult.uri;

                // re-use old if we have it
                if (! oldDetails) {
                    elem = detailsTemplate.clone().attr('data-uri', uri);
                    $(EVENT, elem).hpCollapsible();
                    $(elem).children().hide();
                    $(SPINNER, elem).show();
                }

                presenter.expandAlert(uri);
                renderDetailsCompletionHandler = handler;

                // elem is intentionally undefined if we don't create it here
                return elem;
            };

            this.collapsed = function (indexResult) {
                presenter.collapseAlert(indexResult.uri);
            };

            // for ActivityView to build owner cell
            this.renderOwner = renderOwner;

            // for ActivityView to build state cell
            this.renderState = renderState;

            this.annotateRow = annotateRow;

            this.pause = function () {
                unregisterListeners();
                presenter.pause();
            };

            this.resume = function () {
                registerListeners();
                resetActionMenu();
                presenter.resume();
            };

            this.init = function () {
                if (! detailsTemplate) {
                    detailsTemplate = $(alertDetailsHtml);
                    localizer.localizeDom(detailsTemplate);
                    $(WRITE_NOTE, detailsTemplate).attr('placeholder',
                        localizer.getString('fs.alerts.eventData.writeNote'));
                    noteTemplate = $(NOTE_TEMPLATE, detailsTemplate).remove().
                        removeAttr('id').removeClass('hp-template');
                    $('.hp-delete', noteTemplate).hide();
                    eventPropertyTemplate = $(EVENT_PROPERTY_TEMPLATE, detailsTemplate).remove().
                        removeAttr('id').removeClass('hp-template');
                    changeStateTemplate =
                        detailsTemplate.filter('#hp-activity-alert-change-state-template').
                        removeAttr('id').removeClass('hp-template');
                    assignTemplate =
                        detailsTemplate.filter('#hp-activity-alert-assign-template').
                        removeAttr('id').removeClass('hp-template');
                    detailsTemplate = detailsTemplate.filter('.hp-alert-details');
                }

                resetActionMenu();
                registerListeners();
            };
        }

        return new ActivityAlertView();
    }());

    return ActivityAlertView;
});
