function createDataset(fields, constraints, sortFields) {
  var dataset = DatasetBuilder.newDataset();
  dataset.addColumn("DESCRICAO");
  dataset.addColumn("CBO");

  var servicecode = "Postprod";
  var usuario = "fluig";
  var senha = "Ginseng@";

  var filial = "01";
  var pagesize = 100;
  var page = 1;
  var total = null;
  var termoBusca = getSearchTerm(constraints);
  var limiteLinhas = getLimit(constraints, 200);
  var linhasAdicionadas = 0;

  try {
    var clientService = fluigAPI.getAuthorizeClientService();

    while (true) {
      var endpoint =
        "https://rest.grupoginseng.com.br/rest/uf_sigagpe/funcoes" +
        "?filial=" + encodeURIComponent(filial) +
        "&page=" + encodeURIComponent(page) +
        "&pagesize=" + encodeURIComponent(pagesize);

      var data = {
        companyId: "1",
        serviceCode: servicecode,
        endpoint: endpoint,
        method: "get",
        timeoutService: "60000",
        params: {},
        options: {
          encoding: "UTF-8",
          useBasicAuth: true,
          username: usuario,
          password: senha
        }
      };

      var vo = clientService.invoke(JSON.stringify(data));
      var retorno = vo.getResult();

      if (!retorno) break;

      var obj = JSON.parse(retorno);

      // se a API usa "sucesso"
      if (obj.sucesso !== true) {
        dataset.addRow(["(API retornou sucesso=false)", ""]);
        break;
      }

      // sua lista vem em "funcoes" (não "items")
      var funcoes = obj.funcoes;

      if (!funcoes || funcoes.length === 0) break;

      // guarda total se vier
      if (total === null && obj.total != null) total = Number(obj.total);

      for (var i = 0; i < funcoes.length; i++) {
        var descricao = String(funcoes[i].RJ_DESC || "");
        var cbo = String(funcoes[i].RJ_CODCBO || "");

        if (matchSearch(termoBusca, descricao, cbo)) {
          dataset.addRow([descricao, cbo]);
          linhasAdicionadas++;
          if (linhasAdicionadas >= limiteLinhas) break;
        }
      }

      if (linhasAdicionadas >= limiteLinhas) break;

      // condição de parada segura
      if (funcoes.length < pagesize) break;

      // se quiser parar com base no total:
      if (total !== null && page * pagesize >= total) break;

      page++;
    }

  } catch (e) {
    dataset = DatasetBuilder.newDataset();
    dataset.addColumn("DESCRICAO");
    dataset.addColumn("CBO");
    dataset.addRow(["ERRO AO CARREGAR FUNCOES: " + String(e), ""]);
  }

  return dataset;
}

function getSearchTerm(constraints) {
  if (!constraints || constraints.length === 0) return "";

  var searchField = "";
  var searchValue = "";
  var term = "";

  for (var i = 0; i < constraints.length; i++) {
    var c = constraints[i];
    var field = String(c.getFieldName ? c.getFieldName() : c.fieldName || "").toLowerCase();
    var value = String(c.getInitialValue ? c.getInitialValue() : c.initialValue || "");

    if (field === "searchfield") {
      searchField = String(value).toLowerCase();
    } else if (field === "searchvalue") {
      searchValue = value;
    } else if (field === "descricao" || field === "rj_desc" || field === "cbo" || field === "rj_codcbo") {
      term = value;
    }
  }

  if (searchValue !== "") return searchValue;
  if (searchField !== "" && term !== "") return term;
  return term;
}

function getLimit(constraints, defaultValue) {
  if (!constraints || constraints.length === 0) return defaultValue;

  for (var i = 0; i < constraints.length; i++) {
    var c = constraints[i];
    var field = String(c.getFieldName ? c.getFieldName() : c.fieldName || "").toLowerCase();
    var value = String(c.getInitialValue ? c.getInitialValue() : c.initialValue || "");

    if (field === "sqllimit" || field === "limit") {
      var n = parseInt(value, 10);
      if (!isNaN(n) && n > 0) return n;
    }
  }

  return defaultValue;
}

function matchSearch(term, descricao, cbo) {
  var t = String(term || "").toLowerCase().trim();
  if (t === "") return true;

  var desc = String(descricao || "").toLowerCase();
  var cod = String(cbo || "").toLowerCase();
  return desc.indexOf(t) >= 0 || cod.indexOf(t) >= 0;
}
