/* table_editor, par Sébastien L. 2021-11-12
 */

/*****************************/
/* Mise en place des données */
/*****************************/
let lastX;
let lastY;

function build_table(data) {
  let output = "";
  let sumsUE = {};
  let sumsRessources = {};
  let value;

  data.forEach((cellule) => {
    output += `
            <div
                class="${cellule.style || ""}"
                data-editable="${cellule.editable || "false"}"
                data-module_id="${cellule.module_id}"
                data-ue_id="${cellule.ue_id}"
                data-x="${cellule.x}"
                data-y="${cellule.y}"
                data-nbX="${cellule.nbX || 1}"
                data-nbY="${cellule.nbY || 1}"
                data-data="${cellule.data}"
                data-orig="${cellule.data}"
                title="${cellule.title || ""}"
                style="
                    --x:${cellule.x};
                    --y:${cellule.y};
                    --nbX:${cellule.nbX || 1};
                    --nbY: ${cellule.nbY || 1};
                ">${cellule.data}</div>`; // ne pas mettre d'espace car c'est utilisé par :not(:empty) après

    if (cellule.style.includes("champs")) {
      if (cellule.editable == true && cellule.data) {
        value = parseFloat(cellule.data) * 100;
      } else {
        value = 0;
      }
      sumsRessources[cellule.y] = (sumsRessources[cellule.y] ?? 0) + value;
      sumsUE[cellule.x] = (sumsUE[cellule.x] ?? 0) + value;
    }
  });

  output += showSums(sumsRessources, sumsUE);
  document.querySelector(".tableau").innerHTML = output;
  installListeners();
}

function showSums(sumsRessources, sumsUE) {
  lastX = Object.keys(sumsUE).length + 2;
  lastY = Object.keys(sumsRessources).length + 2;

  let output = "";

  Object.entries(sumsUE).forEach(([num, value]) => {
    output += `
            <div
                class="sums"
                data-editable="false"
                data-x="${num}"
                data-y="${lastY}"
                style="
                    --x:${num};
                    --y:${lastY};
                    --nbX:1;
                    --nbY:1;
                ">
                ${(value / 100).toLocaleString(undefined, {
                  minimumFractionDigits: 0,
                  maximumFractionDigits: 2,
                })}
            </div>`;
  });

  Object.entries(sumsRessources).forEach(([num, value]) => {
    output += `
            <div
                class="sums"
                data-editable="false"
                data-x="${lastX}"
                data-y="${num}"
                style="
                    --x:${lastX};
                    --y:${num};
                    --nbX:1;
                    --nbY:1;
                ">
                ${(value / 100).toLocaleString(undefined, {
                  minimumFractionDigits: 0,
                  maximumFractionDigits: 2,
                })}
            </div>`;
  });

  return output;
}

/*****************************/
/* Gestion des évènements    */
/*****************************/

function installListeners() {
  if (read_only) {
    return;
  }
  document.body.addEventListener("keydown", key);
  document.querySelectorAll("[data-editable=true]").forEach((cellule) => {
    cellule.addEventListener("click", function () {
      selectCell(this);
    });
    cellule.addEventListener("dblclick", function () {
      modifCell(this);
    });
    cellule.addEventListener("blur", function () {
      let currentModif = document.querySelector(".modifying");
      if (currentModif) {
        if (!save(currentModif)) {
          return;
        }
      }
    });
    cellule.addEventListener("input", processSums);
  });
}

/*********************************/
/* Interaction avec les cellules */
/*********************************/
function selectCell(obj) {
  if (obj.classList.contains("modifying")) {
    return; // Cellule en cours de modification, ne pas sélectionner.
  }
  let currentModif = document.querySelector(".modifying");
  if (currentModif) {
    if (!save(currentModif)) {
      return;
    }
  }

  document.querySelectorAll(".selected, .modifying").forEach((cellule) => {
    cellule.classList.remove("selected", "modifying");
    cellule.removeAttribute("contentEditable");
    cellule.removeEventListener("keydown", keyCell);
  });
  obj.classList.add("selected");
}

function modifCell(obj) {
  if (obj) {
    obj.classList.add("modifying");
    obj.contentEditable = true;
    obj.addEventListener("keydown", keyCell);
    obj.focus();
  }
}

function key(event) {
  switch (event.key) {
    case "Enter":
      modifCell(document.querySelector(".selected"));
      event.preventDefault();
      break;
    case "ArrowRight":
      ArrowMove(1, 0);
      break;
    case "ArrowLeft":
      ArrowMove(-1, 0);
      break;
    case "ArrowUp":
      ArrowMove(0, -1);
      break;
    case "ArrowDown":
      ArrowMove(0, 1);
      break;
  }
}

function ArrowMove(x, y) {
  if (
    document.querySelector(".modifying") ||
    !document.querySelector(".selected")
  ) {
    return; // S'il n'y a aucune cellule selectionnée ou si une cellule est encours de modification, on ne change pas
  }

  let selected = document.querySelector(".selected");
  let next = document.querySelector(
    `[data-x="${parseInt(selected.dataset.x) + x}"][data-y="${
      parseInt(selected.dataset.y) + y
    }"][data-editable="true"]`
  );

  if (next) {
    selectCell(next);
  }
}

function keyCell(event) {
  if (event.key == "Enter") {
    event.preventDefault();
    event.stopPropagation();
    if (!save(this)) {
      return;
    }
    this.classList.remove("modifying");
    let selected = document.querySelector(".selected");
    ArrowMove(0, 1);
    if (selected != document.querySelector(".selected")) {
      modifCell(document.querySelector(".selected"));
    }
  }
}

function processSums() {
  let sum = 0;
  document
    .querySelectorAll(
      `[data-editable="true"][data-x="${this.dataset.x}"]:not(:empty)`
    )
    .forEach((e) => {
      let val = parseFloat(e.innerText);
      if (!isNaN(val)) {
        sum += val * 100;
      }
    });
  document.querySelector(
    `.sums[data-x="${this.dataset.x}"][data-y="${lastY}"]`
  ).innerText = (sum / 100).toLocaleString(undefined, {
    minimumFractionDigits: 0,
    maximumFractionDigits: 2,
  });

  sum = 0;
  document
    .querySelectorAll(
      `[data-editable="true"][data-y="${this.dataset.y}"]:not(:empty)`
    )
    .forEach((e) => {
      let val = parseFloat(e.innerText);
      if (!isNaN(val)) {
        sum += val * 100;
      }
    });
  document.querySelector(
    `.sums[data-x="${lastX}"][data-y="${this.dataset.y}"]`
  ).innerText = (sum / 100).toLocaleString(undefined, {
    minimumFractionDigits: 0,
    maximumFractionDigits: 2,
  });
}

/******************************/
/* Affichage d'un message     */
/******************************/
function message(msg) {
  var div = document.createElement("div");
  div.className = "message";
  div.innerHTML = msg;
  document.querySelector("body").appendChild(div);
  setTimeout(() => {
    div.remove();
  }, 3000);
}
