(function () {
    'use strict';

    angular
        .module('editorRotas')
        .controller('etapa1Controller', etapa1);

    etapa1.$inject = ['$scope', '$rootScope', 'FuncionalidadesMapa', 'atalhos', 'ferramentaCamadaVisualizacao', 'etapasService', 'historicoService',
        'pacmansService', 'rotasService', 'setoresService', 'FormValidation', '__env', 'ferramentaApagarTrecho', 'ferramentaContinuarItinerario',
        'ferramentaImportarHistorico', 'ferramentaInicioFimColeta', 'configuracoesGerais', '$routeParams', 'ngNotify', 'calculoDistancia', 'toaster'];

    function etapa1($scope, $rootScope, FuncionalidadesMapa, atalhos, ferramentaCamadaVisualizacao, etapasService, historicoService,
        pacmansService, rotasService, setoresService, FormValidation, __env, ferramentaApagarTrecho, ferramentaContinuarItinerario,
        ferramentaImportarHistorico, ferramentaInicioFimColeta, configuracoesGerais, $routeParams, ngNotify, calculoDistancia, toaster) {

        var vm = this;
        angular.extend(vm, {
            salvarEtapa: salvarEtapa,
            abrirModalImportarHistoricoSetor: abrirModalImportarHistoricoSetor,
            fecharModalImportarHistoricoSetor: fecharModalImportarHistoricoSetor,
            importarHistoricoSetor: importarHistoricoSetor,
            abrirModalImportarHistoricoVeiculo: abrirModalImportarHistoricoVeiculo,
            fecharModalImportarHistoricoVeiculo: fecharModalImportarHistoricoVeiculo,
            importarHistoricoVeiculo: importarHistoricoVeiculo,
            carregarVeiculosSetorPorData: carregarVeiculosSetorPorData,
            abrirModalApagarTodaRota: abrirModalApagarTodaRota,
            fecharModalApagarTodaRota: fecharModalApagarTodaRota,
            apagarTodaRota: apagarTodaRota,
            setarDataLimiteImportacaoSetor: setarDataLimiteImportacaoSetor,
            setarDataLimiteImportacaoVeiculo: setarDataLimiteImportacaoVeiculo,
            excluirRotaRodape: excluirRotaRodape,
            avancarEtapa: avancarEtapa,
            TratarEvento: TratarEvento
        });

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

        // ------------ variáveis locais
        let _setorRealizado = null;
        // ------------ variáveis locais

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

            // 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 ultima coleta do setor
            historicoService.CarregarSetoresRealizados($routeParams.CodigoSetor)
                .then((result) => { _setorRealizado = result.data; })
                .catch(errorRequest);

            // 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) {
            let rota = FuncionalidadesMapa.PlotarRota(result.data, $routeParams.CodigoRota, false, null, true, '', true);
            rota.Selecionado = true;

            vm.isValid = rota.getPath().getLength() > 0 && vm.informacoesRotaAtual.EtapaEnum === 1;
            if (vm.informacoesRotaAtual.EtapaEnum !== 1) vm.RotaObservable.notify('enable');

            if (result.data && result.data !== null && result.data !== 'null' && result.data.length > 0)
                FuncionalidadesMapa.PlotarIniciofim($routeParams.CodigoRota, vm.permissions);

            ferramentaApagarTrecho.InitApagarTrecho();

            // Carrega as outras rotas do setor
            rotasService.CarregarRotasSetor($routeParams.CodigoSetor)
                .then(successCarregarRotasSetor)
                .catch(errorRequest);

            vm.carregarCamadas();
        }

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

            if (!result.data || result.data === 'null')
                throw 'não foi possível atualizar os dados das outras rotas do setor';

            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.Selecionado = false;
                    rotaPlotada.Descricao = rota.Descricao;
                    rotaPlotada.Apelido = rota.Apelido;
                    rotaPlotada.RotasTemp = rota.RotasTemp;
                }
                vm.rotasSetor.push(rota);
            });

            vm.CarregarConfiguracoesVisualizacao('Etapa01');
            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 1
        /**
         * Salva a etapa 1
         */
        function salvarEtapa() {
            let rota = FuncionalidadesMapa.GetRota($routeParams.CodigoRota);

            if (ferramentaApagarTrecho.GetPolylinesApagarTecho().length > 1) {
                ngNotify.set('Existem trechos avulsos na rota, por favor verifique.', { type: 'warn', sticky: true, button: true });
                return false;
            } else if (!rota || rota.getPath().getArray().length === 0) {
                ngNotify.set('É preciso desenhar uma rota para Salvar!', { type: 'warn', sticky: true, button: true });
                return false;
            }

            vm.statusRodape = 'salvando';

            //ngNotify.dismiss();

            let pontos = [];
            calculoDistancia.calcularDistanciaPonto(rota);

            rota.getPath().getArray().forEach((i) => {
                pontos.push({
                    Distancia: i.Distancia ? i.Distancia : 0,
                    DentroSetor: FuncionalidadesMapa.GetSetor().Contains(i),
                    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: 'T'
            };

            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 = true;
                ngNotify.set(result.data.MensagemSucesso, { type: 'success', sticky: false });
                vm.habilitarBotoes('T');

                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 1

        // ---------------- Avançar etapa
        /**
         * Avança a rota para a próxima etapa
         */
        function avancarEtapa() {
            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/Etapa2/?CodigoSetor=" + $routeParams.CodigoSetor + "&CodigoRota=" + $routeParams.CodigoRota + "&rt=" + $routeParams.rt;
        }

        // ---------------- Avançar etapa

        // ------------ Apagar toda a rota
        /**
         * Abre a modal de apagar toda a rota.
         */
        function abrirModalApagarTodaRota() {
            vm.openModal('Confirmar apagar toda a rota', __env.appPath + 'scripts/partials/confirmar-apagar-rota.partial.html', fecharModalApagarTodaRota)
                .then(() => vm.modalOpen = true)
        }

        /**
         * Fecha a modal de apagar toda a rota.
         */
        function fecharModalApagarTodaRota() {
            vm.modalOpen = false;
            vm.closeModal().then(() => {
                if (atalhos) atalhos.Habilita(true)
            })
        }

        /**
         * Apaga toda a rota.
         */
        function apagarTodaRota() {
            vm.setFormStatus(vm.formApagarRota, 'SENDING').then(() => {
                ferramentaApagarTrecho.Desabilita();
                ferramentaApagarTrecho.ApagarTodaRota();
                ferramentaApagarTrecho.AtualizaRotaPlotada();
                ferramentaImportarHistorico.LimparHistoricosImportados();
                FuncionalidadesMapa.RemoverInicioFim();

                $rootScope.borrachaSimples = true;


                vm.RotaObservable.notify('enable');
                vm.isValid = false;
                vm.setFormStatus(vm.formApagarRota, 'SEND_SUCCESS').then(() => {
                    ngNotify.set('Rota apagada com sucesso', { type: 'success', sticky: false });
                    fecharModalApagarTodaRota();
                });
            });
        }

        // ------------ Apagar toda a rota

        // -------------------------- Importar Historico de Coleta no Setor
        /**
         * Abre modal de importar historico de Setor.
         */
        function abrirModalImportarHistoricoSetor() {
            // Seta data para pesquisa do veiculos do Setor.
            let data = _setorRealizado.DataHoraInicio ? new Date(_setorRealizado.DataHoraInicio) : new Date();

            historicoService.CarregarVeiculosSetor($routeParams.CodigoSetor, data.toISOString())
                .then(successCarregarVeiculosDoSetor)
                .catch(errorRequest);
        }

        /**
         * Abre a modal de histórico do setor com a lista de veículos da ultima coleta
         * @param {*} result Result enviado pelo servidor com os dados.
         */
        function successCarregarVeiculosDoSetor(result) {
            // Inicializa variaveis.
            vm.listaVeiculos = result.data;
            vm.pesquisaData = new Date(_setorRealizado.DataExecucao);
            vm.historicoImportado = false;

            // Constroi objeto do form.
            vm.historicoSetor = {
                codigoVeiculo: '',
                dataHoraInicio: null,
                dataHoraFim: null,
                horaInicio: '00:00',
                horaFim: '00:00',
                formatarCampos: function () {
                    let camposFormatados = {
                        codigoVeiculo: this.codigoVeiculo,
                        dataHoraInicio: new Date(this.dataHoraInicio),
                        dataHoraFim: new Date(this.dataHoraFim),
                    };

                    camposFormatados.dataHoraInicio.setHours(this.horaInicio.split(':')[0]);
                    camposFormatados.dataHoraInicio.setMinutes(this.horaInicio.split(':')[1]);
                    camposFormatados.dataHoraFim.setHours(this.horaFim.split(':')[0]);
                    camposFormatados.dataHoraFim.setMinutes(this.horaFim.split(':')[1]);

                    camposFormatados.dataHoraInicio = camposFormatados.dataHoraInicio.toISOString();
                    camposFormatados.dataHoraFim = camposFormatados.dataHoraFim.toISOString();

                    return camposFormatados;
                }
            };

            // Abre modal do importar historico.
            vm.openModal('Importar histórico de Coleta no Setor', __env.appPath + 'scripts/Etapa01/modais/importar-historico-setor.partial.html', fecharModalImportarHistoricoSetor)
                .then(() => {
                    vm.validationFormImportarHistoricoSetor = new FormValidation(vm.formImportarHistoricoSetor);
                    vm.validationFormImportarHistoricoSetor.setControlsValidation(vm.validateTimeInterval);
                    vm.modalOpen = true;
                });
        }

        /**
         * Consulta os veiculos do Setor.
         * @param data {Date}
         */
        function carregarVeiculosSetorPorData(data) {
            if (!data) return;
            historicoService.CarregarVeiculosSetor($routeParams.CodigoSetor, data.toISOString()).then((result) => {
                if (result.data.length !== 0) vm.listaVeiculos = result.data;
                else {
                    vm.listaVeiculos = null;
                    ngNotify.set('Nenhum histórico encontrado para a data selecionada', {
                        target: '#modalNotificationOuter',
                        type: 'warn',
                        sticky: false
                    });
                }
                vm.historicoSetor.codigoVeiculo = null;
            }).catch(errorRequest)
        }

        /**
         * Busca as datas inicial e final do apontamento de macro do veículo
         * @param veiculoSelecionado
         */
        function setarDataLimiteImportacaoSetor(veiculoSelecionado) {
            vm.veiculoSelecionado = veiculoSelecionado;

            vm.historicoSetor.dataHoraInicio = new Date(veiculoSelecionado.InicioColeta);
            vm.historicoSetor.dataHoraFim = new Date(veiculoSelecionado.FimColeta);
            vm.historicoSetor.horaInicio = new Date(veiculoSelecionado.InicioColeta).getFullTimeString();
            vm.historicoSetor.horaFim = new Date(veiculoSelecionado.FimColeta).getFullTimeString();
        }

        /**
         * Fecha a modal de importar historico do setor.
         */
        function fecharModalImportarHistoricoSetor() {
            vm.modalOpen = false;
            vm.closeModal().then(() => {
                vm.validationFormImportarHistoricoSetor.resetControlsValidation();
                vm.historicoSetor = {};
            })
        }

        /**
         * Importa historico por setor.
         */
        function importarHistoricoSetor(validarHistoricoImportado) {
            vm.setFormStatus(vm.formImportarHistoricoSetor, 'SENDING').then(() => {
                let obj = vm.historicoSetor.formatarCampos();

                if (validarHistoricoImportado)
                    vm.historicoImportado = ferramentaImportarHistorico.verificaHistoricoImportado(obj.codigoVeiculo, obj.dataHoraInicio, obj.dataHoraFim);

                if (vm.voltarAcao && !vm.undo) vm.historicoImportado = false;
                if (!vm.historicoImportado || !validarHistoricoImportado) {
                    ferramentaImportarHistorico.importarHistorico(obj.codigoVeiculo, obj.dataHoraInicio, obj.dataHoraFim)
                        .then((result) => {
                            if (result.data) {
                                vm.setFormStatus(vm.formImportarHistoricoSetor, 'SEND_SUCCESS').then(() => {
                                    fecharModalImportarHistoricoSetor();
                                    ngNotify.set('Histórico importado com sucesso', { type: 'success', sticky: false });
                                    vm.RotaObservable.notify('enable');
                                })
                            } else {
                                vm.setFormStatus(vm.formImportarHistoricoSetor, null).then(() => {
                                    ngNotify.set('Nenhum histórico encontrado para o período selecionado', { target: '#modalNotificationOuter', type: 'warn', sticky: false });
                                })
                            }
                        })
                        .catch((error) => {
                            vm.setFormStatus(vm.formImportarHistoricoSetor, 'SEND_FAIL').then(() => {
                                fecharModalImportarHistoricoSetor();
                                ngNotify.set(error.statusText, { type: 'error', sticky: true, button: true });
                            });
                        });
                } else {
                    vm.setFormStatus(vm.formImportarHistoricoSetor, null);
                }
            });
        }

        // -------------------------- Importar Historico de Coleta do veiculo
        /**
         * Abre a modal de importar historico de Veiculo.
         */
        function abrirModalImportarHistoricoVeiculo() {

            // Efetua consulta do veiculos do Setor.
            historicoService.CarregarTodosVeiculos()
                .then(successCarregarTodosVeiculos)
                .catch(errorRequest);
        }

        /**
         * Abre a modal de histórico dos veículos apresentando todos os mesmos
         * @param {*} result Result enviado pelo servidor com os dados.
         */
        function successCarregarTodosVeiculos(result) {
            // Inicializa variaveis.
            vm.listaVeiculos = result.data;
            vm.historicoImportado = false;

            // Constroi objeto do form.
            vm.historicoVeiculo = {
                codigoVeiculo: '',
                dataHoraInicio: null,
                dataHoraFim: null,
                horaInicio: '00:00',
                horaFim: '00:00',
                formatarCampos: function () {

                    let camposFormatados = {
                        codigoVeiculo: this.codigoVeiculo,
                        dataHoraInicio: new Date(this.dataHoraInicio),
                        dataHoraFim: new Date(this.dataHoraFim),
                    };

                    camposFormatados.dataHoraInicio.setHours(this.horaInicio.split(':')[0]);
                    camposFormatados.dataHoraInicio.setMinutes(this.horaInicio.split(':')[1]);
                    camposFormatados.dataHoraFim.setHours(this.horaFim.split(':')[0]);
                    camposFormatados.dataHoraFim.setMinutes(this.horaFim.split(':')[1]);

                    camposFormatados.dataHoraInicio = camposFormatados.dataHoraInicio.toISOString();
                    camposFormatados.dataHoraFim = camposFormatados.dataHoraFim.toISOString();

                    return camposFormatados;
                }
            };

            // Abre modal do importar historico.
            vm.openModal('Importar Histórico do Veículo', __env.appPath + 'scripts/Etapa01/modais/importar-historico-veiculo.partial.html', fecharModalImportarHistoricoVeiculo)
                .then(() => {
                    vm.validationFormImportarHistoricoVeiculo = new FormValidation(vm.formImportarHistoricoVeiculo);
                    vm.validationFormImportarHistoricoVeiculo.setControlsValidation(vm.validateTimeInterval);
                    vm.modalOpen = true
                });
        }

        /**
         * Busca as datas inicial e final do apontamento de macro do veículo
         * @param veiculoSelecionado
         */
        function setarDataLimiteImportacaoVeiculo(veiculoSelecionado) {
            vm.veiculoSelecionado = veiculoSelecionado;

            vm.historicoVeiculo.dataHoraInicio = new Date(veiculoSelecionado.InicioColeta);
            vm.historicoVeiculo.dataHoraFim = new Date(veiculoSelecionado.FimColeta);
            vm.historicoVeiculo.horaInicio = new Date(veiculoSelecionado.InicioColeta).toLocaleTimeString();
            vm.historicoVeiculo.horaFim = new Date(veiculoSelecionado.FimColeta).toLocaleTimeString();
        }

        /**
         * Fecha a modal de importar historico do setor
         */
        function fecharModalImportarHistoricoVeiculo() {
            vm.modalOpen = false;
            vm.closeModal().then(() => {
                vm.validationFormImportarHistoricoVeiculo.resetControlsValidation();
                vm.historicoVeiculo = {};
            })
        }

        /**
         * Importa o histórico por veículo
         */
        function importarHistoricoVeiculo(validarHistoricoImportado) {
            vm.setFormStatus(vm.formImportarHistoricoVeiculo, 'SENDING').then(() => {
                let obj = vm.historicoVeiculo.formatarCampos();

                if (validarHistoricoImportado)
                    vm.historicoImportado = ferramentaImportarHistorico.verificaHistoricoImportado(obj.codigoVeiculo, obj.dataHoraInicio, obj.dataHoraFim);

                if (!vm.historicoImportado || !validarHistoricoImportado) {
                    ferramentaImportarHistorico.importarHistorico(obj.codigoVeiculo, obj.dataHoraInicio, obj.dataHoraFim).then((result) => {
                        if (result.data) {
                            vm.setFormStatus(vm.formImportarHistoricoVeiculo, 'SEND_SUCCESS').then(() => {
                                fecharModalImportarHistoricoVeiculo();
                                ngNotify.set('Histórico importado com sucesso', { type: 'success', sticky: false });
                                vm.RotaObservable.notify('enable')
                            })
                        } else {
                            vm.setFormStatus(vm.formImportarHistoricoVeiculo, null).then(() => {
                                ngNotify.set('Nenhum histórico encontrado para o período selecionado', { target: '#modalNotificationOuter', type: 'warn', sticky: true, button: true });
                            })
                        }
                    }).catch((error) => {
                        vm.setFormStatus(vm.formImportarHistoricoVeiculo, 'SEND_FAIL').then(() => {
                            fecharModalImportarHistoricoVeiculo();
                            ngNotify.set(error.message, { type: 'warn', sticky: false });
                        });
                    })
                } else {
                    vm.setFormStatus(vm.formImportarHistoricoVeiculo, null);
                }
            });
        }

        //---------------------------------------
        function errorRequest(error) {
            ngNotify.set(error.message, { type: 'error', sticky: true, button: true });
            console.error(error);
        }
    }
})();
