let paineis = [];
let SEQPROD = null;
let dadosSeq = {
  MODELO: "",
  COLECAO: "",
  MARCA: "",
  GRUPO: "",
  LINHA: "",
  ETIQUETA: "",
  TIPO: "",
  SEQUENCIAL: "",
};
let telaFormaCodigo; // 'ACESSO' ou 'CADASTRO'

const CONFIG = {
  CHECKBOX_TO_CAMPO: {
    cbModelo: "MODELO",
    cbColecao: "COLECAO",
    cbMarca: "MARCA",
    cbGrupo: "GRUPO",
    cbLinha: "LINHA",
    cbEtiqueta: "ETIQUETA",
    cbTipoProd: "TIPO",
  },
  PAINEL_TO_TELA: {
    GRUPO: "GRUPOPRODUTO",
    TIPO: "TIPOPRODUTO",
    MODELO: "MODELO",
    COLECAO: "COLECAO",
    MARCA: "MARCA",
    LINHA: "LINHA",
    ETIQUETA: "ETIQUETA",
  },
  TABELA_CONFIG: {
    MODELO: { tabela: "MODELO", where: "ATIVO = 'S'" },
    COLECAO: {
      tabela: "COLECAO",
      where: "ATIVO = 'S' AND USA_FORMA_CODIGO = 'S'",
    },
    MARCA: { tabela: "MARCA", where: "ATIVO = 'S' AND USA_FORMA_CODIGO = 'S'" },
    GRUPO: {
      tabela: "GRUPO_PA",
      where: "ATIVO = 'S' AND USA_FORMA_CODIGO = 'S'",
    },
    LINHA: { tabela: "TABLIN", where: "USA_FORMA_CODIGO = 'S'" },
    ETIQUETA: {
      tabela: "ETQ_PROD",
      where: "ATIVO = 'S' AND USA_FORMA_CODIGO = 'S'",
    },
    TIPO: { tabela: "CAD_TIPO_PROD", where: "ATIVO = 'S'" },
  },
  CAMPOS_PADRAO: ["CODIGO", "DESCRICAO"],
  COLUNAS_TABELA: [
    { data: "CODIGO", title: "Código" },
    { data: "DESCRICAO", title: "Descrição" },
  ],
  CHECKBOXES: [
    "cbModelo",
    "cbColecao",
    "cbMarca",
    "cbGrupo",
    "cbLinha",
    "cbEtiqueta",
    "cbTipoProd",
  ],
};

const $checkboxes = $('#tipos input[type="checkbox"]');
const $codMontado = $("#txtCodigoMontado");
const $descMontada = $("#txtDescricaoMontada");
const $plchCodMontado = $("#placeholder-txtCodigoMontado");
const $plchDescMontada = $("#placeholder-txtDescricaoMontada");

$(document).ready(async function () {
  $("#tabConfig").on("click", function () {
    $("#divConfig").removeClass("d-none");
    $("#divFormaCodigo").addClass("d-none");
    $("#btnConfirmarConfig").removeClass("d-none");
    $("#btnGerar").addClass("d-none");
    $("#btnExcluirConfig").removeClass("d-none");
    $("#btnConfirmaCodigo").addClass("d-none");
    $("#codigoPreview").addClass("d-none");
    $("#descricaoPreview").addClass("d-none");
  });

  $("#tabFormaCodigo").on("click", function () {
    $("#divConfig").addClass("d-none");
    $("#divFormaCodigo").removeClass("d-none");
    $("#btnConfirmarConfig").addClass("d-none");
    $("#btnGerar").removeClass("d-none");
    $("#btnExcluirConfig").addClass("d-none");

    if ($("#txtCodigoFormado").val() != "")
      $("#btnConfirmaCodigo").removeClass("d-none");

    $("#codigoPreview").removeClass("d-none");
    $("#descricaoPreview").removeClass("d-none");
  });

  $("#btnVoltarModalFormaCodigo").on("click", function () {
    if (telaFormaCodigo == "CADASTRO")
      window.location.href = BASE_URI + "/produto";
    else $("#modal-forma-codigo, #modalDuplicar").modal("hide");
  });
});

async function buscarConfiguracao({ camposSelect, where, erroMsg }) {
  const sql = {
    tabela: "SOLUCAO",
    camposSelect,
    where,
  };

  const response = await requisicao(
    "GET",
    "/sisplan/funcoes/v1/pesquisa?",
    `JSON=${JSON.stringify(sql)}`,
  );

  if (!response) throw new Error(erroMsg);

  const json = await response.json();

  if (response.status !== 200) throw new Error(json.RESULT[0].mensagem);

  return json.RESULT[0][0];
}

function validaPermissaoTela(tela) {
  const permissoesTela = JSON.parse(getCookie("acessos_web"));

  const rotas = {
    MODELO: "/modelo",
    COLECAO: "/colecao",
    MARCA: "/marca",
    GRUPOPRODUTO: "/grupo",
    LINHA: "/linha",
    ETIQUETA: "/etiqueta",
    TIPOPRODUTO: "/tipoproduto",
  };

  for (const permissao of permissoesTela) {
    if (
      permissao.NOME_TELA === tela &&
      (permissao.CONSULTA === "S" ||
        permissao.ALTERA === "S" ||
        permissao.INCLUI === "S")
    ) {
      return rotas[tela];
    }
  }

  throw new Error(`Você não tem acesso a tela de ${tela.toLowerCase()}`);
}

async function callBackOk(pTabela) {
  try {
    const telaMapeada = CONFIG.PAINEL_TO_TELA[pTabela] || pTabela;
    const page = validaPermissaoTela(telaMapeada);

    const nomeTela =
      telaMapeada == "TIPOPRODUTO"
        ? "Tipo de Produto"
        : telaMapeada == "GRUPOPRODUTO"
          ? "Grupo de Produto"
          : telaMapeada.charAt(0).toUpperCase() +
            telaMapeada.slice(1).toLowerCase();

    parent.abrirEmNovaAbaIFrame(nomeTela, `${BASE_URI}/${page}`);
    window.location.href = BASE_URI + "/produto";
  } catch (error) {
    msgAlerta(error.message, () => {
      window.location.href = BASE_URI + "/produto";
    });
  }
}

function criarCardSimples(id, label) {
  return $("<div>", {
    class: "sequence-card",
    "data-id": id,
    text: label,
  });
}

function criarCardRemovivel(id, label) {
  return $("<div>", {
    class: "sequence-card removable",
    "data-id": id,
  }).append(
    $("<span>", { text: label }),
    $("<button>", {
      type: "button",
      class: "btn-remove",
      text: "✕",
    }),
  );
}

function adicionarCardCodigo(id, label, isRemovivel = true) {
  if ($codMontado.find(`[data-id="${id}"]`).length) return;

  const card = isRemovivel
    ? criarCardRemovivel(id, label)
    : criarCardSimples(id, label);

  $codMontado.append(card);

  $plchCodMontado.text("");
}

function adicionarCardDescricao(id, label, isRemovivel = true) {
  if ($descMontada.find(`[data-id="${id}"]`).length) return;

  const card = isRemovivel
    ? criarCardRemovivel(id, label)
    : criarCardSimples(id, label);

  $descMontada.append(card);

  $plchDescMontada.text("");
}

function removerCardDeTodos(id) {
  $codMontado.find(`[data-id="${id}"]`).remove();
  $descMontada.find(`[data-id="${id}"]`).remove();
}

function removerTodosCards() {
  $codMontado.find("[data-id]").remove();
  $descMontada.find("[data-id]").remove();
}

function converterCheckboxParaValores(checkboxes) {
  return checkboxes.map((cb) => CONFIG.CHECKBOX_TO_CAMPO[cb]).filter(Boolean);
}

function montaDadosSalvarConfig() {
  const codigoMontado = converterCheckboxParaValores(
    $("#txtCodigoMontado .sequence-card")
      .map(function () {
        return $(this).data("id");
      })
      .get(),
  );

  const descricaoMontada = converterCheckboxParaValores(
    $("#txtDescricaoMontada .sequence-card")
      .map(function () {
        return $(this).data("id");
      })
      .get(),
  );

  return {
    CAMPOS_ORDENACAO: codigoMontado,
    CODIGO_MONTADO: codigoMontado,
    DESCRICAO_MONTADA: descricaoMontada,
    SEPARADOR: $("#txtSeparador").val(),
    TAMSEQUENCIAL: $("#txtSequencial").val(),
  };
}

function validarDadosConfig(dados) {
  if (dados.CODIGO_MONTADO.length === 0)
    return "Necessário informar os campos de ordenação do código montado!";

  if (dados.DESCRICAO_MONTADA.length === 0)
    return "Necessário informar os campos de ordenação da descrição montada!";

  if (parseInt(dados.TAMSEQUENCIAL || "0") === 0)
    return "Necessário informar o tamanho do sequencial!";

  return null;
}

async function buscaDados(pTabela) {
  const config = CONFIG.TABELA_CONFIG[pTabela];
  if (!config) return [];

  const sqlDados = {
    tabela: config.tabela,
    camposSelect: CONFIG.CAMPOS_PADRAO,
    where: [config.where],
  };

  const response = await requisicao(
    "GET",
    "/sisplan/funcoes/v1/pesquisa?",
    `JSON=${JSON.stringify(sqlDados)}`,
  );

  if (!response)
    throw new Error(
      "Não foi possível buscar os dados do painel. Tente novamente mais tarde.",
    );

  const jsonResponse = await response.json();

  if (response.status != 200) throw new Error(jsonResponse.RESULT[0].mensagem);

  if (jsonResponse.RESULT[0].length == 0) {
    await tratarErroNaoEncontrado(pTabela);
    return [];
  }

  return jsonResponse.RESULT[0];
}

async function tratarErroNaoEncontrado(pTabela) {
  if (!$("#modal-forma-codigo").hasClass("show")) return;

  $("#modal-forma-codigo").modal("hide");

  const usaFormacaoCodigo = !["TIPO", "MODELO"].includes(pTabela);
  const precisaAtivo = !["LINHA", "TIPO", "MODELO"].includes(pTabela);

  const propriedade = usaFormacaoCodigo
    ? "<strong>Usar na Formação de Código</strong>"
    : "<strong>Ativo</strong>";

  const complemento = precisaAtivo
    ? "e <strong>Ativo</strong> estão devidamente habilitadas"
    : "está devidamente habilitada";

  const mensagem = `
            <p class="font-size-4">
                <strong>FORMAÇÃO DE CÓDIGO:</strong> 
                Nenhum registro de <strong>${pTabela.toLowerCase()}</strong> foi encontrado.<br>
                Verifique se a propriedade ${propriedade} ${complemento}.<br>
                Caso não existam registros válidos, realize o 
                <strong>cadastro de ${pTabela.toLowerCase()}</strong> 
                ou entre em contato com o <strong>suporte</strong> da 
                <strong>Sisplan Sistemas</strong>.
            </p>
        `;

  await msgAlertaHtml(
    mensagem,
    () => callBackOk(pTabela),
    () => (window.location.href = BASE_URI + "/produto"),
    () => (window.location.href = BASE_URI + "/produto"),
    `Abrir cadastro de ${pTabela.toLowerCase()}`,
    "Fechar",
  );

  throw new Error(
    `Nenhuma ${pTabela.toLowerCase()} encontrada. Por favor, verifique!`,
  );
}

async function criarTabelaPainel(painel, codigoProduto) {
  if (
    ![
      "MODELO",
      "COLECAO",
      "MARCA",
      "GRUPO",
      "LINHA",
      "ETIQUETA",
      "TIPO",
      "PRODUTO",
    ].includes(painel)
  )
    return;
  let dadosCodigo;

  if (codigoProduto) {
    dadosCodigo = await buscaDadosAcesso(painel, codigoProduto);
  }

  const title = painel.charAt(0).toUpperCase() + painel.slice(1).toLowerCase();

  $("#listaTabelas").append(`
            <div class="col-3">
                <div class="header-list">
                    <h4 class="list-title">Lista de <b>${title}</b></h4>
                    <div class="input-with-icon">
                        <i class="fas fa-filter filter-icon"></i>
                        <input
                            type="text"
                            class="form-control txtFiltro"
                            id="txtFiltro${painel}"
                            placeholder="Filtrar"
                        >
                    </div>
                </div>
                <table 
                    id="tabela${painel}"
                    class="table table-sm-sisp table-select table-hover text-start"
                    width="100%"
                >
                    <thead></thead>
                    <tbody></tbody>
                </table>
            </div>
        `);

  const dados = await buscaDados(painel);
  inicializarDataTable(painel, dados, dadosCodigo);
}

function inicializarDataTable(painel, dados, sel) {
  const tabela = $(`#tabela${painel}`).DataTable({
    bPaginate: false,
    destroy: true,
    scrollY: "25vh",
    lengthChange: false,
    searching: true,
    columns: CONFIG.COLUNAS_TABELA,
    data: dados,
  });

  if (dados.length === 1) {
    tabela.rows().nodes().to$().addClass("selected");
  }

  $(`#tabela${painel}_filter`).addClass("d-none");
  tabela.columns.adjust().draw(false);

  $(`#tabela${painel}`).on("click", "tr", function () {
    if (!$(this).hasClass("selected")) {
      $(`#tabela${painel}`)
        .DataTable()
        .$("tr.selected")
        .removeClass("selected");
      $(this).addClass("selected");
    }
  });

  $(`#txtFiltro${painel}`).on("keyup", function () {
    $(`#tabela${painel}`).DataTable().search(this.value).draw();
  });

  if (sel) {
    $(`#tabela${painel}`).DataTable().$("tr.selected").removeClass("selected");
    $(`#tabela${painel}`)
      .DataTable()
      .rows()
      .every(function () {
        const data = this.data();
        if (data.CODIGO == sel) {
          $(this.node()).addClass("selected");
        }
      });
  }
}

async function criarTabelas(paineis, codigoProduto) {
  for (const painel of paineis) {
    await criarTabelaPainel(painel, codigoProduto);
  }
}

function pegaLinhaSelecionadaTabela(painel) {
  return $(`#tabela${painel}`).DataTable().row("tr.selected").data();
}

async function pegaSequencialSeqProd(campos, tamSeq) {
  const sql = {
    tabela: "SEQ_PROD",
    camposSelect: ["SEQUENCIAL"],
    where: "1=1",
  };
  campos.forEach((c) => {
    const valor = pegaLinhaSelecionadaTabela(c);
    if (valor && valor.CODIGO) sql.where += ` AND ${c} = '${valor.CODIGO}'`;
  });
  sql.where = [sql.where];

  const response = await requisicao(
    "GET",
    "/sisplan/funcoes/v1/pesquisa?",
    `JSON=${JSON.stringify(sql)}`,
  );

  if (!response) throw new Error("Erro ao buscar o sequencial");

  const json = await response.json();

  if (response.status !== 200) throw new Error(json.RESULT[0].mensagem);

  if (json.RESULT[0].length > 0 && json.RESULT[0][0].SEQUENCIAL)
    return String(parseInt(json.RESULT[0][0].SEQUENCIAL) + 1).padStart(
      parseInt(paineis.SEQUENCIAL),
      "0",
    );
  else return "1".padStart(tamSeq, "0");
}

async function gerarCodigo(configs) {
  const {
    PAINEIS,
    FORMA_CODIGO,
    FORMA_DESCRICAO,
    SEPARADOR = "",
    SEQUENCIAL = 1,
  } = configs;

  for (const p of PAINEIS) {
    const dados = pegaLinhaSelecionadaTabela(p);
    if (!dados)
      return msgAlerta(
        "Necessário selecionar um registro em todas as tabelas.",
      );
  }

  const paineisCodigo = FORMA_CODIGO ?? PAINEIS;
  const paineisDescricao = FORMA_DESCRICAO ?? PAINEIS;

  const getValor = (painel, campo) => {
    const linha = pegaLinhaSelecionadaTabela(painel);
    return linha?.[campo] ?? "";
  };

  SEQPROD = await pegaSequencialSeqProd(paineisCodigo, parseInt(SEQUENCIAL));
  dadosSeq.SEQUENCIAL = SEQPROD;

  const seq = SEQPROD;
  const codigo = [
    ...paineisCodigo.map((p) => getValor(p, "CODIGO")).filter(Boolean),
    seq,
  ].join(SEPARADOR);
  const descricao = paineisDescricao
    .map((p) => getValor(p, "DESCRICAO"))
    .filter(Boolean)
    .join(" ");

  return { codigo, descricao };
}

function retornaNomePaineis(painel) {
  return painel.charAt(0).toUpperCase() + painel.slice(1).toLowerCase();
}

function processarLista(listaPaineis, funcaoAdicionar) {
  const lista = listaPaineis?.length ? listaPaineis : paineis.PAINEIS;
  lista.forEach((item) => {
    const nomeFormatado = retornaNomePaineis(item);
    funcaoAdicionar(item, nomeFormatado, false);
  });
}

function preencheConfiguracoes(paineis) {
  if (paineis.PAINEIS.length === 0) return;

  const PAINEIS = paineis.PAINEIS;
  const FORMA_CODIGO = paineis.FORMA_CODIGO;
  const FORMA_DESCRICAO = paineis.FORMA_DESCRICAO;

  const codigoTitle = [...paineis.FORMA_CODIGO, "SEQUENCIAL"].join(
    paineis.SEPARADOR || ", ",
  );
  const descTitle = paineis.FORMA_DESCRICAO.join(", ");
  $("#txtCodigoFormado").prop("title", `Código gerado por: ${codigoTitle}`);
  $("#txtDescricaoFormada").prop("title", `Descrição gerada por: ${descTitle}`);

  const variaveis = {
    MODELO: "cbModelo",
    COLECAO: "cbColecao",
    MARCA: "cbMarca",
    GRUPO: "cbGrupo",
    LINHA: "cbLinha",
    ETIQUETA: "cbEtiqueta",
    TIPO: "cbTipoProd",
  };

  PAINEIS.forEach((painel) => {
    $(`#${variaveis[painel]}`).prop("checked", true);
  });
  processarLista(FORMA_CODIGO, adicionarCardCodigo);
  processarLista(FORMA_DESCRICAO, adicionarCardDescricao);

  for (const cb of CONFIG.CHECKBOXES) {
    $(`#${cb}`).prop("disabled", true);
  }

  $("#txtSeparador").val(paineis.SEPARADOR).prop("disabled", true);
  $("#txtSequencial").val(paineis.SEQUENCIAL).prop("disabled", true);
}

async function atualizaSequencial(campos) {
  const response = await requisicao(
    "POST",
    "/sisplan/produto/v1/atualizasequencial?",
    `FILTROS=${JSON.stringify(campos)}`,
  );

  if (!response)
    throw new Error(
      "Erro ao atualizar o sequencial. Entre em contato com o suporte da Sisplan Sistemas.",
    );

  const json = await response.json();

  if (response.status !== 200) throw new Error(json.RESULT[0].mensagem);
}

async function confirmaCodigoGerado() {
  const PRODUTO = {
    CODIGO: $("#txtCodigoFormado").val(),
    DESCRICAO: $("#txtDescricaoFormada").val(),
  };

  const title = "Campo bloqueado pela formação de código.";
  $(telaFormaCodigo == 'CADASTRO' ? "#txtCodigo" : "#txtProdutoDuplicar")
    .val(PRODUTO.CODIGO)
    .prop("disabled", true)
    .prop("title", title);

  $("#txtDescricaoProduto").val(PRODUTO.DESCRICAO);

  if (paineis.PAINEIS.includes("MODELO")) {
    const mod = pegaLinhaSelecionadaTabela("MODELO");
    dadosSeq.MODELO = mod.CODIGO;
    insereValor("#txtModelo", mod.CODIGO, mod.DESCRICAO);
    $("#txtModelo, #btnModelo, #btnAModelo")
      .prop("disabled", true)
      .prop("title", title);
  }

  if (paineis.PAINEIS.includes("COLECAO")) {
    const col = pegaLinhaSelecionadaTabela("COLECAO");
    dadosSeq.COLECAO = col.CODIGO;
    insereValor("#txtColecao", col.CODIGO, col.DESCRICAO);
    $("#txtColecao, #btnColecao, #btnAColecao")
      .prop("disabled", true)
      .prop("title", title);
  }

  if (paineis.PAINEIS.includes("MARCA")) {
    const mar = pegaLinhaSelecionadaTabela("MARCA");
    dadosSeq.MARCA = mar.CODIGO;
    insereValor("#txtMarca", mar.CODIGO, mar.DESCRICAO);
    $("#txtMarca, #btnMarca, #btnAMarca")
      .prop("disabled", true)
      .prop("title", title);
  }

  if (paineis.PAINEIS.includes("GRUPO")) {
    const gru = pegaLinhaSelecionadaTabela("GRUPO");
    dadosSeq.GRUPO = gru.CODIGO;
    insereValor("#txtGrupo", gru.CODIGO, gru.DESCRICAO);
    $("#txtGrupo, #btnGrupo, #btnAGrupo")
      .prop("disabled", true)
      .prop("title", title);
  }

  if (paineis.PAINEIS.includes("LINHA")) {
    const lin = pegaLinhaSelecionadaTabela("LINHA");
    dadosSeq.LINHA = lin.CODIGO;
    insereValor("#txtLinha", lin.CODIGO, lin.DESCRICAO);
    $("#txtLinha, #btnLinha, #btnALinha")
      .prop("disabled", true)
      .prop("title", title);
  }

  if (paineis.PAINEIS.includes("ETIQUETA")) {
    const eti = pegaLinhaSelecionadaTabela("ETIQUETA");
    dadosSeq.ETIQUETA = eti.CODIGO;
    insereValor("#txtEtiqueta", eti.CODIGO, eti.DESCRICAO);
    $("#txtEtiqueta, #btnEtiqueta, #btnAEtiqueta")
      .prop("disabled", true)
      .prop("title", title);
  }

  if (paineis.PAINEIS.includes("TIPO")) {
    const tip = pegaLinhaSelecionadaTabela("TIPO");
    dadosSeq.TIPO = tip.CODIGO;
    insereValor("#txtTipoProduto", tip.CODIGO, tip.DESCRICAO);
    $("#txtTipoProduto, #btnTipoProduto, #btnLimpaTipoProduto")
      .prop("disabled", true)
      .prop("title", title);
  }

  $("#modal-forma-codigo").modal("hide");
}

async function buscaPaineis() {
  const configuracoes = {};

  // ===================== PAINÉIS =====================
  const dadosPaineis = await buscarConfiguracao({
    camposSelect: [
      "DESCRICAO3 SEQUENCIAL",
      "DESCRICAO4 SEPARADOR",
      "DESCRICAO5 PAINEIS",
    ],
    where: ["VARIAVEL = 'FORMACODIGOPROD2' AND DESCRICAO = 'REGRA_FORMACAO'"],
    erroMsg: "Não foi possível buscar os painéis.",
  });
  if (dadosPaineis) {
    if (dadosPaineis.SEQUENCIAL)
      configuracoes.SEQUENCIAL = dadosPaineis.SEQUENCIAL;
    if (dadosPaineis.SEPARADOR)
      configuracoes.SEPARADOR = dadosPaineis.SEPARADOR;
    if (dadosPaineis.PAINEIS)
      configuracoes.PAINEIS = dadosPaineis.PAINEIS.trim().split("  ");
  }

  // ===================== FORMA CÓDIGO =====================
  const dadosCodigo = await buscarConfiguracao({
    camposSelect: ["DESCRICAO2 FORMA_CODIGO"],
    where: [
      "VARIAVEL = 'FORMACODIGOPROD2' AND DESCRICAO = 'REGRA_FORMACAO_COD'",
    ],
    erroMsg: "Não foi possível buscar a forma de código.",
  });
  if (dadosCodigo && dadosCodigo.FORMA_CODIGO)
    configuracoes.FORMA_CODIGO = dadosCodigo.FORMA_CODIGO.trim().split(" + ")
  else configuracoes.FORMA_CODIGO = dadosPaineis.PAINEIS.trim().split("  ");


  // ===================== FORMA DESCRIÇÃO =====================
  const dadosDesc = await buscarConfiguracao({
    camposSelect: ["DESCRICAO2 FORMA_DESCRICAO"],
    where: [
      "VARIAVEL = 'FORMACODIGOPROD2' AND DESCRICAO = 'REGRA_FORMACAO_DESC'",
    ],
    erroMsg: "Não foi possível buscar a forma de descrição.",
  });
  if (dadosDesc && dadosDesc.FORMA_DESCRICAO)
    configuracoes.FORMA_DESCRICAO =
      dadosDesc.FORMA_DESCRICAO.trim().split(" + ")
  else configuracoes.FORMA_DESCRICAO = dadosPaineis.PAINEIS.trim().split("  ");

  return configuracoes;
}

function aguardarModalAbrir() {
  $("#modal-forma-codigo").modal({
    backdrop: "static",
    keyboard: false,
    show: true,
  });

  return new Promise((resolve) => {
    $("#modal-forma-codigo")
      .one("shown.bs.modal", function () {
        resolve();
      })
      .modal("show");
  });
}

function inicializarSortables() {
  const sortableConfig = {
    axis: "x",
    containment: "parent",
    tolerance: "pointer",
  };
  $codMontado.sortable(sortableConfig);
  $descMontada.sortable(sortableConfig);
}

function registrarEventListeners() {
  $checkboxes.on("change", function () {
    const $cb = $(this);
    const id = $cb.attr("id");
    const label = $(`label[for="${id}"]`).text();

    if ($cb.is(":checked")) {
      adicionarCardCodigo(id, label, true);
      adicionarCardDescricao(id, label, true);
    } else {
      removerCardDeTodos(id);
    }
  });

  $(document).on("click", ".btn-remove", function () {
    $(this).closest(".sequence-card").remove();
  });

  $("#btnConfirmarConfig").on("click", async function () {
    const dados = montaDadosSalvarConfig();
    const erro = validarDadosConfig(dados);

    if (erro) {
      msgAlerta(erro);
      return;
    }

    const config = {
      SEQUENCIAL: dados.TAMSEQUENCIAL,
      SEPARADOR: dados.SEPARADOR,
      PAINEIS: dados.CAMPOS_ORDENACAO.join("  "),
    };

    const codDesc = {
      CODIGO: encodeURI(dados.CODIGO_MONTADO.join(" + ")),
      DESCRICAO: encodeURI(dados.DESCRICAO_MONTADA.join(" + ")),
    };

    const response = await requisicao(
      "POST",
      "/sisplan/produto/v1/salvaconfiguracoesformacodigo?",
      `CONFIG=${JSON.stringify(config)}&CONFIGCODDESC=${JSON.stringify(codDesc)}`,
    );

    if (!response)
      throw new Error("Erro ao salvar os dados, tente novamente mais tarde.");

    const json = await response.json();

    if (response.status !== 200) throw new Error(json.RESULT[0].mensagem);

    msgAlerta(
      "Dados Gravados com Sucesso. Abra a tela novamente!",
      () => (window.location.href = BASE_URI + "/produto"),
      undefined,
      () => (window.location.href = BASE_URI + "/produto"),
      undefined,
      false,
      true,
    );
  });

  $("#btnExcluirConfig").on("click", async function () {
    await msgAguardaConfirmacao(
      "Você tem certeza que deseja excluir a configuração atual? Esta ação é irreversível!",
      async () => {
        const response = await requisicao(
          "DELETE",
          "/sisplan/produto/v1/configuracaoformacodigo?",
        );

        if (!response)
          throw new Error(
            "Erro ao excluir a configuração, tente novamente mais tarde.",
          );

        const json = await response.json();

        if (response.status !== 200) throw new Error(json.RESULT[0].mensagem);

        for (const c of CONFIG.CHECKBOXES) {
          $(`#${c}`).prop("checked", false).prop("disabled", false);
        }

        removerTodosCards();
        $plchCodMontado.text(
          'Selecione uma opção no menu "Campos Disponíveis"',
        );
        $plchDescMontada.text(
          'Selecione uma opção no menu "Campos Disponíveis"',
        );

        $("#txtSeparador").val("").prop("disabled", false);
        $("#txtSequencial").val("").prop("disabled", false);

        msgAlerta("Configuração excluída!");
      },
      () => {},
    );
  });

  $("#btnGerar").on("click", async function () {
    const configs = paineis;
    const resultado = await gerarCodigo(configs);

    $("#txtCodigoFormado").val(resultado.codigo);
    $("#txtDescricaoFormada").val(resultado.descricao);

    $("#btnGerar").html(
      '<span class="fas fa-cogs pr-1"></span> Gerar Novamente',
    );
    $("#btnConfirmaCodigo").removeClass("d-none");
  });

  $("#btnConfirmaCodigo").on("click", async function () {
    await confirmaCodigoGerado();
  });
}

async function buscaDadosAcesso(campo, codigoProduto) {
  const sql = {
    tabela: "PRODUTO",
    camposSelect: [campo],
    where: [`CODIGO = '${codigoProduto}'`],
  };
  const dados = await retornaJsonPesquisaPadrao(JSON.stringify(sql));
  return dados[0][campo];
}
