function ModuloEdicaoRD(data) {
    let mSelf = this;
    mSelf.Titulo = data.Titulo;
    mSelf.ModuloId = data.ModuloId;
    mSelf.Template = data.Template;
    mSelf.Data = ko.observable(new ModuloEdicaoRdData());
    mSelf.Init = () => mSelf.Data().Init()
}

function ModuloEdicaoRdData() {
    let mSelf = this;

    mSelf.RDEmEdicao = ko.observable(false);
    mSelf.DadosOperacao = ko.observable(null);
    mSelf.IdProximo = ko.observable(1);
    mSelf.ListaFuncoes = ko.observableArray([]);
    mSelf.OpcoesFuncoes = ko.observableArray([]);
    mSelf.ApontamentosRD = ko.observable(null);
    mSelf.ModelosRdsDisponiveis = ko.observableArray(null);

    mSelf.CarregarRDEdicao = null;
    mSelf.Configuracoes = null;
    mSelf.Historicos = ko.observableArray([]);

    mSelf.Init = () => {
        $('.loading-div-edicao').fadeIn();

        mSelf.DadosOperacao(new DadosOperacao(mSelf));
        mSelf.DadosOperacao().Init();

        mSelf.ApontamentosRD(new ApontamentosRD(mSelf));
        mSelf.ApontamentosRD().Init();

        ScriptHomologado();
        mSelf.CarregarRD();

        mSelf.ListarModelos();

        jQuery(document).ready(($) => {
            if (window.history && window.history.pushState) {
                window.history.pushState('forward', null, '');
                $(window).on('popstate', () => mSelf.Cancelar());
            }
        });
    };

    mSelf.CarregarConfiguracao = (codigoMacro, callback) => {
        params = {
            codigoMacro: codigoMacro
        };
        $.ajax({
            url: `${urlGlobal}EditorRD/EditorRD/CarregarConfiguracoes`,
            dataType: 'json',
            type: 'GET',
            data: ko.toJS(params),
            success: (data) => {
                mSelf.Configuracoes = data;
                if (callback)
                    callback();
                if (!mSelf.Configuracoes || mSelf.Configuracoes.length == 0) {
                    vm.Perspectiva.AbrirConfirmacao('Alguns campos não foram configurados para essa macro. Por favor, entre em contato com consultor.',
                        () => vm.ShowMensagemAlerta('Entre em contato com o consultor!'), null, 'Ok, Entendi!', true);
                }
            }
        });
    };

    mSelf.CarregarPeriodoSetor = (codigoOperacao, codigoSetor, codigoRegional) => {
        params = {
            codigoOperacao: codigoOperacao,
            setor: codigoSetor,
            regional: codigoRegional
        };
        $.ajax({
            url: `${urlGlobal}EditorRD/EditorRD/CarregarPeriodoSetor`,
            dataType: 'json',
            type: 'GET',
            data: ko.toJS(params),
            success: (data) => {
                mSelf.DadosOperacao().Turno(data.Descricao);
                mSelf.DadosOperacao().CodigoTurno(data.Codigo);
            },
            error: () => mSelf.DadosOperacao().Turno('Turno não encontrado')
        });
    };

    mSelf.CarregarPeriodoSetorRealizado = (codigoOperacao, codigoSetorRealizado) => {
        params = {
            codigoOperacao: codigoOperacao,
            codigoSetorRealizado: codigoSetorRealizado
        };
        $.ajax({
            url: `${urlGlobal}EditorRD/EditorRD/CarregarPeriodoSetorRealizado`,
            dataType: 'json',
            type: 'GET',
            data: ko.toJS(params),
            success: (data) => {
                mSelf.DadosOperacao().Turno(data.Descricao);
                mSelf.DadosOperacao().CodigoTurno(data.Codigo);
            },
            error: () => mSelf.DadosOperacao().Turno('Turno não encontrado')
        });
    }

    mSelf.CarregarRD = () => {
        if (vm.Codigo > 0 && vm.Origem > 0) {
            params = {
                codigo: vm.Codigo,
                origem: vm.Origem
            };
            $.ajax({
                url: `${urlGlobal}EditorRD/EditorRD/ValidarRD`,
                dataType: 'json',
                type: 'GET',
                data: ko.toJS(params),
                beforeSend: () => $('.loading-div').fadeIn(),
                success: (result) => {
                    if (result.Validado)
                        $.ajax({
                            url: `${urlGlobal}EditorRD/EditorRD/CarregarEdicaoRD`,
                            dataType: 'json',
                            type: 'GET',
                            data: ko.toJS(params),
                            success: (data) => {
                                mSelf.CarregarConfiguracao(data.DadosOperacao.Macro.Codigo, () => {
                                    mSelf.CarregarRDEdicao = new CarregarRDEdicao(mSelf, data);
                                    mSelf.CarregarHistoricoRD();
                                });
                            },
                            error: () => { }
                        });
                    else window.open(`${urlGlobal}EditorRD/EditorRD/EdicaoRD?codigo=${vm.Codigo}&origem=${result.Origem}`, '_self', false);
                },
                error: () => $('.loading-div').fadeOut()
            });

        } else {
            $('.loading-div-edicao').fadeOut();
        }
    };

    mSelf.VisualizacaoRD = () => {
        let origem = vm.Origem;
        if (origem == 1)
            origem = 3;

        window.open(`${urlGlobal}EditorRD/EditorRD/VisualizarRD?codigo=${vm.Codigo}&origem=${origem}`, '_self', false);
    };

    mSelf.VoltarPaginaInicial = () => window.open(`${urlGlobal}EditorRD`, '_self', false);

    mSelf.PaginaNovoModeloRd = () => window.open(`${urlGlobal}EditorRD/EditorRD/CadastroModeloRD`, '_self', false);

    mSelf.ConfirmacaoSairEdicao = (tipo) => {
        let redirect = tipo === 'modelo' ? mSelf.PaginaNovoModeloRd : mSelf.VoltarPaginaInicial;
        vm.Perspectiva.AbrirConfirmacao('Deseja sair sem salvar os dados?', redirect, null);
    }

    mSelf.ListarModelos = (evt) => {
        let params = {
            take: 10,
            skip: 0,
            useTakeSkip: false
        };

        $.ajax({
            url: `${urlGlobal}/EditorRD/EditorRD/CarregarGridModelos`,
            dataType: 'json',
            type: 'GET',
            data: params,
            beforeSend: () => $('.loading-div').fadeIn(),
            success: (data) => {
                mSelf.ModelosRdsDisponiveis(data.Grid.Data);
                RegistrarCombobox('select-modelo');
            },
            error: (err) => console.log(err),
            complete: () => $('.loading-div').fadeOut()
        });
    };


    mSelf.CarregarModelo = (data) => {
        mSelf.ListaFuncoes.removeAll();

        params = {
            codigo: data.Codigo
        };

        $.ajax({
            url: `${urlGlobal}EditorRD/EditorRD/CarregarModelo`,
            dataType: 'json',
            type: 'GET',
            data: ko.toJS(params),
            beforeSend: () => $('.loading-div').fadeIn(),
            success: (data) => {
                mSelf.DadosOperacao().RDModelo(true);

                mSelf.CarregarConfiguracao(data.DadosOperacao.Macro.Codigo, () => {
                    mSelf.CarregarModeloRD = new CarregarModeloRD(mSelf, data);
                });
            },
            error: (erro) => console.log(erro),
            complete: () => $('.loading-div').fadeOut()
        });
    };

    mSelf.AdicionarFuncao = (data, evt, top) => {
        if (!$(evt.target).hasClass('disabled-plus-bnt')) {

            if (top) {
                mSelf.ListaFuncoes.splice(0, 0, {
                    Id: mSelf.IdProximo(),
                    NomeFuncao: 'SELECIONE',
                    CodigoMacroFuncao: 0,
                    Posicao: 0,
                    ListaApontamentos: ko.observableArray([]),
                    IdProximo: 1,
                    OpcoesApontamentos: [],
                    Visivel: ko.observable(false)
                });

            } else {
                let i = mSelf.ListaFuncoes.indexOf(data) + 1;
                mSelf.ListaFuncoes.splice(i, 0, {
                    Id: mSelf.IdProximo(),
                    NomeFuncao: 'SELECIONE',
                    CodigoMacroFuncao: 0,
                    Posicao: 0,
                    ListaApontamentos: ko.observableArray([]),
                    IdProximo: 1,
                    OpcoesApontamentos: [],
                    Visivel: ko.observable(false)
                });
            }
            RegistrarCombobox(`ComboFuncao${mSelf.IdProximo()}`);

            mSelf.IdProximo(mSelf.IdProximo() + 1);
        }
    };

    mSelf.ExcluirFuncao = (data) => mSelf.ListaFuncoes.remove(data);

    mSelf.ConfirmacaoExcluirFuncao = (data, evt) => {
        let msg = data.ListaApontamentos().length > 0 ? `Tem certeza que deseja excluir a função ${data.NomeFuncao} e os seus apontamentos?` :
            `Tem certeza que deseja excluir a função ${data.NomeFuncao}?`;

        vm.Perspectiva.AbrirConfirmacao(msg, mSelf.ExcluirFuncao, data);
    }

    mSelf.SelecionarFuncao = (data, evt, obj) => {
        obj.NomeFuncao = data.Descricao || data.NomeFuncao;
        obj.CodigoMacroFuncao = data.Codigo || data.CodigoMacroFuncao;
        obj.Posicao = data.Posicao;
        obj.Visivel(true);

        mSelf.ApontamentosRD().CarregarApontamentos(mSelf.DadosOperacao().MacroSelecionada().Codigo, obj.Posicao, obj);
    };

    mSelf.RecuperarRdOriginal = () => vm.Perspectiva.AbrirConfirmacao('Deseja apagar esta RD e recuperar a RD Original?', mSelf.AcaoRecuperarRdOriginal, null);

    mSelf.AcaoRecuperarRdOriginal = (codigoSetorManual) => {
        if (vm.Origem == 2) //Caso a origem seja de uma RD Manual
            mSelf.AcaoRecuperarRdOriginalManual();
        else
            mSelf.AcaoRecuperarRdOriginalAutomatica();
    };

    mSelf.AcaoRecuperarRdOriginalManual = () => {
        let param = {
            codigoSetorManual: mSelf.CodigoRDManual()
        };

        $.ajax({
            url: `${urlGlobal}EditorRD/EditorRD/RecuperarRdOriginalManual`,
            contentType: 'application/json; charset=utf-8',
            dataType: 'json',
            type: 'POST',
            data: JSON.stringify(param),
            beforeSend: () => $('.loading-div').fadeIn(),
            success: (ret) => {
                if (ret.IsSucesso) {
                    window.location.href = `${urlGlobal}EditorRD/EditorRD/VisualizarRD?codigo=${vm.Codigo}&origem=${vm.Origem}`;
                    localStorage.setItem('MostrarMsgRecuperacaoRd', 'RD recuperada com sucesso!');
                } else {
                    $('.loading-div').fadeOut();
                    vm.ShowMensagemErro(rest.Resposta);
                }
            },
            complete: () => { }
        }).done(() => { });
    };

    mSelf.AcaoRecuperarRdOriginalAutomatica = () => {
        let param = {
            codigoSetorRealizado: vm.Codigo
        };

        $.ajax({
            url: `${urlGlobal}EditorRD/EditorRD/RecuperarRdOriginalAutomatica`,
            contentType: 'application/json; charset=utf-8',
            dataType: 'json',
            type: 'POST',
            data: JSON.stringify(param),
            beforeSend: () => $('.loading-div').fadeIn(),
            success: (ret) => {
                if (ret.IsSucesso)
                    window.location.href = `${urlGlobal}EditorRD/EditorRD/VisualizarRD?codigo=${vm.Codigo}&origem=1`;
                else {
                    $('.loading-div').fadeOut();
                    vm.ShowMensagemErro(rest.Resposta);
                }
            },
            complete: () => { }
        }).done(() => { });
    };

    mSelf.CodigoSetorRealizado = ko.observable(null);
    mSelf.CodigoRDManual = ko.observable(null);
    mSelf.Homologado = ko.observable(false);

    mSelf.ClickHomologado = (bool) => mSelf.Homologado(bool);

    mSelf.Salvar = () => {
        vm.FecharTodosMensagemAlerta();
        ko.utils.arrayForEach(mSelf.ListaFuncoes(), (f) => {
            ko.utils.arrayForEach(f.ListaApontamentos(), (a) => mSelf.ApontamentosRD().SalvarEdicao(a, null, f));
        });

        let emEdicao = false,
            contemApontamentos = false;

        ko.utils.arrayForEach(mSelf.ListaFuncoes(), (f) => {
            ko.utils.arrayForEach(f.ListaApontamentos(), (a) => {
                contemApontamentos = true;
                if (a.RDEmEdicao() || a.RDEmEdicaoValidacao.Hodometro() || a.RDEmEdicaoValidacao.Horimetro() || a.RDEmEdicaoValidacao.DataHora())
                    emEdicao = true;
            });
        });

        if (!contemApontamentos) {
            vm.ShowMensagemAlerta('RD não contem apontamentos, não é possivel salvar!');
            return;
        }
        if (emEdicao) {
            vm.ShowMensagemAlerta('Informe os campos obrigatórios para essa RD');
            return;
        }

        let macro = mSelf.DadosOperacao().MacroSelecionada();
        let operacao = mSelf.DadosOperacao().OperacoesSelecionada();
        let veiculo = mSelf.DadosOperacao().VeiculoSelecionada();
        let codigoSetorRealizado = mSelf.CodigoSetorRealizado();
        let codigoRDManual = mSelf.CodigoRDManual();
        let controle = mSelf.DadosOperacao().ControleValue();
        let dataExecucao = mSelf.DadosOperacao().DataExecucao();
        let turno = mSelf.DadosOperacao().Turno();
        let codigoTurno = mSelf.DadosOperacao().CodigoTurno();
        let homologado = mSelf.Homologado();

        if (veiculo == 'Selecione' || !dataExecucao) {
            vm.ShowMensagemAlerta('Informe os campos obrigatórios para essa RD');

            if (veiculo == 'Selecione') {
                $('#ComboVeiculo').find('.sel-val').addClass('linha-vermelha');
                $('.name-search').addClass('linha-vermelha');
            }
            if (!dataExecucao)
                $('#dataExecucao').addClass('linha-vermelha');
            return;
        }

        let rd = {
            Codigo: codigoRDManual,
            CodigoSetorRealizado: codigoSetorRealizado,
            CodigoVeiculo: veiculo.Codigo,
            Controle: controle,
            DataExecucao: dataExecucao,
            Homologado: homologado ? 1 : 0,
            CodigoMacro: macro.Codigo,
            MacroDescricao: macro.Descricao,
            CodigoOperacao: operacao.Codigo,
            Turno: turno,
            CodigoTurno: codigoTurno,
            ListaApontamentos: [],
        };

        vm.CodigoVeiculo = veiculo.Codigo;
        vm.Origem = codigoSetorRealizado ? 3 : 2;

        ko.utils.arrayForEach(mSelf.ListaFuncoes(), (f) => {
            let funcao = f;
            ko.utils.arrayForEach(f.ListaApontamentos(), (a) => {
                let apontamento = {
                    CodigoSetorManual: codigoRDManual,
                    CodigoMacroArvore: a.Codigo,

                    DataHoraApontamento: `${a.Data()}T${a.Hora()}`,
                    Hodometro: a.Hodometro().toString().replace('.', ','),
                    HorimetroFormatado: a.Horimetro(),

                    MacroDescricaoCampo: a.Campo,
                    MacroPosicaoCampo: a.Posicao,
                    MacroStatusCampo: a.Status,

                    CodigoMacroFuncao: funcao.CodigoMacroFuncao,
                    NomeMacroFuncao: funcao.NomeFuncao,
                    PosicaoMacroFuncao: funcao.Posicao,

                    CodigoMacroArvorePai: parseInt(`${f.Id}${a.Index}`),
                    Agrupamento: parseInt(`${f.Id}${a.Index}`)
                };

                if (a.ValorValido()) {
                    const valorValido = a.ValorValidoSelecionado();
                    apontamento.CodigoValorValido = valorValido.Codigo;
                    apontamento.ValorValidoDescricao = valorValido.Descricao;
                    apontamento.ValorValidoPosicaoCampo = valorValido.Posicao;
                    apontamento.ValorValidoStatus = valorValido.Status;
                    apontamento.Valor = valorValido.Valor;
                } else {
                    apontamento.Valor = a.Valor().trim();
                }

                rd.ListaApontamentos.push(apontamento);
            });
        });

        let Pai = 0,
            Index = -1;
        ko.utils.arrayForEach(rd.ListaApontamentos, (item) => {
            if (Index != item.CodigoMacroArvorePai) {
                Index = item.CodigoMacroArvorePai;
                Pai = item.CodigoMacroArvore;
                item.CodigoMacroArvorePai = null;
            } else {
                item.CodigoMacroArvorePai = Pai;
            }
        });

        $.ajax({
            url: `${urlGlobal}EditorRD/EditorRD/SalvarRD`,
            contentType: 'application/json; charset=utf-8',
            dataType: 'json',
            type: 'POST',
            data: JSON.stringify(rd),
            beforeSend: () => $('.loading-div').fadeIn(),
            success: (ret) => {
                vm.FecharTodosMensagemAlerta();
                if (!ret.IsSucesso) {
                    vm.ShowMensagemAlerta(ret.Resposta);
                    $('.loading-div').fadeOut();
                } else {
                    localStorage.setItem('MostrarMsgRd', true);
                    if (codigoRDManual == null && codigoSetorRealizado == null)
                        localStorage.setItem('MsgRD', 'RD adicionada com sucesso!');
                    else
                        localStorage.setItem('MsgRD', 'RD alterada com sucesso!');
                    
                    let rd = JSON.parse(ret.Resposta);
                    if (rd){
                        var isRdManual = rd.DataHoraInsercao === rd.SetorRealizado.DataHoraInsercao;
                        vm.Codigo = isRdManual ? rd.Codigo : rd.CodigoSetorRealizado;
                        vm.Origem = isRdManual ? 2 : vm.Origem;
                    }

                    mSelf.VisualizacaoRD();
                }
            },
            error: (erro) => console.log(erro),
            complete: (obj) => console.log(obj)
        });
    };

    mSelf.CarregarHistoricoRD = () => {

        if (vm.Origem == 1) { //Caso a origem seja de uma RD Automatica
            let params = {
                codigoSetorRealizado: mSelf.CodigoSetorRealizado()
            };

            $.ajax({
                url: `${urlGlobal}EditorRD/EditorRD/CarregarHistoricoRDAutomatica`,
                dataType: 'json',
                type: 'GET',
                data: ko.toJS(params),
                success: (data) => {
                    if (data) {
                        for (let index in data) {
                            let item = ko.mapping.fromJS(data[index]);
                            mSelf.Historicos.push(item);
                        }
                    }
                },
                error: () => { }
            });
        } else {
            let params = {
                codigoSetorManual: mSelf.CodigoRDManual()
            };

            $.ajax({
                url: `${urlGlobal}EditorRD/EditorRD/CarregarHistoricoRD`,
                dataType: 'json',
                type: 'GET',
                data: ko.toJS(params),
                success: (data) => {
                    if (data) {
                        for (let index in data) {
                            let item = ko.mapping.fromJS(data[index]);
                            mSelf.Historicos.push(item);
                        }
                    }
                },
                error: () => { }
            });
        }
    };

    mSelf.VisualizarRdOriginal = (data, evt) => {
        if (vm.Origem == 3)
            vm.Origem = 1;

        window.open(`${urlGlobal}EditorRD/EditorRD/RDOriginal?codigo=${vm.Codigo}&origem=${vm.Origem}`);
    };

    mSelf.Cancelar = () => vm.Perspectiva.AbrirConfirmacao('Deseja realmente cancelar sem salvar os dados?', mSelf.CancelarEvent, null);

    mSelf.CancelarEvent = () => {
        if (mSelf.RDEmEdicao())
            window.open(`${urlGlobal}EditorRD/EditorRD/VisualizarRD?codigo=${vm.Codigo}&origem=${vm.Origem}`, '_self', false);
        else
            mSelf.VoltarPaginaInicial();
    };
}