<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <title>AG Grid Tree User Rights</title>
  <script src="https://cdn.jsdelivr.net/npm/ag-grid-community@29.3.4/dist/ag-grid-community.min.noStyle.js"></script>
  <link href="https://cdn.jsdelivr.net/npm/ag-grid-community@29.3.4/styles/ag-grid.css" rel="stylesheet" />
  <link href="https://cdn.jsdelivr.net/npm/ag-grid-community@29.3.4/styles/ag-theme-alpine.css" rel="stylesheet" />
  <style>
    html, body, #myGrid {
      height: 75vh;
      margin: 20px auto;
      width: 95%;
    }
  </style>
</head>
<body>

<h3>Select Role:
  <select id="roleSelect"></select>
  <button id="saveRights">Save Rights</button>
</h3>

<div id="myGrid" class="ag-theme-alpine"></div>

<script>
const roles = [
  { id: 1, name: "Admin" },
  { id: 2, name: "Manager" },
  { id: 3, name: "Viewer" }
];

const permissions = ["add", "edit", "delete", "view", "print"];

// Simulated hierarchical modules
const rowData = [
  { id: 1, module: "Sales", rights: {}, parent: null },
  { id: 2, module: "Orders", rights: {}, parent: 1 },
  { id: 3, module: "Invoices", rights: {}, parent: 1 },
  { id: 4, module: "Purchase", rights: {}, parent: null },
  { id: 5, module: "Suppliers", rights: {}, parent: 4 },
  { id: 6, module: "Inventory", rights: {}, parent: null }
];

// Column Definitions
const columnDefs = [
  {
    field: "module",
    headerName: "Module",
    cellRenderer: "agGroupCellRenderer"
  },
  ...permissions.map(perm => ({
    headerName: perm.charAt(0).toUpperCase() + perm.slice(1),
    field: perm,
    width: 90,
    cellRenderer: checkboxRenderer,
    headerComponent: SelectAllHeader,
    headerComponentParams: { perm },
    editable: true
  }))
];

// Checkbox cell
function checkboxRenderer(params) {
  const checked = params.data[params.colDef.field] || false;
  const checkbox = document.createElement('input');
  checkbox.type = 'checkbox';
  checkbox.checked = checked;

  checkbox.addEventListener('change', (e) => {
    params.node.setDataValue(params.colDef.field, e.target.checked);
  });

  return checkbox;
}

// "Select All" header checkbox
function SelectAllHeader() {}
SelectAllHeader.prototype.init = function(params) {
  this.params = params;
  this.eGui = document.createElement('div');
  const checkbox = document.createElement('input');
  checkbox.type = 'checkbox';
  this.eGui.appendChild(checkbox);

  checkbox.addEventListener('change', () => {
    const checked = checkbox.checked;
    const col = params.column.getColId();
    params.api.forEachNode(node => {
      node.setDataValue(col, checked);
    });
  });

  this.update = () => {
    const col = params.column.getColId();
    let all = true, none = true;
    params.api.forEachNode(node => {
      if (node.data[col]) none = false;
      else all = false;
    });
    checkbox.indeterminate = !(all || none);
    checkbox.checked = all;
  };

  params.api.addEventListener('cellValueChanged', this.update);
};
SelectAllHeader.prototype.getGui = function() {
  return this.eGui;
};

// Grid setup
const gridOptions = {
  columnDefs,
  rowData: null,
  treeData: true,
  animateRows: true,
  getDataPath: data => {
    // Build tree path using parent links
    const path = [];
    let current = data;
    while (current) {
      path.unshift(current.module);
      current = rowData.find(r => r.id === current.parent);
    }
    return path;
  },
  getRowNodeId: data => data.id,
  defaultColDef: {
    resizable: true,
    sortable: true
  },
  onGridReady: () => {
    // Load initial data
    gridOptions.api.setRowData(
      rowData.map(row => ({ ...row, ...Object.fromEntries(permissions.map(p => [p, false])) }))
    );
  }
};

// Role dropdown population
roles.forEach(role => {
  const opt = document.createElement('option');
  opt.value = role.id;
  opt.textContent = role.name;
  document.getElementById('roleSelect').appendChild(opt);
});

let currentRoleId = roles[0].id;
document.getElementById('roleSelect').addEventListener('change', function () {
  currentRoleId = this.value;
  // TODO: Load role rights from server
  alert("Load rights for Role ID: " + currentRoleId);
});

document.getElementById('saveRights').addEventListener('click', function () {
  const rights = [];
  gridOptions.api.forEachNode(node => {
    const rightsObj = { moduleId: node.data.id };
    permissions.forEach(perm => rightsObj[perm] = node.data[perm]);
    rights.push(rightsObj);
  });
  console.log("Save for role:", currentRoleId, rights);
  // TODO: Send to server with AJAX
  alert("Rights saved (mock)");
});

// Init AG Grid
new agGrid.Grid(document.getElementById('myGrid'), gridOptions);
</script>

</body>
</html>
