(function () {
    'use strict';

    angular
        .module('contestacaoApp')
        .directive('ferramentaReferencias', ferramentaReferencias);

    ferramentaReferencias.$inject = ['setoresServiceFactory', 'utilsFactory', 'ClassificacaoReferencias', 'mapsSingletonService'];

    /* @ngInject */
    function ferramentaReferencias(setoresServiceFactory, utilsFactory, ClassificacaoReferencias, mapsSingletonService) {
        return {
            restrict: 'E',
            replace: true,
            link: link,
            templateUrl: __env.appPath + 'scripts/components/tools/referencias/ferramenta-referencias.directive.html',
            scope: false
        };

        function link(scope) {
            //exports
            angular.extend(scope.vm, {
                selecionarClassificacao: selecionarClassificacao,
                selecionarTipo: selecionarTipo,
                selecionarReferencia: selecionarReferencia,
                limparReferencias: limparReferencias,
                filtrarReferencias: filtrarReferencias
            });

            scope.vm.listaReferencias = [];
            scope.vm.referenciaFiltrada = '';

            setoresServiceFactory.carregarReferencias()
                .then(result => {
                    scope.vm.listaReferencias = formatarRetornoServidor(result.data);

                    scope.vm.listaReferencias
                        .forEach(classificacao => classificacao.tipos
                            .forEach(tipo => tipo.referencias
                                .forEach(referencia => referencia.inicializar())));

                }).catch((error) => console.error(error));

            function filtrarReferencias() {
                if (scope.vm.referenciaFiltrada === undefined) {
                    return;
                }

                scope.vm.listaReferencias.forEach(classificacao => {
                    classificacao.tipos.forEach(tipo => {
                        tipo.referencias.forEach(referencia => referencia.visivel = referencia.descricao
                            .toUpperCase().includes(scope.vm.referenciaFiltrada.toUpperCase()));

                        tipo.visivel = !!tipo.referencias.find(referencia => referencia.visivel);
                        tipo.checked = tipo.todasReferenciasSelecionadas();
                    });

                    classificacao.checked = classificacao.todosTiposSelecionados();
                });
            }

            scope.$on('aoSelecionarClassificacao', manipularEventoSelecionarClassificacao);
            scope.$on('aoSelecionarTipo', manipularEventoSelecionarTipo);
            scope.$on('aoSelecionarReferencia', manipularEventoSelecionarReferencia);

            function manipularEventoSelecionarClassificacao(evt, classificacao) {
                classificacao.manipularStatusTipos();
                classificacao.tipos.filter(x => x.visivel)
                    .forEach(tipo => scope.$emit('aoSelecionarTipo', classificacao, tipo));
            }

            function manipularEventoSelecionarTipo(evt, classificacao, tipo) {
                tipo.manipularStatusReferencias();
                tipo.referencias.filter(x => x.visivel)
                    .forEach(referencia => scope.$emit('aoSelecionarReferencia', classificacao, tipo, referencia));

                classificacao.checked = classificacao.todosTiposSelecionados();
                mapsSingletonService.getMap().fitBoundsElements('referencia');
            }

            function manipularEventoSelecionarReferencia(evt, classificacao, tipo, referencia, selecaoDireta) {
                referencia.checked ? referencia.objetoMapa.exibirObjetoMapa() : referencia.objetoMapa.ocultarObjetoMapa();

                tipo.checked = tipo.todasReferenciasSelecionadas();
                classificacao.checked = classificacao.todosTiposSelecionados();


                if (selecaoDireta) {
                    mapsSingletonService.getMap().fitBoundsElements('referencia', (data) => data == referencia.codigo);
                }
            }

            function selecionarClassificacao(classificacao) {
                scope.$emit('aoSelecionarClassificacao', classificacao);
            }

            function selecionarTipo(classificacao, tipo) {
                scope.$emit('aoSelecionarTipo', classificacao, tipo);
            }

            function selecionarReferencia(classificacao, tipo, referencia) {
                scope.$emit('aoSelecionarReferencia', classificacao, tipo, referencia, true);
            }

            function limparReferencias() {
                scope.vm.listaReferencias.forEach(classificacao => {
                    classificacao.checked = false;
                    scope.$emit('aoSelecionarClassificacao', classificacao);
                });
            }

            function formatarRetornoServidor(dados) {
                const obj = utilsFactory.convertKeysToCamelCase(dados);
                let newObjs = [];

                for (let prop in obj) {
                    if (obj.hasOwnProperty(prop)) {
                        newObjs.push(new ClassificacaoReferencias(obj[prop], prop));
                    }
                }

                return newObjs;
            }
        }
    }
}
)();


