(function () {
    'use strict';

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

    ferramentaContestacao.$inject = ['__env', 'setoresServiceFactory', 'ngNotify', '$location', '$compile', 'infowindowTemplates', 'utilsFactory',
        'userMessages', 'FormValidation', 'mapsSingletonService'];

    /* @ngInject */
    function ferramentaContestacao(__env, setoresServiceFactory, ngNotify, $location, $compile, infowindowTemplates, utilsFactory,
        userMessages, FormValidation, mapsSingletonService) {
        return {
            restrict: 'E',
            replace: true,
            require: 'ngModel',
            templateUrl: __env.appPath + 'scripts/components/tools/contestacao/ferramenta-contestacao.directive.html',
            link: link,
            scope: false
        };

        function link(scope) {
            /* exports */
            let _urlParams = $location.$$search;
            angular.extend(scope.vm, {
                carregarJustificativasSetor: carregarJustificativasSetor,
                toggleJustificativa: toggleJustificativa,
                downloadFileContestacao: downloadFileContestacao,
                responderContestacao: responderContestacao,
                fecharModalJustificativa: fecharModalJustificativa,
                salvarJustificativa: salvarJustificativa,
                removerJustificativa: removerJustificativa,
                downloadFileJustificativa: downloadFileJustificativa,
                toggleTrechoContestacao: toggleTrechoContestacao,
                abrirFerramentaContestacao: abrirFerramentaContestacao,
                onAddFileContestacao: onAddFileContestacao,
                onAddFileJustificativa: onAddFileJustificativa,
                onRemoveFile: onRemoveFile,
                cancelarContestacao: cancelarContestacao,
                setarValidacaoFormContestacao: setarValidacaoFormContestacao
            });

            scope.vm.listaJustificativas = [];
            scope.vm.listaNovosArquivosContestacao = [];
            scope.vm.listaNovosArquivosJustificativa = [];
            scope.vm.listaArquivosContestacao = [];
            scope.vm.listaJustificativasContestacao = [];
            scope.vm.descricaoArquivosJustificativa = 'Localize...';
            scope.vm.validacaoArquivoMensagem = null;
            let justificativaHabilitada = false;
            let buttonToggle = null;

            setoresServiceFactory.carregarJustificativa()
                .then(result => {
                    scope.vm.listaJustificativas = result.data;
                    scope.vm.formContestacao = scope.formContestacao;
                    scope.$watch('vm.listaNovosArquivosContestacao', onAddFileContestacao);
                    scope.$watch('vm.listaNovosArquivosJustificativa', onAddFileJustificativa);
                })
                .catch(errorRequest);

            function carregarJustificativasSetor() {
                setoresServiceFactory.carregarJustificativas(_urlParams.codigoSetor, _urlParams.dt)
                    .then(result => {
                        /* Remover justificativas atuais */
                        scope.vm.listaJustificativasContestacao = [];
                        mapsSingletonService.getMap().closePopup('justificativa');
                        mapsSingletonService.getMap().removeMarkers('justificativa');

                        /* TODO: ver possibilidade de fazer JSON.parse em todos os retornos de consulta */
                        if (result.data && result.data !== 'null' && result.data.length > 0) {
                            result.data.forEach(justificativa => plotarJustificativa(justificativa));
                        }
                    }).catch(errorRequest);
            }

            function abrirFerramentaContestacao(codigoTrecho) {
                scope.vm.toolOpen = 'question';
                const element = $(`#trecho-${codigoTrecho}`);

                if (!element.hasClass('open')) {
                    const trigger = element.find('[data-collapse-trigger]');
                    $(trigger).click();
                }
            }

            scope.$parent.$on('toggleTrechosContestados', (localScope, todosTrechosContestadosAparecem) => {
                var historico = scope.vm.contestacao.Contestacao.ContestacaoHistorico.flatMap(x => x.ContestacaoHistoricoTrecho);
                historico.forEach(x => x.markerToggled = todosTrechosContestadosAparecem);
            });

            function toggleTrechoContestacao(trecho) {
                const map = mapsSingletonService.getMap();

                trecho.markerToggled = true;
                var historico = scope.vm.contestacao.Contestacao.ContestacaoHistorico.flatMap(x => x.ContestacaoHistoricoTrecho);
                var todosTrechosContestadosAparecem = historico.every(x => x.markerToggled);

                scope.$parent.$emit('todosTrechosContestadosAparecem', todosTrechosContestadosAparecem);

                map.toggleMarkers(trecho.markerToggled, 'contestacao', (x) => x === trecho.CodigoTrecho);
                map.setCenterMarker('contestacao', (x) => x === trecho.CodigoTrecho);
                scope.vm.onClickContestacao(null, trecho.CodigoTrecho, true);
            }

            function responderContestacao() {
                if (scope.vm.contestacao.Contestacao.StatusContestacao === 3 ||
                    scope.vm.contestacao.Contestacao.StatusContestacao === 4) {
                    reabrirContestacao();
                } else {
                    let obj = {
                        codigoContestacao: scope.vm.contestacao.Contestacao.Codigo,
                        observacao: scope.vm.contestacao.Contestacao.ObservacaoGeral,
                        justificativa: scope.vm.contestacao.Contestacao.Justificativa,
                        trechos: JSON.stringify(scope.vm.contestacao.Contestacao.ContestacaoTrecho)
                    };

                    if (!validateFileRules(scope.vm.listaArquivosContestacao)) {
                        return;
                    }

                    let dataAsFormData = new FormData();
                    angular.forEach(scope.vm.listaArquivosContestacao,
                        (value, key) => dataAsFormData.append(key, value));

                    dataAsFormData.append('codigoContestacao', obj.codigoContestacao);
                    dataAsFormData.append('observacao', obj.observacao);
                    dataAsFormData.append('justificativa', obj.justificativa);
                    dataAsFormData.append('trechos', obj.trechos);

                    scope.vm.showLoading();
                    setoresServiceFactory.responderContestacaoArquivo(dataAsFormData)
                        .then((result) => recarregarContestacao(result, userMessages.CONTESTACAO_RESPONDIDA))
                        .catch(errorRequest);
                }
            }

            function reabrirContestacao() {
                scope.vm.showLoading();
                setoresServiceFactory.reabrirContestacao(scope.vm.contestacao.Contestacao.Codigo)
                    .then((result) => recarregarContestacao(result, userMessages.CONTESTACAO_REABERTA))
                    .catch(errorRequest);
            }

            function recarregarContestacao(result, mensagem) {
                if (result && result.data) {
                    if (result.data.Sucesso) {
                        ngNotify.set(mensagem, { type: 'success', sticky: false });

                        scope.vm.carregarContestacao();
                        scope.vm.listaArquivosContestacao = [];
                    } else {
                        ngNotify.set(result.data.MensagemErro, { type: 'error', sticky: true });
                    }
                }
                scope.vm.hideLoading();
            }

            /* Todo: refatorar toda a parte de inclusão, remoção e validação de arquivos */
            function onAddFileContestacao(newValue) {
                if (newValue.length) {
                    scope.vm.listaArquivosContestacao.push(...newValue);
                }

                validateFileRules(scope.vm.listaArquivosContestacao);
            }

            function onAddFileJustificativa(newValue) {
                if (newValue.length) {
                    scope.vm.descricaoArquivosJustificativa = Array.from(newValue).map(x => x.name).join(', ');
                }

                validateFileRules(Array.from(newValue));
            }

            function validateFileRules(arquivos) {
                let message = null;

                if (arquivos.some(x => !x.name.toLowerCase().includes('.jpg') &&
                    !x.name.toLowerCase().includes('.png') && !x.name.toLowerCase().includes('.pdf') &&
                    !x.name.toLowerCase().includes('.jpeg'))) {
                    message = userMessages.FORMATO_ARQUIVOS_INCORRETOS;
                } else if (arquivos.length > 10) {
                    message = userMessages.QUANTIDADE_ARQUIVOS_EXCEDENTE;
                } else if (arquivos.length > 0 && utilsFactory
                    .convertMebibyteToByte(arquivos
                        .map(x => x.size)
                        .reduce((accumulator, currentValue) => accumulator + currentValue)) >= 5) {
                    message = userMessages.TAMANHO_ARQUIVOS_EXCEDENTE;
                }

                scope.vm.validacaoArquivoMensagem = message;
                if (scope.vm.formContestacao.$valid && message) {
                    setTimeout(() => scope.vm.scrollBottom('#scroll-ferramenta-contestacao'), 10);
                }

                return !message;
            }

            function onRemoveFile(file) {
                scope.vm.listaArquivosContestacao = scope.vm.listaArquivosContestacao.filter(item => item !== file);
                $('#listaArquivosContestacaoInput').prop('value', '');

                validateFileRules(scope.vm.listaArquivosContestacao);
            }

            function downloadFileContestacao(anexo) {
                window.open(`${__env.baseUrl}/Setores/Contestacao/DownloadAnexo?arquivo=${anexo.Anexo}` +
                    `&data=${anexo.DataHora}&codigoContestacao=${scope.vm.contestacao.Contestacao.Codigo}`);
            }

            function toggleJustificativa(enabled = true) {
                justificativaHabilitada = !justificativaHabilitada && enabled;
                buttonToggle = event.target;

                if (justificativaHabilitada) {
                    habilitaSelecaoJustificativa();
                } else {
                    desabilitaSelecaoJustificativa();
                }
            }

            function habilitaSelecaoJustificativa() {
                $(buttonToggle).addClass('active');

                const map = mapsSingletonService.getMap();
                const options = new InlogMaps.PolygonAlterOptions();
                options.color = '#9542ca';
                options.fillColor = '#9542ca';
                map.alterPolygonOptions('setor', options);

                $('#map svg, #map svg *').addClass('cursor-new-point');

                map.addPolygonEvent('setor', InlogMaps.PolygonEventType.Click, habilitaJustificativa);
            }

            function desabilitaSelecaoJustificativa() {
                $(buttonToggle).removeClass('active');
                justificativaHabilitada = false;

                const options = new InlogMaps.PolygonAlterOptions();
                options.color = '#000';
                options.fillColor = '#000';
                mapsSingletonService.getMap().alterPolygonOptions('setor', options);
                mapsSingletonService.getMap().removePolygonEvent('setor', InlogMaps.PolygonEventType.Click);

                $('#map svg, #map svg *').removeClass('cursor-new-point');
            }

            function habilitaJustificativa(event) {
                scope.vm.showLoading();
                mapsSingletonService.buscarGeoCodeReverso(event.latlng)
                    .then((result) => {
                        scope.vm.justificativa = {
                            CodigoSetor: _urlParams.codigoSetor,
                            DescricaoSetor: scope.vm.setorDescricao,
                            DataColeta: _urlParams.dt,
                            Latitude: Math.round(event.latlng[0] * 1000000),
                            Longitude: Math.round(event.latlng[1] * 1000000),
                            Endereco: result
                        };

                        scope.vm.hideLoading();
                        abrirModalJustificativa(result, event.latlng);
                    }).catch(err => {
                        console.log(err);
                        scope.vm.hideLoading();
                    });
            }

            function abrirModalJustificativa() {
                scope.vm.openModal('Justificar ponto', __env.appPath + 'scripts/partials/modal/modal-justificativa-setor.html', fecharModalJustificativa);
            }

            function fecharModalJustificativa() {
                scope.vm.closeModal().then(() => {
                    scope.vm.justificativa = {}
                    scope.vm.listaNovosArquivosJustificativa = [];
                    scope.vm.validacaoArquivoMensagem = null;
                });
            }

            function salvarJustificativa() {
                const arquivos = Array.from(scope.vm.listaNovosArquivosJustificativa);
                if (!validateFileRules(arquivos)) {
                    return;
                }
                const justificativa = scope.vm.justificativa;
                const dataAsFormData = new FormData();

                angular.forEach(arquivos,
                    (value, key) => dataAsFormData.append(key, value));

                dataAsFormData.append('justificativa', JSON.stringify(justificativa));

                setoresServiceFactory.salvarJustificativa(dataAsFormData)
                    .then(result => {
                        if (result.data && result.data.Sucesso) {
                            fecharModalJustificativa();
                            plotarJustificativa(result.data.Objeto);
                            ngNotify.set(userMessages.JUSTIFICATIVA_CRIADA, {
                                type: 'success',
                                sticky: false
                            });
                        }
                    })
                    .catch(errorRequest);
            }

            function plotarJustificativa(justificativa) {
                const latlng = [justificativa.Latitude / 1000000, justificativa.Longitude / 1000000];
                const iconUrl = `${__env.baseUrl}/${__env.appPath}images/ico_justificativa.png`;
                const icon = new InlogMaps.MarkerIcon(iconUrl, [27, 27]);
                const options = new InlogMaps.MarkerOptions(latlng, true, false, icon);
                options.object = { codigo: justificativa.Codigo };
                mapsSingletonService.getMap().drawMarker('justificativa', options, clickJustificativa);

                if (justificativa.CodigoPacman) {
                    mapsSingletonService.getMap().closePopup('pacmans');
                    mapsSingletonService.getMap().toggleMarkers(false, 'pacmans',
                        (item) => item.codigoPacman === justificativa.CodigoPacman);
                }

                scope.vm.listaJustificativasContestacao.push(justificativa);
            }

            function clickJustificativa(event, object) {
                const justificativa = scope.vm.listaJustificativasContestacao.find(item => item.Codigo === object.codigo);
                const options = new InlogMaps.PopupOptions();
                options.marker = 'justificativa';
                options.conditionMarker = (item) => item.codigo === object.codigo;

                if (justificativa.CodigoPacman) {
                    const pacman = scope.vm.listaPacmans.find(pacman => pacman.Codigo === justificativa.CodigoPacman);
                    options.content = $compile(infowindowTemplates.montarInfoWindowPacmanJustificado(justificativa, pacman))(scope)[0];
                }
                else options.content = $compile(infowindowTemplates
                    .montarInfoWindowPontoJustificado(justificativa))(scope)[0];

                mapsSingletonService.getMap().drawPopup('justificativa', options);
            }


            function downloadFileJustificativa(anexo, datahora, codigoJustificativa) {
                window.open(`${__env.baseUrl}/Setores/Setores/DownloadAnexoJustificativa?arquivo=${anexo}` +
                    `&data=${datahora}&codigoJustificativa=${codigoJustificativa}`);
            }

            function removerJustificativa(codigoJustificativa) {
                setoresServiceFactory.excluirJustificativa(codigoJustificativa)
                    .then(result => {
                        if (result.data && result.data.Sucesso) {
                            let codigoJustificativa = result.data.Objeto;
                            let idx = scope.vm.listaJustificativasContestacao.findIndex(item => item.Codigo === codigoJustificativa);

                            if (scope.vm.listaJustificativasContestacao[idx].CodigoPacman) {
                                /* Verifica se a camada está habilitada */
                                let camadaPacman = scope.vm.camadas.find(item => item.tipoCamada === scope.vm.tipoCamada.pacmans);
                                if (camadaPacman.checked) {
                                    mapsSingletonService.getMap().toggleMarkers(true, 'pacmans',
                                        pacman => pacman.Codigo === scope.vm.listaJustificativasContestacao[idx].CodigoPacman);
                                }
                            }

                            scope.vm.listaJustificativasContestacao.splice(idx, 1);
                            mapsSingletonService.getMap().closePopup('justificativa');
                            mapsSingletonService.getMap().removeMarkers('justificativa', (item) => item.codigo === codigoJustificativa);
                        }
                    }).catch(errorRequest);
            }

            function cancelarContestacao() {
                if (!scope.vm.validationFormContestacao) return;
                scope.vm.validationFormContestacao.resetControlsValidation();
                scope.vm.validationFormContestacao = null;
                scope.vm.contemPontosInvalidos = false;
                scope.vm.listaArquivosContestacao = [];
                scope.vm.validacaoArquivoMensagem = null;
            }

            function setarValidacaoFormContestacao() {
                if (scope.vm.validationFormContestacao !== null && scope.vm.validationFormContestacao !== undefined) return;

                scope.vm.validationFormContestacao = new FormValidation(scope.vm.formContestacao);
                scope.vm.validationFormContestacao.setControlsValidation(scope.vm.validacaoGrupoTrechosContestacao);
            }

            function copiarRespostaGeral() {
                if (scope.vm.copiarResposta) {
                    scope.vm.contestacao.Contestacao.ContestacaoTrecho.forEach(trecho => {
                        trecho.Descricao = scope.vm.contestacao.Contestacao.ObservacaoGeral;
                        trecho.Justificativa = scope.vm.contestacao.Contestacao.Justificativa;
                    });
                }
            }

            scope.$watch('vm.contestacao.Contestacao.ObservacaoGeral', copiarRespostaGeral);
            scope.$watch('vm.contestacao.Contestacao.Justificativa', copiarRespostaGeral);
            scope.$watch('vm.copiarResposta', copiarRespostaGeral);

            function errorRequest(error) {
                console.error(error);
            }
        }
    }
})();
