$('#tutorial').on('click', function () {
  $(document).ready(async function () {
    const driver = new Driver({
      doneBtnText: 'Sair',
      closeBtnText: 'Fechar',
      nextBtnText: 'Próximo',
      prevBtnText: 'Anterior',
      allowClose: false
    })
    driver.defineSteps([
      {
        element: "#stepForm1",
        popover: {
          title: "Capa",
          description:
            "Aqui se encontram os campos da capa.",
          position: "bottom",
        },
      },
      {
        element: '#stepForm2',
        popover: {
          title: 'Campos Processos',
          description: 'Aqui se encontram os campos dos processos.',
          position: 'top'
        }
      },
      {
        element: '#stepForm3',
        popover: {
          title: 'Botões Processos',
          description: 'Aqui se encontram os botões de manutenção dos processos.',
          position: 'top'
        }
      },
      {
        element: '#divTabelaProcessos',
        popover: {
          title: 'Processos',
          description: 'Aqui se encontram os processos.',
          position: 'top'
        }
      },
      {
        element: '#btnVoltar',
        popover: {
          title: 'Voltar',
          description: 'Aqui está o botão para voltar à consulta.',
          position: 'bottom'
        }
      },
      {
        element: '#btnGravar',
        popover: {
          title: 'Gravar',
          description: 'Aqui está o botão para gravar as informações.',
          position: 'bottom'
        }
      }
    ])
    driver.start()
  })
})

$(document).ready(async function () {
  const url = window.location.href
  const id = url.split('/')[url.split('/').length - 1]

  if (id && id !== 'create') {
    carregarCadastro(id)
    desabilitarCamposChaves()
  } else {
    criarTabelaProcessos([])
    criarTabelaGrupos([])
  }

  function desabilitarCamposChaves() {
    $('#txtCadastro').prop('disabled', true)
    $('#txtCodigoProduto').prop('disabled', true)
    $('#btnCodigoProduto').prop('disabled', true)
    $('#btnLimpaCodigoProduto').prop('disabled', true)
    $('#txtParte').prop('disabled', true)
    $('#btnParte').prop('disabled', true)
    $('#btnLimpaParte').prop('disabled', true)
  }

  $('.quatroCasasDecimaisQuantityFormat').maskMoney({
    decimal: ".",
    thousands: "",
    precision: 4,
  })

  $('.duasCasasDecimaisCurrencyFormat').maskMoney({
    decimal: ",",
    thousands: "",
    precision: 2,
  })

  $('.quatroCasasDecimaisCurrencyFormat').maskMoney({
    decimal: ",",
    thousands: "",
    precision: 4,
  })

  componenteFiltro('parte', false, false)
  componenteFiltro('cor', false, false)
  componenteFiltro('maquina', false, false, 'MaquinaProcessos')
  componenteFiltro('material', false, false, 'MaterialProcessos')

  setTimeout(
    () => $('#txtCodigoProduto').focus(),
    100
  )

  $('#btnCodigoProduto').pesquisa_serverside(['#txtCodigoProduto', '#txtDescricaoProduto'], ['CODIGO', 'DESCRICAO'], ['DESCRICAO', 'DESCRICAO'], '{"tabela":"PRODUTO", "camposSelect":[ "CODIGO", "DESCRICAO" ], "where": null}', 'Pesquisa Produto', undefined, [true, true])
  $('#btnLimpaCodigoProduto').on('click', function () {
    $('#txtCodigoProduto').val('')
    $('#txtDescricaoProduto').val('')
  })

  $('#txtOperacaoProcessos').autocompleta(
    1,
    `JSON={ "tabela":"OPERACAO", "camposSelect":[ "CODIGO CHAVE", "DESCRICAO DESCRICAO"], "where": null}`,
    undefined,
    undefined,
    undefined,
    carregarDadosOperacao,
  )
  $('#btnOperacaoProcessos').pesquisa(
    '#txtOperacaoProcessos',
    'CODIGO',
    'DESCRICAO',
    `/sisplan/funcoes/v1/pesquisa?JSON={ "tabela":"OPERACAO", "camposSelect":[ "CODIGO", "DESCRICAO"], "where": null}`,
    "Pesquisa Operação",
    "OPERACAO",
    undefined,
    carregarDadosOperacao
  )
  $('#btnLimpaOperacaoProcessos').on('click', function () {
    $('#txtOperacaoProcessos').val('')
    $('#txtGrupoProcessos').val('')
    $('#txtMaquinaProcessos').val('')
    $('#txtComplementoProcessos').val('')
    $('#txtObservacaoProcessos').val('')
    $('#txtTempoTotalProcessos').val('')
    $('#txtParteProcessos').val('')
  })

  function carregarDadosOperacao() {
    setTimeout(() => {
      const chave = pegaChave('#txtOperacaoProcessos')
      buscarDadosOperacao(chave).then((data) => {
        if (data) preencherDadosOperacao(data)
      }).catch((error) => {
        console.error(error)
        msgErro('Ocorreu um erro ao buscar os dados da operação.')
      })
    }, 0)
  }

  async function buscarDadosOperacao(chave) {
    const response = await requisicao("GET", `/sisplan/sequenciaoperacional/v1/retornardadosoperacao?`, `&CHAVE=${chave}`, '', 3600000)

    const json = await response.json()

    if (json) {
      const { resultado, mensagem } = json
      if (mensagem?.codigo !== 200) {
        throw mensagem?.mensagem
      }

      return resultado
    }
  }

  function preencherDadosOperacao(data) {
    insereValor('#txtGrupoProcessos', data.grupo?.codigo, data.grupo?.descricao)
    insereValor('#txtMaquinaProcessos', data.maquina?.codigo, data.maquina?.descricao)
    insereValor('#txtComplementoProcessos', data.complemento)
    insereValor('#txtObservacaoProcessos', data.observacao)
    insereValor('#txtTempoTotalProcessos', parseFloat(data.tempoTotal).toLocaleString("pt-br", {
      maximumFractionDigits: 4,
      minimumFractionDigits: 4,
    }))
    insereValor('#txtParteProcessos', data.parte)
    insereValor('#txtCustoProcessos', parseFloat(data.grupo?.custo).toLocaleString("pt-br", {
      maximumFractionDigits: 4,
      minimumFractionDigits: 4,
    }))
    insereValor('#txtTempoProcessos', parseFloat(data.tempo).toLocaleString("pt-br", {
      maximumFractionDigits: 4,
      minimumFractionDigits: 4,
    }))
    insereValor('#txtTempoTotalProcessos', parseFloat(data.tempo).toLocaleString("pt-br", {
      maximumFractionDigits: 4,
      minimumFractionDigits: 4,
    }))
    insereValor('#txtTempoOperacaoProcessos', parseFloat(data.tempo).toLocaleString("pt-br", {
      maximumFractionDigits: 4,
      minimumFractionDigits: 4,
    }))
    insereValor('#txtTempoOperacaoCapaProcessos', parseFloat(data.tempo).toLocaleString("pt-br", {
      maximumFractionDigits: 4,
      minimumFractionDigits: 4,
    }))
    insereValor('#txtTempoOriginalProcessos', parseFloat(data.tempo).toLocaleString("pt-br", {
      maximumFractionDigits: 4,
      minimumFractionDigits: 4,
    }))
    insereValor('#txtTempoHoraProcessos', data.tempoHora)
    calcularCustoTotal()
  }

  $('#txtGrupoProcessos').autocompleta(
    1,
    `JSON={ "tabela":"CADFLUXO", "camposSelect":[ "CODIGO CHAVE", "DESCRICAO DESCRICAO"], "where": null}`,
    undefined,
    undefined,
    undefined,
    carregarDadosGrupo,
  )
  $('#btnGrupoProcessos').pesquisa(
    '#txtGrupoProcessos',
    'CODIGO',
    'DESCRICAO',
    `/sisplan/funcoes/v1/pesquisa?JSON={ "tabela":"CADFLUXO", "camposSelect":[ "CODIGO", "DESCRICAO"], "where": null}`,
    "Pesquisa Grupo",
    "CADFLUXO",
    undefined,
    carregarDadosGrupo
  )
  $('#btnLimpaGrupoProcessos').on('click', function () {
    $('#txtGrupoProcessos').val('')
    $('#txtCustoProcessos').val('')
  })

  function carregarDadosGrupo() {
    setTimeout(() => {
      const chave = pegaChave('#txtGrupoProcessos')
      buscarDadosGrupo(chave).then((data) => {
        if (data) preencherDadosGrupo(data)
      }).catch((error) => {
        console.error(error)
        msgErro('Ocorreu um erro ao buscar os dados do grupo.')
      })
    }, 0)
  }

  async function buscarDadosGrupo(chave) {
    const response = await requisicao("GET", `/sisplan/sequenciaoperacional/v1/retornardadosgrupooperacao?`, `&CHAVE=${chave}`, '', 3600000)

    const json = await response.json()

    if (json) {
      const { resultado, mensagem } = json
      if (mensagem?.codigo !== 200) {
        throw mensagem?.mensagem
      }

      return resultado
    }
  }

  function preencherDadosGrupo(data) {
    insereValor('#txtCustoProcessos', parseFloat(data.custo).toLocaleString("pt-br", {
      maximumFractionDigits: 4,
      minimumFractionDigits: 4,
    }))
    calcularCustoTotal()
  }

  $('#stepForm1 input').keydown(function (event) {
    if (event.key === 'Enter' || event.keyCode === 13) {
      event.preventDefault()

      const inputs = $('#stepForm1 input:visible:enabled')
      const nextInput = inputs.eq(inputs.index(this) + 1)

      if (nextInput.length) {
        nextInput.focus()
      }
    }
  })

  $('#stepForm2 input').keydown(function (event) {
    if (event.key === 'Enter' || event.keyCode === 13) {
      event.preventDefault()

      const inputs = $('#stepForm2 input:visible:enabled')
      const nextInput = inputs.eq(inputs.index(this) + 1)

      if (nextInput.length) {
        nextInput.focus()
      }
    }
  })

  async function carregarCadastro(chave) {
    $.LoadingOverlay('show')
    buscarDadosCadastro(
      chave
    ).then(({ capa, processos, grupos, tabelaGrupos, totais, }) => {
      if (capa) preencherCapa(capa)
      criarTabelaProcessos(processos ?? [])
      criarTabelaGrupos(grupos ?? [])
      if (tabelaGrupos) preencherTabelaGrupos(tabelaGrupos)
      if (totais) preencherTotaisTempos(totais)
    }).catch((error) => {
      console.error(error)
      msgErro('Ocorreu um erro ao carregar os dados.')
    }).finally(() => {
      $.LoadingOverlay('hide')
    })
  }

  async function buscarDadosCadastro(chave) {
    const filtros = {
      id: chave,
    }
    const response = await requisicao("GET", `/sisplan/sequenciaoperacional/v1/retornardadoscadastro?`, `&FILTROS=${JSON.stringify(filtros)}`, '', 3600000)

    const json = await response.json()

    if (json) {
      const { resultado, mensagem } = json
      if (mensagem?.codigo !== 200) {
        throw mensagem?.mensagem
      }

      return resultado
    }
  }

  function preencherCapa(data) {
    insereValor('#txtId', data?.id)
    insereValor('#txtCadastro', String(data?.cadastro).substring(0, 10))
    insereValor('#txtCodigoProduto', data?.produto)
    insereValor('#txtDescricaoProduto', data?.descricao)
    insereValor('#txtParte', data?.parte, data?.descricaoParte)
    insereValor('#txtCor', data?.cor, data?.descricaoCor)
    insereValor('#txtDificuldade', parseFloat(data?.dificuldade ?? 0).toLocaleString("pt-br", {
      maximumFractionDigits: 2,
      minimumFractionDigits: 2,
    }))
    $('#cbPadrao').prop('checked', data?.padrao === 'S')
  }

  function criarTabelaProcessos(data) {
    if ($.fn.DataTable.isDataTable('#tabelaProcessos')) {
      $('#tabelaProcessos').DataTable().destroy()
      $('#tabelaProcessos').empty()
    }

    const columns = [
      {
        data: 'ordem',
        title: 'Ordem',
      },
      {
        data: 'ordemOriginal',
        title: 'Ordem Original',
        visible: false,
      },
      {
        data: 'grupo',
        title: 'Grupo',
      },
      {
        data: 'descricaoGrupo',
        title: 'Descrição Grupo',
      },
      {
        data: 'operacao',
        title: 'Operação',
      },
      {
        data: 'descricaoOperacao',
        title: 'Descrição Operação',
      },
      {
        data: 'maquina',
        title: 'Máquina',
      },
      {
        data: 'descricaoMaquina',
        title: 'Descrição Máquina',
      },
      {
        data: 'dificuldade',
        title: 'Dificuldade',
        render: function (data) {
          if (!data) {
            return parseFloat(0).toLocaleString("pt-br", {
              maximumFractionDigits: 2,
              minimumFractionDigits: 2,
            })
          }
          return parseFloat(data).toLocaleString("pt-br", {
            maximumFractionDigits: 2,
            minimumFractionDigits: 2,
          })
        },
        className: 'text-right',
      },
      {
        data: 'custo',
        title: 'Custo',
        render: function (data) {
          if (!data) {
            return parseFloat(0).toLocaleString("pt-br", {
              maximumFractionDigits: 4,
              minimumFractionDigits: 4,
            })
          }
          return parseFloat(data).toLocaleString("pt-br", {
            maximumFractionDigits: 4,
            minimumFractionDigits: 4,
          })
        },
        className: 'text-right',
      },
      {
        data: 'custoTotal',
        title: 'Custo Total',
        render: function (data) {
          if (!data) {
            return parseFloat(0).toLocaleString("pt-br", {
              maximumFractionDigits: 4,
              minimumFractionDigits: 4,
            })
          }
          return parseFloat(data).toLocaleString("pt-br", {
            maximumFractionDigits: 4,
            minimumFractionDigits: 4,
          })
        },
        className: 'text-right',
      },
      {
        data: 'tempo',
        title: 'Tempo',
        render: function (data) {
          if (!data) {
            return parseFloat(0).toLocaleString("pt-br", {
              maximumFractionDigits: 4,
              minimumFractionDigits: 4,
            })
          }
          return parseFloat(data).toLocaleString("pt-br", {
            maximumFractionDigits: 4,
            minimumFractionDigits: 4,
          })
        },
        className: 'text-right',
      },
      {
        data: 'tempoTotal',
        title: 'Tempo Total',
        render: function (data) {
          if (!data) {
            return parseFloat(0).toLocaleString("pt-br", {
              maximumFractionDigits: 4,
              minimumFractionDigits: 4,
            })
          }
          return parseFloat(data).toLocaleString("pt-br", {
            maximumFractionDigits: 4,
            minimumFractionDigits: 4,
          })
        },
        className: 'text-right',
      },
      {
        data: 'comprimento',
        title: 'Comprimento',
        render: function (data) {
          if (!data) {
            return parseFloat(0).toLocaleString("pt-br", {
              maximumFractionDigits: 4,
              minimumFractionDigits: 4,
            })
          }
          return parseFloat(data).toLocaleString("pt-br", {
            maximumFractionDigits: 4,
            minimumFractionDigits: 4,
          })
        },
        className: 'text-right',
      },
      {
        data: 'tempoOperacao',
        title: 'Tempo Operação',
        render: function (data) {
          if (!data) {
            return parseFloat(0).toLocaleString("pt-br", {
              maximumFractionDigits: 4,
              minimumFractionDigits: 4,
            })
          }
          return parseFloat(data).toLocaleString("pt-br", {
            maximumFractionDigits: 4,
            minimumFractionDigits: 4,
          })
        },
        className: 'text-right',
      },
      {
        data: 'tempoHora',
        title: 'Tempo Hora',
      },
      {
        data: 'tempoOperacaoCapa',
        title: 'Tempo Operação + Capa',
        render: function (data) {
          if (!data) {
            return parseFloat(0).toLocaleString("pt-br", {
              maximumFractionDigits: 4,
              minimumFractionDigits: 4,
            })
          }
          return parseFloat(data).toLocaleString("pt-br", {
            maximumFractionDigits: 4,
            minimumFractionDigits: 4,
          })
        },
        className: 'text-right',
      },
      {
        data: 'indice',
        title: 'Índice',
        render: function (data) {
          if (!data) {
            return parseFloat(0).toLocaleString("pt-br", {
              maximumFractionDigits: 2,
              minimumFractionDigits: 2,
            })
          }
          return parseFloat(data).toLocaleString("pt-br", {
            maximumFractionDigits: 2,
            minimumFractionDigits: 2,
          })
        },
        className: 'text-right',
      },
      {
        data: 'parte',
        title: 'Parte',
      },
      {
        data: 'material',
        title: 'Material',
      },
      {
        data: 'descricaoMaterial',
        title: 'Descrição Material',
      },
      {
        data: 'complemento',
        title: 'Complemento',
      },
      {
        data: 'observacao',
        title: 'Observação',
      },
    ]

    const table = $('#tabelaProcessos').DataTable({
      sort: false,
      paging: false,
      destroy: true,
      lengthChange: false,
      filter: false,
      info: false,
      ordering: false,
      sorting: false,
      order: false,
      autoWidth: true,
      data,
      columns,
      scrollY: true,
      scrollX: true,
      scrollCollapse: true,
      select: {
        style: 'single',
        toggleable: false,
      },
    })
    let selectedRowIndex = 0

    function selectRow(index) {
      const row = table.row(index)
      if (row.node()) {
        table.rows().deselect()
        table.row(index).select()
        selectedRowIndex = index
      }
    }

    $('#tabelaProcessos_wrapper .dataTables_scrollBody').off('wheel')
    $('#tabelaProcessos_wrapper .dataTables_scrollBody').on('wheel', function (event) {
      event.preventDefault()
      if ($('#btnConfirmarProcessos').hasClass('d-none')) {

        const direction = event.originalEvent.deltaY > 0 ? 1 : -1
        const newIndex = selectedRowIndex + direction


        if (newIndex >= 0 && newIndex < table.rows().count()) {
          selectRow(newIndex)


          const rowNode = table.row(newIndex).node()
          $(rowNode).get(0).scrollIntoView({ behavior: 'smooth', block: 'center' })
        }
      }
    })

    table.off('select')
    table.on('select', function (_e, _dt, type, indexes) {
      if (type === 'row') {
        const data = table.rows(indexes[0]).data().toArray()
        selectedRowIndex = indexes[0]
        preencherDadosCamposProcessos(data[0])
      }
    })

    $(document).off('keydown')
    $(document).on('keydown', function (event) {
      if ($('#btnConfirmarProcessos').hasClass('d-none') && (event.key === 'ArrowDown' || event.key === 'ArrowUp')) {
        event.preventDefault()

        const direction = event.key === 'ArrowDown' ? 1 : -1
        const newIndex = selectedRowIndex + direction

        if (newIndex >= 0 && newIndex < table.rows().count()) {
          selectRow(newIndex)
          const rowNode = table.row(newIndex).node()
          $(rowNode).get(0).scrollIntoView({ behavior: 'smooth', block: 'center' })
        }
      }
    })

    selectRow(selectedRowIndex)
    table.columns.adjust().draw(false)
  }

  $('#btnIncluirProcessos').on('click', function () {
    if (!$('#txtCodigoProduto').val()) {
      msgErro('Código do produto não informado, impossível continuar.')
      return
    }
    const datatable = $('#tabelaProcessos').DataTable()
    datatable.rows().deselect()
    limparCamposProcessos()
    habilitarAlteracaoProcessos(datatable)
    setTimeout(
      () => $('#txtOperacaoProcessos').focus(),
      100
    )
  })

  $('#btnAlterarProcessos').on('click', function () {
    iniciarAlteracaoProcessos()
    setTimeout(
      () => $('#txtOperacaoProcessos').focus(),
      100
    )
  })

  $('#btnExcluirProcessos').on('click', function () {
    excluirProcesso()
  })

  $('#btnDesistirProcessos').on('click', function () {
    const datatable = $('#tabelaProcessos').DataTable()
    const [selectedIndex] = datatable.rows({ selected: true }).indexes().toArray()
    desabilitarAlteracaoProcessos()
    if (selectedIndex !== undefined && selectedIndex !== null) {
      datatable.row(selectedIndex).select()
    } else {
      datatable.row(0).select()
    }
  })

  function iniciarAlteracaoProcessos() {
    const datatable = $('#tabelaProcessos').DataTable()
    const selectedIndexes = datatable.rows({ selected: true }).indexes().toArray()
    if (!selectedIndexes || selectedIndexes.length === 0) {
      msgErro('Nenhum registro selecionado, impossível continuar.')
      return
    }
    if (selectedIndexes.length > 1) {
      msgErro('Ocorreu um erro ao alterar, por favor tente novamente.')
      data.row(0).select()
      return
    }
    const [selectedIndex] = selectedIndexes
    const data = datatable.row(selectedIndex).data()
    limparCamposProcessos()
    habilitarAlteracaoProcessos(datatable, data, selectedIndex)
  }

  function excluirProcesso() {
    const datatable = $('#tabelaProcessos').DataTable()
    const selectedIndexes = datatable.rows({ selected: true }).indexes().toArray()
    if (!selectedIndexes || selectedIndexes.length === 0) {
      msgErro('Nenhum registro selecionado, impossível continuar.')
      return
    }
    if (selectedIndexes.length > 1) {
      msgErro('Ocorreu um erro ao alterar, por favor tente novamente.')
      data.row(0).select()
      return
    }
    const [selectedIndex] = selectedIndexes
    datatable.row(selectedIndex).remove().draw(false)
    recalcularOrdemProcessos()
    recalcularGruposTotais()
    datatable.row(selectedIndex).select()
  }

  function limparCamposProcessos() {
    $('.campoProcessos').val('')
    $('#txtOrdemProcessos').val('')
    $('#txtCustoProcessos').val('')
    $('#txtTempoProcessos').val('')
    $('#txtCustoTotalProcessos').val('')
    $('#txtTempoHoraProcessos').val('')
  }

  function habilitarAlteracaoProcessos(datatable, data, selectedIndex) {
    preencherDadosCamposProcessos(data)
    $('.campoProcessos').prop('disabled', false)
    $('.botaoProcessos').prop('disabled', false)
    $('#btnIncluirProcessos').addClass('d-none')
    $('#btnAlterarProcessos').addClass('d-none')
    $('#btnExcluirProcessos').addClass('d-none')
    $('#btnConfirmarProcessos').removeClass('d-none')
    $('#btnDesistirProcessos').removeClass('d-none')
    $('.btnDatatableAlterarProcessos').prop('disabled', true)
    $('#btnSubirOrdemProcessos').addClass('d-none')
    $('#btnDescerOrdemProcessos').addClass('d-none')
    datatable.rows().deselect()
    datatable.select.style('api')
    if (selectedIndex !== undefined && selectedIndex !== null) datatable.row(selectedIndex).select()
  }

  function desabilitarAlteracaoProcessos() {
    $('#tabelaProcessos').DataTable().select.style('single')
    $('.campoProcessos').prop('disabled', true)
    $('.botaoProcessos').prop('disabled', true)
    $('#btnIncluirProcessos').removeClass('d-none')
    $('#btnAlterarProcessos').removeClass('d-none')
    $('#btnExcluirProcessos').removeClass('d-none')
    $('#btnConfirmarProcessos').addClass('d-none')
    $('#btnDesistirProcessos').addClass('d-none')
    $('.btnDatatableAlterarProcessos').prop('disabled', false)
    $('#txtParteProcessos').val('')
    $('#txtTempoTotalProcessos').val('')
    $('#txtTempoTotalProcessos').val('')
    $('#txtTempoOperacaoProcessos').val('')
    $('#txtTempoOperacaoCapaProcessos').val('')
    $('#txtComprimentoProcessos').val('')
    $('#btnSubirOrdemProcessos').removeClass('d-none')
    $('#btnDescerOrdemProcessos').removeClass('d-none')
  }

  function selecionarPrimeiraLinhaTabelaProcessos() {
    $('#tabelaProcessos').DataTable().row(':first', { page: 'current' }).select()
  }

  function selecionarUltimaLinhaTabelaProcessos() {
    const datatable = $('#tabelaProcessos').DataTable()
    datatable.row(':last', { page: 'current' }).select()
    const rowNode = datatable.row(datatable.rows().count() - 1).node()
    $(rowNode).get(0).scrollIntoView({ behavior: 'smooth', block: 'center' })
  }

  function preencherDadosCamposProcessos(data) {
    if (data) {
      insereValor('#txtOrdemProcessos', data.ordem)
      insereValor('#txtOperacaoProcessos', data.operacao, data.descricaoOperacao)
      insereValor('#txtGrupoProcessos', data.grupo, data.descricaoGrupo)
      insereValor('#txtMaquinaProcessos', data.maquina, data.descricaoMaquina)
      insereValor('#txtMaterialProcessos', data.material, data.descricaoMaterial)
      insereValor('#txtComplementoProcessos', data.complemento)
      insereValor('#txtObservacaoProcessos', data.observacao)
      insereValor('#txtDificuldadeProcessos', parseFloat(data.dificuldade ?? 0).toLocaleString("pt-br", {
        maximumFractionDigits: 2,
        minimumFractionDigits: 2,
      }))
      insereValor('#txtComprimentoProcessos', parseFloat(data.comprimento ?? 0).toLocaleString("pt-br", {
        maximumFractionDigits: 4,
        minimumFractionDigits: 4,
      }))
      insereValor('#txtTempoTotalProcessos', parseFloat(data.tempoTotal ?? 0).toLocaleString("pt-br", {
        maximumFractionDigits: 4,
        minimumFractionDigits: 4,
      }))
      insereValor('#txtTempoOperacaoProcessos', parseFloat(data.tempoOperacao ?? 0).toLocaleString("pt-br", {
        maximumFractionDigits: 4,
        minimumFractionDigits: 4,
      }))
      insereValor('#txtTempoOperacaoCapaProcessos', parseFloat(data.tempoOperacaoCapa ?? 0).toLocaleString("pt-br", {
        maximumFractionDigits: 4,
        minimumFractionDigits: 4,
      }))
      insereValor('#txtParteProcessos', data.parte)
      insereValor('#txtIndiceProcessos', parseFloat(data.indice ?? 0).toLocaleString("pt-br", {
        maximumFractionDigits: 2,
        minimumFractionDigits: 2,
      }))
      insereValor('#txtCustoProcessos', parseFloat(data.custo ?? 0).toLocaleString("pt-br", {
        maximumFractionDigits: 4,
        minimumFractionDigits: 4,
      }))
      insereValor('#txtCustoTotalProcessos', parseFloat(data.custoTotal ?? 0).toLocaleString("pt-br", {
        maximumFractionDigits: 4,
        minimumFractionDigits: 4,
      }))
      insereValor('#txtCustoOriginalProcessos', parseFloat(data.custoTotal ?? 0).toLocaleString("pt-br", {
        maximumFractionDigits: 4,
        minimumFractionDigits: 4,
      }))
      insereValor('#txtTempoProcessos', parseFloat(data.tempo ?? 0).toLocaleString("pt-br", {
        maximumFractionDigits: 4,
        minimumFractionDigits: 4,
      }))
      insereValor('#txtTempoHoraProcessos', data.tempoHora)
    } else {
      insereValor('#txtDificuldadeProcessos', parseFloat(100).toLocaleString("pt-br", {
        maximumFractionDigits: 2,
        minimumFractionDigits: 2,
      }))
      insereValor('#txtIndiceProcessos', parseFloat(100).toLocaleString("pt-br", {
        maximumFractionDigits: 2,
        minimumFractionDigits: 2,
      }))
    }
  }

  $('#btnConfirmarProcessos').on('click', function () {
    const processo = retornarNovoProcesso()
    if (!processo.grupo) {
      msgErro('Grupo não informado, impossível continuar.')
      return
    }

    confirmarProcessos(processo)
  })

  function retornarNovoProcesso() {
    const ordem = parseInt($('#txtOrdemProcessos').val())
    const ordemOriginal = ordem
    const grupo = pegaChave('#txtGrupoProcessos')
    const descricaoGrupo = pegaDescricao('#txtGrupoProcessos')
    const operacao = pegaChave('#txtOperacaoProcessos')
    const descricaoOperacao = pegaDescricao('#txtOperacaoProcessos')
    const maquina = pegaChave('#txtMaquinaProcessos')
    const descricaoMaquina = pegaDescricao('#txtMaquinaProcessos')
    const dificuldade = parseFloat(String($('#txtDificuldadeProcessos').val()).replace(',', '.')) || 0
    const custo = parseFloat(String($('#txtCustoProcessos').val()).replace(',', '.')) || 0
    const custoTotal = parseFloat(String($('#txtCustoTotalProcessos').val()).replace(',', '.')) || 0
    const tempo = parseFloat(String($('#txtTempoProcessos').val()).replace(',', '.')) || 0
    const tempoTotal = parseFloat(String($('#txtTempoTotalProcessos').val()).replace(',', '.')) || 0
    const comprimento = parseFloat(String($('#txtComprimentoProcessos').val()).replace(',', '.')) || 0
    const material = pegaChave('#txtMaterialProcessos')
    const descricaoMaterial = pegaDescricao('#txtMaterialProcessos')
    const complemento = $('#txtComplementoProcessos').val()
    const observacao = $('#txtObservacaoProcessos').val()
    const tempoOperacao = parseFloat(String($('#txtTempoOperacaoProcessos').val()).replace(',', '.')) || 0
    const tempoOperacaoCapa = parseFloat(String($('#txtTempoOperacaoCapaProcessos').val()).replace(',', '.')) || 0
    const indice = parseFloat(String($('#txtIndiceProcessos').val()).replace(',', '.')) || 0
    const parte = $('#txtParteProcessos').val()
    const tempoHora = $('#txtTempoHoraProcessos').val()

    return {
      ordem,
      ordemOriginal,
      grupo,
      descricaoGrupo,
      operacao,
      descricaoOperacao,
      maquina,
      descricaoMaquina,
      dificuldade,
      custo,
      custoTotal,
      tempo,
      tempoTotal,
      comprimento,
      material,
      descricaoMaterial,
      complemento,
      observacao,
      tempoOperacao,
      tempoOperacaoCapa,
      indice,
      parte,
      tempoHora,
    }
  }

  function confirmarProcessos(data) {
    try {
      const datatable = $('#tabelaProcessos').DataTable()
      const selectedRow = datatable.rows('.selected')
      const datatableData = datatable.rows().data().toArray()
      const editingRegister = selectedRow.data().toArray()

      if (!editingRegister || editingRegister.length === 0) {
        // if (datatableData.find((item) => item.operacao === data.operacao && item.parte === data.parte && item.grupo === data.grupo)) {
        //   msgErro('Operação já cadastrada no produto, impossível continuar.')
        //   return
        // }

        const currentMaxOrder = datatableData.reduce((max, obj) => {
          return obj.ordem > max ? obj.ordem : max
        }, 0)

        data.ordem = currentMaxOrder + 1

        datatable.row.add(data).draw(false)
        selecionarUltimaLinhaTabelaProcessos()
      } else {
        const [index] = selectedRow.indexes().toArray()
        // const existingRegisterCount = datatableData.filter((item, i) => item.operacao === data.operacao && item.parte === data.parte && item.grupo === data.grupo && index !== i)

        // if (existingRegisterCount && existingRegisterCount.length > 0) {
        //   msgErro('Operação já cadastrada no produto, impossível continuar.')
        //   return
        // }

        if (editingRegister.length > 1) {
          throw new Error()
        }

        datatable.row(index).data(data).draw(false)
      }
      desabilitarAlteracaoProcessos()
      recalcularGruposTotais()
    } catch (error) {
      console.error(error)
      msgErro('Ocorreu um problema ao inserir/editar o registro, por favor tente novamente.')
    } finally {
    }
  }

  function criarTabelaGrupos(data) {
    if ($.fn.DataTable.isDataTable('#tabelaGrupos')) {
      $('#tabelaGrupos').DataTable().destroy()
      $('#tabelaGrupos').empty()
    }

    const columns = [
      {
        data: 'codigo',
        title: 'Grupo',
      },
      {
        data: 'descricao',
        title: 'Descrição',
      },
      {
        data: 'tempo',
        title: 'Tempo',
        render: function (data) {
          if (!data) {
            return parseFloat(0).toLocaleString("pt-br", {
              maximumFractionDigits: 4,
              minimumFractionDigits: 4,
            })
          }
          return parseFloat(data).toLocaleString("pt-br", {
            maximumFractionDigits: 4,
            minimumFractionDigits: 4,
          })
        },
        className: 'text-right',
      },
      {
        data: 'tempoTotal',
        title: 'Tempo Total',
        render: function (data) {
          if (!data) {
            return parseFloat(0).toLocaleString("pt-br", {
              maximumFractionDigits: 4,
              minimumFractionDigits: 4,
            })
          }
          return parseFloat(data).toLocaleString("pt-br", {
            maximumFractionDigits: 4,
            minimumFractionDigits: 4,
          })
        },
        className: 'text-right',
      },
      {
        data: 'custoTotal',
        title: 'Custo Total',
        render: function (data) {
          if (!data) {
            return parseFloat(0).toLocaleString("pt-br", {
              maximumFractionDigits: 4,
              minimumFractionDigits: 4,
            })
          }
          return parseFloat(data).toLocaleString("pt-br", {
            maximumFractionDigits: 4,
            minimumFractionDigits: 4,
          })
        },
        className: 'text-right',
      },
      {
        data: 'precoFaccao',
        title: 'Preço Facção',
        render: function (data) {
          if (!data) {
            return parseFloat(0).toLocaleString("pt-br", {
              maximumFractionDigits: 2,
              minimumFractionDigits: 2,
            })
          }
          return parseFloat(data).toLocaleString("pt-br", {
            maximumFractionDigits: 2,
            minimumFractionDigits: 2,
          })
        },
        className: 'text-right',
      },
      {
        data: 'tempoOperacao',
        title: 'Tempo Operação',
        render: function (data) {
          if (!data) {
            return parseFloat(0).toLocaleString("pt-br", {
              maximumFractionDigits: 4,
              minimumFractionDigits: 4,
            })
          }
          return parseFloat(data).toLocaleString("pt-br", {
            maximumFractionDigits: 4,
            minimumFractionDigits: 4,
          })
        },
        className: 'text-right',
      },
      {
        data: 'tempoOperacaoCapa',
        title: 'Tempo Operação Capa',
        render: function (data) {
          if (!data) {
            return parseFloat(0).toLocaleString("pt-br", {
              maximumFractionDigits: 4,
              minimumFractionDigits: 4,
            })
          }
          return parseFloat(data).toLocaleString("pt-br", {
            maximumFractionDigits: 4,
            minimumFractionDigits: 4,
          })
        },
        className: 'text-right',
      },
      {
        data: 'custoLinha',
        title: 'Custo Linha',
        render: function (data) {
          if (!data) {
            return parseFloat(0).toLocaleString("pt-br", {
              maximumFractionDigits: 4,
              minimumFractionDigits: 4,
            })
          }
          return parseFloat(data).toLocaleString("pt-br", {
            maximumFractionDigits: 4,
            minimumFractionDigits: 4,
          })
        },
        className: 'text-right',
      },
    ]

    $("#tabelaGrupos").DataTable({
      sort: false,
      paging: false,
      destroy: true,
      lengthChange: false,
      filter: false,
      autoWidth: true,
      data,
      columns,
    }).draw(false)
  }

  function preencherTabelaGrupos(tabela) {
    insereValor('#txtTabelaGrupos', tabela?.codigo, tabela?.descricao)
  }

  $('#txtTempoProcessos').on('blur', function () {
    calcularCustoTotal()
  })

  function calcularCustoTotal() {
    const tempo = parseFloat(String($('#txtTempoProcessos').val()).replace(',', '.')) || 0
    const custo = parseFloat(String($('#txtCustoProcessos').val()).replace(',', '.')) || 0
    if (!tempo || !custo) {
      return
    }
    const custoTotal = parseFloat(tempo * custo).toLocaleString("pt-br", {
      maximumFractionDigits: 4,
      minimumFractionDigits: 4,
    })
    $('#txtCustoTotalProcessos').val(custoTotal)
  }


  function recalcularOrdemProcessos() {
    $('#tabelaProcessos').DataTable().rows().every(function (rowIndex) {
      const data = this.data()
      data.ordem = rowIndex + 1
      this.data(data)
    })
  }

  $('#btnSubirOrdemProcessos').on('click', function () {
    try {
      const datatable = $('#tabelaProcessos').DataTable()
      const selectedRow = datatable.rows('.selected')
      if (selectedRow.length > 1) {
        throw new Error()
      }
      alterarOrdemLinhaParaCima(datatable, selectedRow)
    } catch (error) {
      console.error(error)
      $('#tabelaProcessos').DataTable().rows().deselect()
      msgErro('Ocorreu um erro ao realizar a alteração da ordem, por favor tente novamente.')
    }
  })

  function alterarOrdemLinhaParaCima(datatable, selectedRow) {
    const [index] = selectedRow.indexes().toArray()
    if (index === undefined || index === null) {
      msgErro('Nenhum linha selecionada, impossível continuar.')
      return
    }
    if (index <= 0) {
      return
    }
    const previousRowData = datatable.row(index - 1).data()
    const currentRowData = datatable.row(index).data()
    datatable.row(index - 1).data({ ...currentRowData, ordem: parseInt(currentRowData.ordem) - 1 })
    datatable.row(index).data({ ...previousRowData, ordem: parseInt(previousRowData.ordem) + 1 })
    datatable.rows().deselect()
    datatable.row(index - 1).select()
  }

  $('#btnDescerOrdemProcessos').on('click', function () {
    try {
      const datatable = $('#tabelaProcessos').DataTable()
      const selectedRow = datatable.rows('.selected')
      if (selectedRow.length > 1) {
        throw new Error()
      }
      alterarOrdemLinhaParaBaixo(datatable, selectedRow)
    } catch (error) {
      console.error(error)
      $('#tabelaProcessos').DataTable().rows().deselect()
      msgErro('Ocorreu um erro ao realizar a alteração da ordem, por favor tente novamente.')
    }
  })

  function alterarOrdemLinhaParaBaixo(datatable, selectedRow) {
    const [index] = selectedRow.indexes().toArray()
    if (index === undefined || index === null) {
      msgErro('Nenhum linha selecionada, impossível continuar.')
      return
    }
    if (index >= datatable.rows().count() - 1) {
      return
    }
    const previousRowData = datatable.row(index + 1).data()
    const currentRowData = datatable.row(index).data()
    datatable.row(index + 1).data({ ...currentRowData, ordem: parseInt(currentRowData.ordem) + 1 })
    datatable.row(index).data({ ...previousRowData, ordem: parseInt(previousRowData.ordem) - 1 })
    datatable.rows().deselect()
    datatable.row(index + 1).select()
  }

  function recalcularGruposTotais() {
    const data = $('#tabelaProcessos').DataTable().data().toArray()
    calcularGruposTotais(data).then(({ grupos, totais }) => {
      if (grupos) criarTabelaGrupos(grupos)
      if (totais) preencherTotaisTempos(totais)
    }).catch((error) => {
      console.error(error)
      msgErro(error || 'Ocorreu um erro ao calcular os dados.')
    })
  }

  async function calcularGruposTotais(data) {
    const filtros = {
      produto: $('#txtCodigoProduto').val(),
      dificuldade: parseFloat(String($('#txtDificuldade').val()).replace(',', '.')) || 0,
      processos: data,
    }
    const response = await requisicao("POST", `/sisplan/sequenciaoperacional/v1/recalculargrupostotais?`, ``, JSON.stringify(filtros), 3600000)

    const json = await response.json()

    if (json) {
      const { resultado, mensagem } = json
      if (mensagem?.codigo !== 200) {
        throw mensagem?.mensagem
      }

      return resultado
    }
  }

  $('#txtTempoProcessos').on('change', function () {
    if (this.value) {
      recalcularTemposProcessos(this.value)
    }
  })

  function recalcularTemposProcessos(tempo) {
    $('#txtTempoTotalProcessos').val(tempo)
    $('#txtTempoOperacaoProcessos').val(tempo)
    $('#txtTempoOperacaoCapaProcessos').val(tempo)
  }

  function preencherTotaisTempos(data) {
    $('#labelTempoHora').val(data.tempoHora ?? '00:00:00')
    $('#labelTempo').val(data.tempo?.toLocaleString("pt-br", {
      maximumFractionDigits: 4,
      minimumFractionDigits: 4,
    }) ?? '0,0000')
    $('#labelTempoTotalHora').val(data.tempoTotalHora ?? '00:00:00')
    $('#labelTempoTotal').val(data.tempoTotal?.toLocaleString("pt-br", {
      maximumFractionDigits: 4,
      minimumFractionDigits: 4,
    }) ?? '0,0000')
    $('#labelDificuldadeOperacaoHora').val(data.dificuldadeOperacaoHora ?? '00:00:00')
    $('#labelDificuldadeOperacao').val(data.dificuldadeOperacao?.toLocaleString("pt-br", {
      maximumFractionDigits: 4,
      minimumFractionDigits: 4,
    }) ?? '0,0000')
    $('#labelDificuldadeOperacaoCapaHora').val(data.dificuldadeOperacaoCapaHora ?? '00:00:00')
    $('#labelDificuldadeOperacaoCapa').val(data.dificuldadeOperacaoCapa?.toLocaleString("pt-br", {
      maximumFractionDigits: 4,
      minimumFractionDigits: 4,
    }) ?? '0,0000')
    $('#labelCustoTotal').val(data.custoTotal?.toLocaleString("pt-br", {
      maximumFractionDigits: 4,
      minimumFractionDigits: 4,
    }) ?? '0,0000')
  }

  $('#btnGravar').on('click', function () {
    const data = retornarDadosGravar()
    if (validarDadosGravar(data)) iniciarProcessoGravarDados(data)
  })

  function retornarDadosGravar() {
    const padrao = $('#cbPadrao').prop('checked') ? 'S' : 'N'
    const cadastro = $('#txtCadastro').val() || formataData(new Date())
    const id = $('#txtId').val()
    const produto = $('#txtCodigoProduto').val()
    const descricao = $('#txtDescricaoProduto').val()
    const parte = pegaChave('#txtParte')
    const cor = pegaChave('#txtCor')
    const dificuldade = parseFloat(String($('#txtDificuldade').val()).replace(',', '.')) || 0
    const capa = {
      padrao,
      id,
      cadastro,
      produto,
      descricao,
      parte,
      cor,
      dificuldade,
    }
    const processos = $('#tabelaProcessos').DataTable().data().toArray()
    const grupos = $('#tabelaGrupos').DataTable().data().toArray()

    return {
      capa,
      grupos,
      processos,
    }
  }

  function validarDadosGravar(data) {
    if (!data) return

    if (!data.capa?.produto) {
      msgErro('Código do produto não informado, impossível continuar.')
      return
    }

    if (!data.capa?.descricao) {
      msgErro('Descrição não informada, impossível continuar.')
      return
    }

    if (!data.capa?.dificuldade) {
      msgErro('Dificuldade não informada, impossível continuar.')
      return
    }

    if (!data.processos || data.processos?.length === 0) {
      msgErro('Nenhum processo foi adicionado, impossível continuar.')
      return
    }
    return true
  }

  function iniciarProcessoGravarDados(data) {
    $.LoadingOverlay('show')
    gravarDados(data).then(({ capa, processos, grupos, tabelaGrupos, totais, }) => {
      toastr.success("Dados gravados com sucesso!", "Confirmação", {
        toastClass: "alert",
        iconClasses: {
          error: "alert-error",
          info: "alert-info",
          success: "alert-success",
          warning: "alert-warning",
        },
        positionClass: "toast-top-center",
        progressBar: true,
        timeOut: 1000,
        fadeOut: 1000,
        onHidden() {
          if (capa) preencherCapa(capa)
          criarTabelaProcessos(processos ?? [])
          criarTabelaGrupos(grupos ?? [])
          if (tabelaGrupos) preencherTabelaGrupos(tabelaGrupos)
          if (totais) preencherTotaisTempos(totais)
        },
      }).css({
        "margin-top": "20%",
        width: "500px",
        "max-width": "500px",
      })
    }).catch((error) => {
      console.error(error)
      msgErro('Ocorreu um erro ao gravar os dados.')
    }).finally(() => $.LoadingOverlay('hide'))
  }

  async function gravarDados(data) {
    const response = await requisicao("POST", `/sisplan/sequenciaoperacional/v1/gravar?`, ``, JSON.stringify(data), 3600000)

    const json = await response.json()

    if (json) {
      const { resultado, mensagem } = json
      if (mensagem?.codigo !== 200) {
        throw mensagem?.mensagem
      }

      return resultado
    }
  }

  $('#txtCodigoProduto').on('input', function () {
    buscarDadosCodigoInformado(
      this.value
    ).then(({ DESCRICAO: descricao }) => {
      insereValor('#txtDescricaoProduto', descricao)
    }).catch((error) => {
      msgErro('Ocorreu um erro ao buscar a descrição.')
      console.error(error)
    })
  })

  async function buscarDadosCodigoInformado(produto) {
    const pesquisa = {
      camposSelect: ['DESCRICAO'],
      tabela: 'PRODUTO',
      where: [`CODIGO = '${produto}'`],
    }
    const result = await retornaJsonPesquisaPadrao(JSON.stringify(pesquisa))
    return result[0] || {
      DESCRICAO: '',
      UNIDADE: '',
    }
  }

  $('#btnVoltar').on('click', function () {
    window.location.href = `${BASE_URI}/sequencia_operacional`
  })
})