function defineStructure() {
    addColumn("LOGIN");
    addColumn("NOME");
    addColumn("EMAIL");
    addColumn("COLLEAGUE_ID");
    addColumn("GROUP_ID");
}

function onSync(lastSyncDate) {}
function onMobileSync(user) {}

function createDataset(fields, constraints, sortFields) {
    var dataset = DatasetBuilder.newDataset();
    dataset.addColumn("LOGIN");
    dataset.addColumn("NOME");
    dataset.addColumn("EMAIL");
    dataset.addColumn("COLLEAGUE_ID");
    dataset.addColumn("GROUP_ID");

    try {
        var cfg = parseConstraints(constraints);
        var members = getMembersFromGroup(cfg.groupId);
        var termo = normalize(cfg.termoLivre);
        var added = 0;

        for (var i = 0; i < members.length; i++) {
            var memberId = trim(members[i]);
            if (!memberId) continue;

            var col = getColleagueById(memberId);
            if (!col) continue;

            if (termo) {
                var blob = normalize([
                    col.LOGIN,
                    col.NOME,
                    col.EMAIL,
                    col.COLLEAGUE_ID
                ].join(" "));
                if (blob.indexOf(termo) === -1) {
                    continue;
                }
            }

            dataset.addRow([
                col.LOGIN,
                col.NOME,
                col.EMAIL,
                col.COLLEAGUE_ID,
                cfg.groupId
            ]);
            added++;
        }

        if (added === 0) {
            // Mantem dataset vazio para o zoom nao exibir usuarios fora do grupo.
        }
    } catch (e) {
        safeLogError("[ds_motoristas_grupo] Erro no createDataset: " + e);
        dataset = DatasetBuilder.newDataset();
        dataset.addColumn("LOGIN");
        dataset.addColumn("NOME");
        dataset.addColumn("EMAIL");
        dataset.addColumn("COLLEAGUE_ID");
        dataset.addColumn("GROUP_ID");
    }

    return dataset;
}

function parseConstraints(constraints) {
    var out = {
        groupId: "Motoristas",
        termoLivre: ""
    };

    if (!constraints) return out;

    for (var i = 0; i < constraints.length; i++) {
        var c = constraints[i];
        if (!c) continue;

        var field = getConstraintFieldName(c);
        var value = getConstraintInitialValue(c);
        if (!field) continue;
        if (!value) continue;

        if (
            field === "GROUP_ID" ||
            field === "groupId" ||
            field === "group_id" ||
            field === "colleagueGroupPK.groupId"
        ) {
            out.groupId = value;
            continue;
        }

        if (
            field !== "metadata#id" &&
            field !== "metadata#active" &&
            field !== "sqlLimit"
        ) {
            var cleaned = cleanSearchValue(value);
            if (cleaned && (!out.termoLivre || cleaned.length > out.termoLivre.length)) {
                out.termoLivre = cleaned;
            }
        }
    }

    return out;
}

function getMembersFromGroup(groupId) {
    var members = {};
    var out = [];
    var gId = trim(groupId);
    if (!gId) return out;

    var fieldOptions = [
        "colleagueGroupPK.groupId",
        "groupId",
        "group"
    ];

    var groupCandidates = [gId];
    var upper = gId.toUpperCase();
    var lower = gId.toLowerCase();
    if (groupCandidates.indexOf(upper) < 0) groupCandidates.push(upper);
    if (groupCandidates.indexOf(lower) < 0) groupCandidates.push(lower);

    var ds = null;
    for (var g = 0; g < groupCandidates.length; g++) {
        for (var i = 0; i < fieldOptions.length; i++) {
            try {
                var cGroup = DatasetFactory.createConstraint(fieldOptions[i], groupCandidates[g], groupCandidates[g], ConstraintType.MUST);
                ds = DatasetFactory.getDataset("colleagueGroup", null, [cGroup], null);
                if (ds && ds.rowsCount > 0) {
                    break;
                }
            } catch (e) {
                safeLogError("[ds_motoristas_grupo] Erro consultando colleagueGroup (" + fieldOptions[i] + "=" + groupCandidates[g] + "): " + e);
                ds = null;
            }
        }
        if (ds && ds.rowsCount > 0) {
            break;
        }
    }

    if (!ds || ds.rowsCount === 0) {
        // Fallback: alguns ambientes permitem filtrar direto no dataset colleague por groupId.
        try {
            var cGroupCol = DatasetFactory.createConstraint("groupId", gId, gId, ConstraintType.MUST);
            ds = DatasetFactory.getDataset("colleague", null, [cGroupCol], null);
            if (ds && ds.rowsCount > 0) {
                for (var x = 0; x < ds.rowsCount; x++) {
                    var fallbackId = trim(
                        ds.getValue(x, "colleaguePK.colleagueId") ||
                        ds.getValue(x, "colleagueId") ||
                        ds.getValue(x, "login")
                    );
                    if (!fallbackId) continue;
                    if (members[fallbackId]) continue;
                    members[fallbackId] = true;
                    out.push(fallbackId);
                }
            }
        } catch (eFallback) {
            safeLogError("[ds_motoristas_grupo] Erro no fallback por groupId no colleague: " + eFallback);
        }
        return out;
    }

    for (var r = 0; r < ds.rowsCount; r++) {
        var colleagueId = trim(
            ds.getValue(r, "colleagueGroupPK.colleagueId") ||
            ds.getValue(r, "colleagueId") ||
            ds.getValue(r, "login")
        );
        if (!colleagueId) continue;
        if (members[colleagueId]) continue;
        members[colleagueId] = true;
        out.push(colleagueId);
    }

    return out;
}

function getColleagueById(colleagueId) {
    var id = trim(colleagueId);
    if (!id) return null;

    var fieldsToTry = ["colleaguePK.colleagueId", "colleagueId", "login"];
    var ds = null;

    // 1) Tenta buscando somente ativos com diferentes campos.
    for (var i = 0; i < fieldsToTry.length; i++) {
        ds = getColleagueDataset(id, fieldsToTry[i], true);
        if (ds && ds.rowsCount > 0) {
            break;
        }
    }

    // 2) Fallback sem constraint de ativo (alguns ambientes tratam "active" de forma diferente).
    if (!ds || ds.rowsCount === 0) {
        for (var j = 0; j < fieldsToTry.length; j++) {
            ds = getColleagueDataset(id, fieldsToTry[j], false);
            if (ds && ds.rowsCount > 0) {
                break;
            }
        }
    }

    if (!ds || ds.rowsCount === 0) return null;

    var row = pickActiveRow(ds);
    if (row < 0) row = 0;

    var colleaguePkId = trim(
        ds.getValue(row, "colleaguePK.colleagueId") ||
        ds.getValue(row, "colleagueId") ||
        ds.getValue(row, "login")
    );
    if (!colleaguePkId) return null;

    return {
        LOGIN: trim(ds.getValue(row, "login")),
        NOME: trim(ds.getValue(row, "colleagueName")),
        EMAIL: trim(ds.getValue(row, "mail")),
        COLLEAGUE_ID: colleaguePkId
    };
}

function getColleagueDataset(id, fieldName, onlyActive) {
    try {
        var constraints = [
            DatasetFactory.createConstraint(fieldName, id, id, ConstraintType.MUST)
        ];

        if (onlyActive) {
            constraints.push(DatasetFactory.createConstraint("active", "true", "true", ConstraintType.MUST));
        }

        return DatasetFactory.getDataset("colleague", null, constraints, null);
    } catch (e) {
        safeLogError("[ds_motoristas_grupo] Erro consultando colleague (" + fieldName + "=" + id + ", active=" + onlyActive + "): " + e);
        return null;
    }
}

function pickActiveRow(ds) {
    if (!ds || ds.rowsCount <= 0) return -1;

    for (var i = 0; i < ds.rowsCount; i++) {
        var activeValue = trim(ds.getValue(i, "active") || ds.getValue(i, "colleaguePK.active"));
        if (!activeValue) return i;

        var n = normalize(activeValue);
        if (n === "true" || n === "1" || n === "yes" || n === "sim" || n === "y" || n === "s" || n === "t") {
            return i;
        }
    }

    return -1;
}

function getConstraintFieldName(constraint) {
    try {
        if (constraint.fieldName) return String(constraint.fieldName);
        if (constraint._field) return String(constraint._field);
        if (typeof constraint.getFieldName === "function") return String(constraint.getFieldName());
    } catch (e) {}
    return "";
}

function getConstraintInitialValue(constraint) {
    try {
        if (constraint.initialValue != null) return trim(constraint.initialValue);
        if (constraint._initialValue != null) return trim(constraint._initialValue);
        if (typeof constraint.getInitialValue === "function") return trim(constraint.getInitialValue());
    } catch (e) {}
    return "";
}

function trim(v) {
    return String(v == null ? "" : v).trim();
}

function normalize(v) {
    return trim(v).toLowerCase();
}

function cleanSearchValue(v) {
    return trim(v).replace(/[%*_]/g, "");
}

function safeLogError(message) {
    try {
        log.error(String(message));
    } catch (e) {}
}
