(function () {
    'use strict';

    angular
        .module('editorRotas')
        .controller('etapa2Controller', etapa2);

    etapa2.$inject = ['$scope', 'FuncionalidadesMapa', 'atalhos', 'ferramentaCamadaVisualizacao', 'ferramentaClassificarTrechos', '$routeParams',
        'pacmansService', 'rotasService', 'setoresService', 'etapasService', '__env', 'ferramentaContinuarItinerario', 'ferramentaInicioFimColeta',
        'configuracoesGerais', 'ngNotify', 'calculoDistancia'
    ];

    function etapa2($scope, FuncionalidadesMapa, atalhos, ferramentaCamadaVisualizacao, ferramentaClassificarTrechos, $routeParams,
        pacmansService, rotasService, setoresService, etapasService, __env, ferramentaContinuarItinerario, ferramentaInicioFimColeta,
        configuracoesGerais, ngNotify, calculoDistancia) {

        const vm = this;
        angular.extend(vm, {
            excluirRotaRodape: excluirRotaRodape,
            avancarEtapa: avancarEtapa,
            salvarEtapa: salvarEtapa,
            TratarEvento: TratarEvento
        });

        // ------------ variáveis do scope
        vm.visibility = {
            camadaVisualizacao: true,
            cursor: true,
            importarHistorico: false,
            continuarItinerario: false,
            ajustarTrecho: false,
            classificarTrecho: true,
            apagarTrecho: false,
            medirDistancia: true,
            inicioFimColeta: true,
            horarioColeta: false,
            pacmans: false,
            informacoesRota: true
        };
        vm.appPath = __env.appPath;
        vm.configuracoesGerais = configuracoesGerais.data;
        vm.usarGeoGoogle = false;
        vm.permissions = ['camadaVisualizacao', 'informacoesRota', 'classificarTrechos', 'medirDistancia', 'inicioFimColeta', 'cursor'];
        // ------------ variáveis do scope

        //------------- Chamada ao inicializar a controller
        $scope.Init = () => {
            // Seta os escopos nas factories e inicializa ferramentas
            ferramentaContinuarItinerario.Init($scope.Mapa, ferramentaInicioFimColeta);
            FuncionalidadesMapa.SetScope($scope);
            atalhos.Init();
            atalhos.SetScope($scope);
            FuncionalidadesMapa.SetScope($scope);

            // Carrega as informações da rota
            rotasService.CarregarInformacaoRotaPorCodigoRota({
                CodigoRota: $routeParams.CodigoRota,
                RotasTemp: $routeParams.rt
            })
                .then(successCarregarInformacaoRotaPorCodigo)
                .catch(errorRequest);
        };

        vm.SignalR = new PersistentConnectionSR({
            mapeamento: urlGlobal + "TunelEditorRotas",
            onConnected: function () {
                console.log('SignalR Conectado');
            }
        });

        vm.SignalR.SetHandlers(vm);

        function TratarEvento(evento, mensagem) {
            console.log(evento);
            console.log(mensagem);
        }

        // ------------ Callbacks requisições iniciais
        /**
         * Apresenta as informações da modal de informações da rota e realiza as outras requisições da tela
         * @param {*} result
         */
        function successCarregarInformacaoRotaPorCodigo(result) {

            vm.informacoesRotaAtual = result.data;
            vm.habilitarBotoes(result.data.Etapa);

            // Carrega área do setor
            setoresService.CarregarSetorArea($routeParams.CodigoSetor, $routeParams.CodigoRota, $routeParams.rt)
                .then(successCarregarSetorArea)
                .catch(errorRequest);

            // Carrega a rota
            rotasService.CarregarRota({
                CodigoRota: $routeParams.CodigoRota,
                RotasTemp: $routeParams.rt
            })
                .then(successCarregarRota)
                .catch(errorRequest);

            // Carrega os pacmans da rota
            pacmansService.CarregarPacmans({
                CodigoRota: $routeParams.CodigoRota,
                RotasTemp: $routeParams.rt
            })
                .then(successCarregarPacmans)
                .catch(errorRequest);
        }

        /**
         * Plota o setor no mapa
         * @param {*} result
         */
        function successCarregarSetorArea(result) {
            vm.Setor = $routeParams.CodigoSetor;
            if (result.data) FuncionalidadesMapa.AreaCordenadas($scope.Mapa.map, result.data);
            vm.carregarCamadas();
        }

        /**
         * Plota a rota no mapa
         * @param {*} result
         */
        function successCarregarRota(result) {
            if (result.data) {
                FuncionalidadesMapa.PlotarRota(result.data, $routeParams.CodigoRota, false, null, true, '', true);
                FuncionalidadesMapa.PlotarIniciofim($routeParams.CodigoRota, ferramentaInicioFimColeta);
                let polyline = FuncionalidadesMapa.GetRota($routeParams.CodigoRota);
                ferramentaClassificarTrechos.SelecaoPolylineClassificacao(polyline, $scope.Mapa);

                vm.isValid = ferramentaClassificarTrechos.TodosOsTrechosClassificados() && vm.informacoesRotaAtual.EtapaEnum === 2;
                if (vm.informacoesRotaAtual.EtapaEnum !== 2) vm.RotaObservable.notify('enable');

                if (!ferramentaClassificarTrechos.TodosOsTrechosClassificados()) {
                    setTimeout(() => ngNotify.set('Existe(m) ' + ferramentaClassificarTrechos.QuantidadeTrechoSemClassificacao() + ' trecho(s) restante(s) para classificação!', {
                        type: 'warn',
                        sticky: false,
                        button: false
                    }), 5000);

                    setTimeout(() => {
                        mostrarMensagemTamanhoRota(polyline);
                    }, 8000);
                } else {
                    mostrarMensagemTamanhoRota(polyline);
                }

                rotasService.CarregarRotasSetor($routeParams.CodigoSetor)
                    .then(successCarregarRotasSetor)
                    .catch(errorRequest);
            }
            vm.carregarCamadas();
        }

        function mostrarMensagemTamanhoRota(polyline) {
            let poly = polyline.getPath().getArray();

            if (poly.length > 2000) {
                ngNotify.set('Devido a grande quantidade de pontos o processamento da classificação terá uma duração maior que o convencional.', {
                    type: 'warn',
                    sticky: true,
                    button: true
                });
            } else if (poly.length > 1000) {
                ngNotify.set('Devido a quantidade de pontos, o sistema poderá apresentar lentidão ao classificar.', {
                    type: 'warn',
                    sticky: true,
                    button: true
                });
            }
        }

        /**
         * Preenche as outras rotas do setor
         * @param {*} result
         */
        function successCarregarRotasSetor(result) {
            let rotaPlotada = null;
            vm.rotasSetor = [];

            result.data.forEach((rota) => {
                if (rota.Codigo === parseInt($routeParams.CodigoRota)) rota.Selecionada = true;

                if (rota.Status !== 4 && rota.Codigo !== parseInt($routeParams.CodigoRota)) {
                    rotaPlotada = FuncionalidadesMapa.PlotarRota(null, rota.Codigo, false, null, false, '', false);
                    rotaPlotada.Selecionada = false;
                    rotaPlotada.Descricao = rota.Descricao;
                    rotaPlotada.Apelido = rota.Apelido;
                    rotaPlotada.RotasTemp = rota.RotasTemp;
                }

                vm.rotasSetor.push(rota);
            });

            vm.CarregarConfiguracoesVisualizacao('Etapa02');
            ferramentaCamadaVisualizacao.MostrarPacmans(false, parseInt($routeParams.CodigoRota));
        }

        /**
         * Plota os pacmans e recarrega as camadas
         * @param {*} result
         */
        function successCarregarPacmans(result) {
            if (result.data) FuncionalidadesMapa.PlotarPacman(result.data, $routeParams.CodigoRota);
            vm.carregarCamadas();
        }
        // ------------ Callbacks requisições iniciais

        /**
         * Exclui rota pelo botão do rodapé
         */
        function excluirRotaRodape() {
            let rota = {
                Codigo: $routeParams.CodigoRota,
                RotasTemp: $routeParams.rt,
                Status: 1
            };

            vm.abrirModalExcluirRota(rota);
        }

        // --------------------- Salvar Etapa
        /**
         * Salva a classificação da etapa
         */
        function salvarEtapa() {
            let rota = FuncionalidadesMapa.GetRota($routeParams.CodigoRota);
            calculoDistancia.calcularDistanciaPonto(rota);
            let pontos = [];

            rota.getPath().getArray().forEach((i) => {
                pontos.push({
                    Distancia: i.Distancia ? i.Distancia : 0,
                    DentroSetor: i.DentroSetor ? i.DentroSetor : false,
                    Trecho: i.Trecho ? i.Trecho : null,
                    Tipo: i.Tipo ? i.Tipo : "",
                    Latitude: parseInt(i.lat() * 1000000),
                    Longitude: parseInt(i.lng() * 1000000),
                    PossuiGeocode: i.PossuiGeocode ? i.PossuiGeocode : "",
                    TransversalInicio: i.TransversalInicio ? i.TransversalInicio : "",
                    TransversalFim: i.TransversalFim ? i.TransversalFim : "",
                    Rua: i.Rua ? i.Rua : "",
                    PacmanAtivo: i.PacmanAtivo ? i.PacmanAtivo : "",
                    Instrucao: i.Instrucao
                });
            });

            let params = {
                pontos: pontos,
                codigoRota: parseInt($routeParams.CodigoRota),
                estado: 'S'
            };

            vm.statusRodape = 'salvando';
            etapasService.SalvarEtapa(params)
                .then(successSalvarEtapa)
                .catch(errorRequest);
        }

        /**
         * Habilita botão para avançar a etapa ao salvar a rota
         * @param {*} result
         */
        function successSalvarEtapa(result) {
            vm.statusRodape = 'salvo';
            if (result.data.Sucesso) {
                vm.RotaObservable.notify('disable');

                vm.isValid = ferramentaClassificarTrechos.TodosOsTrechosClassificados();

                if (!vm.isValid)
                    setTimeout(() => ngNotify.set('Existe(m) ' + ferramentaClassificarTrechos.QuantidadeTrechoSemClassificacao() + ' trecho(s) restante(s) para classificação!', {
                        type: 'warn',
                        sticky: true,
                        button: true
                    }), 2000);

                ngNotify.set(result.data.MensagemSucesso, {
                    type: 'success',
                    sticky: false,
                    button: true
                });
                vm.habilitarBotoes('S');

                rotasService.CarregarInformacaoRotaPorCodigoRota({
                    CodigoRota: $routeParams.CodigoRota,
                    RotasTemp: $routeParams.rt
                })
                    .then((infoRota) => vm.informacoesRotaAtual = infoRota.data)
                    .catch(errorRequest);
            } else ngNotify.set(result.data.MensagemErro, {
                type: 'error',
                sticky: true,
                button: true
            });
        }
        // --------------------- Salvar Etapa

        // ------------------ Avançar Etapa
        /**
         * Avança para a próxima etapa
         */
        function avancarEtapa() {
            if (!vm.isValid && vm.viewHasChanged) {
                ngNotify.set('A Etapa precisa ser salva para avançar', {
                    type: 'warn',
                    sticky: true,
                    button: true
                });
                return false;
            }

            if (!ferramentaClassificarTrechos.TodosOsTrechosClassificados()) {
                ngNotify.set('Existem trechos não classificados, por favor verifique.', {
                    type: 'warn',
                    sticky: true,
                    button: true
                });
                return false;
            }

            vm.statusRodape = 'avancando';

            etapasService
                .AvancarEtapa({
                    codigoRota: $routeParams.CodigoRota
                })
                .then(successAvancarEtapa)
                .catch(errorRequest);
        }

        /**
         * Redireciona a rota para a próxima etapa
         */
        function successAvancarEtapa() {
            window.location.href = urlGlobal + 'EditorRotas/Etapa3/?CodigoSetor=' + $routeParams.CodigoSetor + '&CodigoRota=' + $routeParams.CodigoRota + '&rt=' + $routeParams.rt;
        }
        // ------------------ Avançar Etapa

        /**
         * Função padrão de erro de requisição
         * @param {*} error parametro com as informações do erro
         */
        function errorRequest(error) {
            if (error.statusText)
                ngNotify.set(error.statusText, {
                    type: 'error',
                    sticky: true,
                    button: true
                });

            console.error(error);
        }
    }
})();
