(function () {
    'use strict';

    angular
        .module('setoresApp')
        .directive('grid', grid);

    grid.$inject = ['__env', '$state', 'utilsFactory', 'mapsSingletonService'];

    /* @ngInject */
    function grid(__env, $state, utilsFactory, mapsSingletonService) {

        let directive = {
            restrict: 'A',
            replace: false,
            require: 'ngModel',
            link: link,
            scope: false
        };
        return directive;

        function link(scope, element, attrs, ngModel) {
            //exports
            angular.extend(scope.vm, {
                clickHeaderGrid: clickHeaderGrid,
                renderGrid: renderGrid,
                refreshGrid: refreshGrid
            });

            let dataView, checkboxSelector, headerButtonsPlugin;

            scope.vm.dataGridOpen = true;

            if (!isNaN(ngModel.$modelValue)) {
                renderGrid();
            }

            ngModel.$render = function () {
                if (ngModel.$modelValue) {
                    ngModel.$modelValue.columns.forEach(function (column) {

                        column.template = column.formatter;

                        switch (column.id) {
                            case 'Logradouro':
                                column.width = 45;
                                column.formatter = logradouroFormatter;
                                break;
                            case 'Atividade':
                                column.formatter = atividadeFormatter;
                                break;
                            case 'PorcentagemRound':
                                column.formatter = porcentagemFormatter;
                                break;
                            case 'ValorOcupacao':
                                column.formatter = ocupacaoFormatter;
                                break;
                            case 'Contestacao':
                            case 'ContestacaoExterna':
                                column.formatter = contestacaoFormatter;
                                break;
                            case 'Ignicao':
                                column.formatter = ignicaoFormatter;
                                break;
                            case 'Velocidade':
                                column.formatter = velocidadeFormatter;
                                break;
                            case 'Acao':
                                column.formatter = acaoFormatter;
                                break;
                            case 'BtnView':
                                column.formatter = column.formatter || btnViewFormatter;
                                break;
                            case 'BtnConfig':
                                column.formatter = btnConfigFormatter;
                                break;
                            case 'Descricao':
                                break;
                            default:
                                column.formatter = defaultFormatter;
                        }
                    });
                    renderGrid();
                }
            };

            function refreshGrid() {
                (ngModel.$modelValue.grid || {
                    invalidate: () => {
                    }
                }).invalidate();

                if (!scope.$$phase) {
                    scope.$apply();
                }

            }

            function renderGrid() {
                ngModel.$modelValue.options.columnPicker = {
                    hideForceFitButton: true,
                    hideSyncResizeButton: true
                };

                checkboxSelector = new Slick.CheckboxSelectColumn({
                    cssClass: "slick-cell-checkboxsel",
                    toolTip: "Selecionar todos"
                });
                headerButtonsPlugin = new Slick.Plugins.HeaderButtons();

                let selectorColumnDef = checkboxSelector.getColumnDefinition();
                let currentFormatter = selectorColumnDef.formatter;
                selectorColumnDef.formatter = (row, cell, value, columnDef, dataContext) => {

                    // Recebe a formatação atual do checkbox
                    let formatter = currentFormatter(row, cell, value, columnDef, dataContext);
                    // Valida se o campo está selecionado
                    let checked = $($(formatter)[0]).is(':checked');
                    let content = '';

                    let tipoAlarme = (!scope.vm.checkedAlarmeType || scope.vm.checkedAlarmeType === (dataContext.IdentificadorDE + dataContext.CodigoSetorCumprimento));
                    let property = checked ? (tipoAlarme ? 'checked="checked"' : 'disabled="disabled"') : (tipoAlarme ? '' : 'disabled="disabled"');

                    if (dataContext) {
                        content = `<input id="selector${row}" type="checkbox" ${property}><label for='selector${row}'></label>`;
                    }

                    return content;
                };

                if (ngModel.$modelValue.customOptions.checkbox) {
                    ngModel.$modelValue.columns.unshift(selectorColumnDef);
                }

                dataView = new Slick.Data.DataView();
                dataView.setItems(ngModel.$modelValue.data, ngModel.$modelValue.uniqueColumn);

                const oldColumnsValue = JSON.parse(localStorage.getItem("grid-setores"));

                if (oldColumnsValue) {
                    localStorage.setItem("grid_setores", JSON.stringify(oldColumnsValue.filter(x => x.visivel).map(x => x.item)));
                    localStorage.removeItem("grid-setores");
                }

                const columnsSaved = JSON.parse(localStorage.getItem("grid_setores"));

                ngModel.$modelValue.columns.forEach(item => {
                    item.visible = !(columnsSaved && !columnsSaved.find(x => item.id === x.id));
                });

                ngModel.$modelValue.grid = new Slick.Grid(element, dataView, ngModel.$modelValue.columns, ngModel.$modelValue.options);
                if (ngModel.$modelValue.customOptions.columnpicker) {
                    ngModel.$modelValue.columnpicker = new Slick.Controls.ColumnPicker(ngModel.$modelValue.columns, ngModel.$modelValue.grid, ngModel.$modelValue.options);
                    ngModel.$modelValue.columnpicker.onColumnsChanged.subscribe((eventData, gridOptions) => {
                        localStorage.setItem("grid_setores", JSON.stringify(gridOptions.columns));
                    });
                }

                ngModel.$modelValue.grid.setSelectionModel(new Slick.RowSelectionModel({
                    selectActiveRow: false
                }));

                dataView.getItemMetadata = metadata(dataView.getItemMetadata);

                function metadata(old_metadata_provider) {
                    let atividadesCell = {};

                    return function (row) {
                        let item = this.getItem(row);
                        let ret = (old_metadata_provider(row) || {});

                        if (item) {
                            ret.class = (ret.class || '');
                            //Include any row level CSS rules here by editing ret.cssClasses

                            //Clear previous CSS rule for this cell.
                            if (atividadesCell.hasOwnProperty(row)) {
                                delete atividadesCell[row];
                            }

                            //Evaluate the value here and add to either map
                            if (!atividadesCell[row]) {
                                atividadesCell[row] = {};
                            }
                            atividadesCell[row].Atividade = 'cor-status-atividade';

                            //Set Cell CSS.
                            ngModel.$modelValue.grid.setCellCssStyles('style-atividades', atividadesCell);
                        }
                        return ret;
                    };
                }

                if (ngModel.$modelValue.customOptions.headerButtons) {
                    ngModel.$modelValue.grid.registerPlugin(headerButtonsPlugin);
                }

                if (ngModel.$modelValue.customOptions.checkbox) {
                    ngModel.$modelValue.grid.registerPlugin(checkboxSelector);
                }

                dataView.onRowCountChanged.subscribe(() => {
                    ngModel.$modelValue.grid.updateRowCount();
                    ngModel.$modelValue.grid.render();
                });

                dataView.onRowsChanged.subscribe((e, args) => {
                    ngModel.$modelValue.grid.invalidateRows(args.rows);
                    ngModel.$modelValue.grid.render();
                });

                headerButtonsPlugin.onCommand.subscribe(ngModel.$modelValue.onHeaderBtnClick);
                ngModel.$modelValue.grid.onClick.subscribe(ngModel.$modelValue.onClick);
                ngModel.$modelValue.grid.onDblClick.subscribe(ngModel.$modelValue.onDblClick);
                ngModel.$modelValue.grid.onScroll.subscribe(ngModel.$modelValue.onScroll);
                ngModel.$modelValue.grid.onSelectedRowsChanged.subscribe(ngModel.$modelValue.onSelectedRowsChanged);
                ngModel.$modelValue.grid.onHeaderClick.subscribe(ngModel.$modelValue.onHeaderClick);
                ngModel.$modelValue.grid.onSort.subscribe((e, args) => {
                    (args.sortCols || []).forEach(col => {
                        let field = col.sortCol.field;
                        let sign = col.sortAsc ? 1 : -1;

                        dataView.sort((dataRow1, dataRow2) => {
                            let value1 = formatColumnValue(dataRow1[field], field),
                                value2 = formatColumnValue(dataRow2[field], field);
                            return (value1 === value2 ? 0 : (value1 > value2 ? 1 : -1)) * sign;
                        });
                    });
                });

                ngModel.$modelValue.grid.autosizeColumns();
                ngModel.$modelValue.grid.checkboxSelector = checkboxSelector;
                mapsSingletonService.getMap().resizeMap();
            }

            function formatColumnValue(value, column) {
                if ('ValorOcupacao' === column) {
                    return value === null ? -1 : value;
                }
                return value || '';
            }

            function clickHeaderGrid() {
                scope.vm.dataGridOpen = !scope.vm.dataGridOpen;
                let footerElement = $state.current.name === 'setores' ? element.parent() : element.parent().parent();

                footerElement.removeAttr('style');
                footerElement.siblings('main').removeAttr('style');

                setTimeout(() => {
                    mapsSingletonService.getMap().resizeMap();
                    if ($state.current.name === 'setores' && scope.vm.gridSetores) {
                        scope.vm.gridSetores.grid.resizeCanvas();
                    }
                }, 300);
            }

            //formatter
            function defaultFormatter(row, cell, value) {
                return !value ? '' : value;
            }

            function logradouroFormatter(row, cell, value, columnDef, dataContext) {
                if (value) {
                    if (value.indexOf('->->') >= 0) {
                        return `<button id="geoCode_${row}" class='btn-geocode ${dataContext.Veiculo ? '' : 'disabled'}' ${dataContext.Veiculo ? '' : 'disabled'}>
                                   Ver logradouro
                                </button>`;
                    } else {
                        return value;
                    }
                } else {
                    return "->->";
                }
            }

            function atividadeFormatter(row, cell, value, columnDef, dataContext) {
                let cor = utilsFactory.preencheHexadecimal(dataContext.AtividadeCor);
                let texto = dataContext.Atividade;
                return texto ? `<span class="atividade-value" data-coratividade="${cor}"
                                style="background-color: ${cor}; box-shadow: 0 0 0 1px ${cor}">${texto}</span>` : "";
            }

            function porcentagemFormatter(row, cell, value, columnDef) {
                return columnDef.template.replace('{value}', value).replace(`>{value}`, `>${value}`);
            }

            function ocupacaoFormatter(row, cell, value, columnDef) {
                let isValid = (!scope.vm.lastItemData || utilsFactory.isAnActualDate(new Date(scope.vm.lastItemData.Pesquisa[0])) && value !== null) && value != null;
                return columnDef.template.replace('{value}', isValid ? value : '0').replace(`>{value}%`, `>${isValid ? `${value}%` : '-'}`);
            }

            function contestacaoFormatter(row, cell, value, columnDef) {
                return columnDef.template.replace('{value}', value);
            }

            function ignicaoFormatter(row, cell, value) {
                return value ? `<span class="${value === 'L' ? 'turned-on' : 'turned-off'}">
                                    <span class="icon-power"></span> ${value === 'L' ? 'Ligado' : 'Desligado'}
                                </span>` : '';
            }

            function velocidadeFormatter(row, cell, value) {
                return `${value || 0} Km/h`;
            }

            function acaoFormatter(row, cell, value, columnDef) {
                return columnDef.template;
            }

            function btnViewFormatter() {
                return `<button class="btn-base btn-size-xs btn-color-default btn-view">
                            <i class="icon-eye icon icon-size-s"></i>
                        </button>`;
            }

            function btnConfigFormatter(row, cell, value, columnDef) {
                columnDef.disabled = !!(ngModel.$modelValue.data[row].CodigoSetorCumprimento && scope.vm.setorEmReprocessamento);

                if (columnDef.disabled) {
                    return `<button class="btn-base btn-size-xs btn-color-default btn-config btn-disabled" disabled>
                            <i class="icon-tool icon icon-size-s"></i>
                        </button>`;
                } else {
                    return `<button class="btn-base btn-size-xs btn-color-default btn-config">
                            <i class="icon-tool icon icon-size-s"></i>
                        </button>`;
                }
            }
        }
    }
})();
