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

define(['hpsum/presenter/enclosure/EnclosurePresenter',
    'hp/core/Router',
    'hp/core/UrlFragment',
    'hp/view/FormStateView',
    'hp/view/AssociationAddView',
    'hp/core/Localizer',
    'jquery',
    'hp/lib/jquery.hpStackedPanels',
    'lib/jquery.selectBox',
    'lib/jquery.dataTables',
    'lib/jquery.dataTables.rowReordering',
    'hp/lib/jquery.hpCollapsible',
    'hp/lib/jquery.hpSearchCombo',
    'hp/lib/jquery.hpToggle'],
function(presenter, router, urlFragment, FormStateView,
    AssociationAddView, localizer) { "use strict";

    var EnclosureEditView = (function() {
      
        var OK = '#tour-enclosure-edit-ok';
        var APPLY = '#tour-enclosure-edit-apply';
        var CANCEL = '#tour-enclosure-edit-cancel';
        var PANEL_SELECTOR = '#tour-enclosure-edit-panel-selector';
        var PANELS = '#tour-enclosure-edit-panels';
        var TITLE = '#tour-enclosure-details-title';
        var NOTIFY = '#tour-enclosure-edit-notify';
        var FORM = '#tour-enclosure-edit-form';
        var NAME = '#tour-enclosure-name';
        var SELECT = '.hp-select';
        var SEARCHER = '#tour-enclosure-searcher';
        var COLLAPSE = '#tour-enclosure-collapse';
        var TOGGLE = '#tour-enclosure-toggle';
        var RELATIONS = '#tour-enclosure-relations';
        var RELATIONS_SEARCH = '#tour-enclosure-relations-search';
        var ADD_RELATION = '#tour-enclosure-relations-add';
        var ROUTE_PREFIX = '/enclosure/edit';
        var NOTIFY_STATUSES = {error:'error', warning:'warning', unknown:'info'};
        
        /**
         * Constructor
         */
        function EnclosureEditView() {
          
            var formStateView = new FormStateView();
            var updateInProgress = false;
            var relationsTable = null;
            var possibleRelations = [];
            var relations = [];
            var editRow = null;
            
            function getRelations(search) {
                var regexp = new RegExp(search, 'i');
                var results =
                    $.grep(possibleRelations, function(result, index) {
                        // exclude existing
                        if ($.grep(relations, function(result2, index2) {
                            return (result2.id === result.id);
                        }).length > 0) {
                            return false;
                        }
                        // check search
                        if (search && search.length > 0) {
                            return (result.name.match(regexp) ||
                                    result.model.match(regexp));
                        }
                        return true;
                    });
                return ({count: results.length, members: results});
            }
            
            function stopEditing() {
                var relation = relationsTable.fnGetData(editRow);
                relation.speed = $('.tour-speed input', editRow).val();
              	relationsTable.fnUpdate( relation.speed, editRow, 2, false );
              	$('.tour-speed', editRow).removeClass('hp-editing');
              	relationsTable.fnDraw();
              	editRow = null;
            }
            
            function onEditRelation(event) {
                var row = $(this).parents('tr')[0];
                var relation = relationsTable.fnGetData(row);
                var speed = $('.tour-speed', row).text();
                if (editRow != row) {
                    if (editRow !== null) {
                        stopEditing(editRow);
                    }
                    $('.tour-speed', row).
                        html('<input value="' + speed + '" size="4">').
                        addClass('hp-editing');
                    editRow = row;
                    relationsTable.fnDraw();
                    $('input', editRow).focus();
                } else if (editRow) {
                    stopEditing(editRow);
                }
                event.stopPropagation();
            }
            
            function onDeleteRelation(event) {
                var row = $(this).parents('tr')[0];
                var relation = relationsTable.fnGetData(row);
                relations = $.grep(relations, function (relation2) {
                    return relation2.id !== relation.id;
                });
                relationsTable.fnDeleteRow(row);
                $('#tour-enclosure-relations-message').
                    text('Removed ' + relation.name);
                event.stopPropagation();
            }
            
            function onAddRelation() {
                var numAdded = 0;
                new AssociationAddView({
                    title: "Add relations",
                    dataTableOptions:  {
                        aoColumns : [
                          {sTitle: 'Name', mDataProp: 'name', sWidth: 100},
                          {sTitle: 'Model', mDataProp: 'model', sWidth: 200}
                        ]
                    },
                    getResults: function (query, handlers) {
                        // simulate error if string is "error"
                        setTimeout(function () {
                            if ('error' === query) {
                                handlers.error('failed to get results');
                            } else {
                                // It is assumed this would be performed on the server side
                                handlers.success(getRelations(query));
                            }
                        }, 200);
                    },
                    apply: function (results) {
                        numAdded += results.length;
                        relations = relations.concat(results);
                        relationsTable.fnAddData(results);
                        relationsTable.fnAdjustColumnSizing();
                        $(RELATIONS + ' .hp-close').click(onDeleteRelation);
                        $('#tour-enclosure-relations-message').
                            text(numAdded + ' added ');
                    }
                });
            }
                
            function onItemChange(item) {
                if (item) {
                    $(TITLE).html(item.name);
                    $(NAME).val(item.name);
                } else {
                    $(TITLE).html('');
                }
                formStateView.reset();
            }
            
            function onItemError(errorMessage) {
                formStateView.noItem(errorMessage);
            }
            
            function onSelectionChange(selection) {
                urlFragment.replaceHrefUris(PANEL_SELECTOR, selection.uris);
                urlFragment.replaceHrefUris(CANCEL, selection.uris);
                $(PANELS).hpStackedPanels('setPanelByLocation', '#' + router.location());
            }
            
            function onItemUpdateSuccess(task) {
                updateInProgress = false;
                formStateView.reset();
                $(CANCEL).trigger('click');
            }

            /**
             * @private
             */
            function onItemUpdateError(errorMessage) {
                updateInProgress = false;
            }
            
            function onUpdateItem() {
                if (! updateInProgress) {
                    updateInProgress = true;
                    formStateView.setMessage({summary: 'Verifying parameters',
                        status: 'unknown', changing: true});
                    setTimeout(function () {
                        if ($(NAME).val() === 'device 10') {
                            formStateView.setMessage({
                                summary: 'Unable to guarantee safety. And let\'s make this a really long message as well so we can see how we handle really long messages here',
                                status: 'error',
                                details: '<p>Sorry! With a really long message so we can see how we handle wrapping, which we should be able to handle really well. Really, really well.</p> <p>Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.</p>'});
                            updateInProgress = false;
                        } else {
                            presenter.updateSelectedItems({name: $(NAME).val()}, {
                                success : onItemUpdateSuccess,
                                error : onItemUpdateError
                            });
                        }
                    }, 3000);
                }
            }
            
            function changeLocation(location) {
                if (location.length > ROUTE_PREFIX.length) {
                    $(PANELS).hpStackedPanels('setPanelByLocation', '#' + location);
                } else {
                    $(PANELS).hpStackedPanels('setFirstPanel');
                }
            }
            
            this.resume = function () {
                presenter.on("selectionChange", onSelectionChange);
                presenter.on("itemChange", onItemChange);
                presenter.on("itemError", onItemError);
                $(PANELS).hpStackedPanels('resume');
            };
            
            this.pause = function () {
                presenter.off("selectionChange", onSelectionChange);
                presenter.off("itemChange", onItemChange);
                presenter.off("itemError", onItemError);
                $(PANELS).hpStackedPanels('pause');
                formStateView.reset();
            };
          
            /**
             * @public
             */
            this.init = function () {
              
                for (var i=1; i<20; i+=1) {
                    possibleRelations.push({
                        id: i,
                        name: "accelerator " + i,
                        model: 'HP Particle Accelerator ' + (['abc', 'def'][i % 2]),
                        speed: 200
                    });
                }
                relations = possibleRelations.splice(1, 3);
              
                relationsTable = $(RELATIONS).dataTable({
                    bPaginate : false,
                    bFilter : true,
                    bInfo : false,
                    sScrollY : 200,
                    sScrollX : 600,
                    sScrollXInner : "100%",
                    bScrollCollapse: true,
                    oLanguage: {
                        sEmptyTable: localizer.getString('hpsum.node.noItemsFound'),
                        sSearch: localizer.getString('hpsum.common.search')
                    },
                    aaData: relations,
                    aoColumns : [
                        {sTitle: 'Name', mDataProp: 'name'},
                        {sTitle: 'Model', mDataProp: 'model'},
                        {sTitle: 'Speed', mDataProp: 'speed', sClass: 'tour-speed'},
                        {fnRender: function (oObj) {
                            return '<div class="hp-edit"></div>';
                        }, sClass: 'hp-icon', sWidth: 20},
                        {fnRender: function (oObj) {
                            return '<div class="hp-close"></div>';
                        }, sClass: 'hp-icon', sWidth: 20}
                    ]
                }).rowReordering().addClass('hp-reorderable');
                
                $(RELATIONS + ' .hp-close').click(onDeleteRelation);
                $(RELATIONS + ' .hp-edit').click(onEditRelation);
                
                $(SELECT).selectBox({autoWidth: false});
                
                $(PANELS).hpStackedPanels({
                    panelSelector : PANEL_SELECTOR
                });
                
                var searchResults = [                    
                    {id: 1, name: "First"},
                    {id: 2, name: "Second", error: 'unavailable'},
                    {id: 3, name: "Third", help: 'help'},
                    {id: 4, name: "Fourth"},
                    {id: 5, name: "Fifth"},
                    {id: 6, name: "Sixth"},
                    {id: 7, name: "Seventh"},
                    {id: 8, name: "Eighth"}
                ];
                
                $(SEARCHER).hpSearchCombo({
                    getResults: function (string, handlers, count, start) {
                        setTimeout(function () {
                            var results = searchResults;
                            if (string && string.length > 0) {
                                results =
                                    $.grep(searchResults, function(option, index) {
                                        return (option.name.match(
                                            new RegExp(string, 'i')));
                                    });
                            }
                            handlers.success({
                                count: results.length,
                                members: results, 
                                start: 0, 
                                total: results.length
                            });
                        }, 200); // simulate server delay
                    },
                    searchingMessage: localizer.getString('search.searching'),
                    noMatchesMessage: localizer.getString('search.noMatches'),
                    matchesMessage: localizer.getString('search.matches')
                });
                
                $(TOGGLE).hpToggle({checked: 'Enabled', unchecked: 'Disabled'});
                
                $(COLLAPSE).hpCollapsible();
                
                formStateView.init({form: FORM,
                    routePattern: ROUTE_PREFIX + '.*',
                    autoTrack: true});
                
                $(ADD_RELATION).bind('click', onAddRelation);
                
                $(TOGGLE).change(function () {
                    if ($("#added").length === 0) {
                        $(TOGGLE).parents('ol').first().
                            append('<li class="hp-form-item"><label for="added">Dynammically added</label>' +
                              '<input id="added"/></li>');
                    }
                });
                
                $(OK).bind('click', function(ev) {
                    onUpdateItem();
                    ev.preventDefault();
                });
                
                $(CANCEL).bind('click', function(ev) {
                    formStateView.reset();
                });
                
                $('#tour-enclosure-usage-interval').change(function () {
                    if ($(this).val() == 0) {
                        formStateView.unUpdate('tour-enclosure-usage-interval', 'Usage interval');
                    } else {
                        formStateView.update('tour-enclosure-usage-interval', 'Usage interval',
                            $(this).val())
                    }
                });
                
                $('#tour-enclosure-usage-type').hpSearchCombo({
                       results: [
                           {id: 1, name: "Choice 1"},
                           {id: 2, name: "Choice 2"},
                           {id: 3, name: "Choice 3"}
                       ]
                   });
                
                router.watch('enclosure edit section', ROUTE_PREFIX + '.*',
                    {parent: ROUTE_PREFIX, change: changeLocation});
                
                this.resume();
            };
        }

        return new EnclosureEditView();
    }());
    
    return EnclosureEditView;
});
