var newRowCount = 0;

async function getSharePointListItems({ site, listName, query }) {
  const endpoint = `${site}/_api/web/lists/getbytitle('${listName}')/GetItems`;

  const response = await fetch(endpoint, {
    method: "POST",
    headers: {
      Accept: "application/json;odata=verbose",
      "Content-Type": "application/json;odata=verbose",
      "X-RequestDigest": document.getElementById("__REQUESTDIGEST").value,
    },
    body: JSON.stringify({
      query: {
        __metadata: { type: "SP.CamlQuery" },
        ViewXml: query,
      },
    }),
  });

  if (!response.ok) throw new Error("SharePoint query failed");

  const data = await response.json();

  return data.d.results; // array of items
}

function DeleteListSelectedItem(site, listName, itemId) {
  return fetch(
    `${site}/_api/web/lists/getbytitle('${listName}')/items(${itemId})`,
    {
      method: "POST",
      headers: {
        Accept: "application/json;odata=verbose",
        "Content-Type": "application/json;odata=verbose",
        "X-RequestDigest": document.getElementById("__REQUESTDIGEST").value,
        "IF-MATCH": "*",
        "X-HTTP-Method": "DELETE",
      },
    }
  );
}

async function getLookupValue(siteUrl, listName, itemId, columnName) {
  showLoader();

  try {
    const endpoint = `${siteUrl}/_api/web/lists/getbytitle('${listName}')/items(${itemId})`;

    const response = await fetch(endpoint, {
      method: "GET",
      headers: { Accept: "application/json;odata=verbose" },
    });

    if (!response.ok) throw new Error("Failed to fetch item.");

    const data = await response.json();

    const item = data.d[columnName];

    hideLoader();
    return item;
  } catch (err) {
    hideLoader();
  }
}

async function CreateGrid(container, config, initialData) {
  let data = initialData ?? []; // use provided data or empty array

  showLoader();

  if (config.dataSource && !initialData) {
    try {
      const items = await getSharePointListItems(config.dataSource);
      data = items.map((item) => {
        const row = {};
        config.columns.forEach((col) => {
          if (col.type == "date") {
            if (item[col.name] != undefined) {
              row[col.name] = new Date(item[col.name]).toLocaleDateString(
                "fa-IR-u-nu-latn"
              );
            } else {
              row[col.name] = "";
            }
          } else if (col.type == "lookup") {
            if (item[col.name + "Id"] != null) {
              row[col.name + "Id"] = item[col.name + "Id"];
            } else {
              row[col.name + "Id"] = "";
            }
          } else {
            row[col.name] = item[col.name] ?? "";
          }
        });
        row["ID"] = item.ID;
        return row;
      });
    } catch (err) {
      console.error("Error fetching SharePoint list items:", err);
    }
  }

  hideLoader();

  CreateGridFromSharePoint(container, config, data);
}

async function CreateGridFromSharePoint(container, config, data) {
  const {
    gridName = "Grid",
    gridDisplayName = gridDisplayName ? gridDisplayName : gridName,
    columns = [],
    showColumns = true,
    showEditButton = false,
    showDelteButton = false,
    onEdit = (rowData) => console.log("Edit", rowData),
    ParentList = ParentList,
  } = config;

  var AllInputs = [];

  container = document.getElementById(container);

  let parentWrapper = container.querySelector("#Parent_Wrapper_" + gridName);

  if (!parentWrapper) {
    parentWrapper = document.createElement("div");
    parentWrapper.id = "Parent_Wrapper_" + gridName;
    parentWrapper.style.width = "100%";
    parentWrapper.style.position = "relative";
    container.appendChild(parentWrapper);
  }

  let gridContainer = parentWrapper.querySelector("#K_Grid_" + gridName);
  if (gridContainer) gridContainer.remove();

  const gridWrapper = document.createElement("div");

  if (config.defaultColumns)
    gridWrapper.setAttribute("defaultcolumns", config.defaultColumns);

  if (config.defaultGlobalColumns) {
    gridWrapper.setAttribute(
      "defaultglobalcolumns",
      config.defaultGlobalColumns
    );
  }

  gridWrapper.id = "K_Grid_" + gridName;
  gridWrapper.setAttribute("siteuRL", config.dataSource.site);
  gridWrapper.setAttribute("listname", config.dataSource.listName);
  gridWrapper.setAttribute("parentlist", ParentList);
  gridWrapper.style.position = "relative";
  gridWrapper.style.width = config.width || "100%";
  gridWrapper.style.padding = "12px";
  gridWrapper.style.boxSizing = "border-box";

  const displayNameDiv = document.createElement("label");
  displayNameDiv.textContent = gridDisplayName;
  displayNameDiv.style.fontSize = "16px";
  displayNameDiv.style.color = "#333";
  displayNameDiv.style.padding = "0 12px";

  var showGridName =
    config.showGridDisplayName != undefined ? config.showGridDisplayName : true;
  if (showGridName) {
    gridWrapper.appendChild(displayNameDiv);
  }

  const table = document.createElement("table");
  table.style.width = "100%";
  table.style.borderSpacing = "10px";
  table.style.borderCollapse = "separate";
  table.style.tableLayout = "fixed";
  if (!showColumns) table.style.marginTop = "-50px";

  // ==========================
  // HEADER
  // ==========================

  const thead = document.createElement("thead");
  const tr = document.createElement("tr");

  columns.forEach((col) => {
    const th = document.createElement("th");
    th.textContent = col.displayName ?? col.name;
    th.style.textAlign = "center";
    th.style.padding = "8px";
    th.style.borderRadius = "10px";
    th.style.width = col.width ?? "100%";
    if (showColumns) {
      th.style.backgroundColor = col.backgroundColor || "#FFC000";
    } else {
      th.style.backgroundColor = "transparent";
      th.style.color = "transparent";
    }
    tr.appendChild(th);
  });

  // ADD ROW BUTTON
  const thAdd = document.createElement("th");

  const btnAdd = document.createElement("button");
  btnAdd.textContent = "+";
  btnAdd.style.background = "transparent";
  btnAdd.style.border = "none";
  btnAdd.style.cursor = "pointer";
  btnAdd.style.fontSize = "20px";
  btnAdd.style.minWidth = "0";
  btnAdd.style.margin = "0";
  btnAdd.style.width = "50px";
  btnAdd.style.padding = "0px";

  btnAdd.onclick = (event) => {
    event.preventDefault();
    const newRow = {};
    columns.forEach((c) => (newRow[c.name] = ""));
    newRow.ID = "NewItem_" + newRowCount++;
    newRow.isDirty = true;
    data.push(newRow);
    CreateGrid(container.id, config, data);
  };

  thAdd.style.width = "50px";
  thAdd.style.height = "42px";
  thAdd.style.padding = "0px";

  thAdd.appendChild(btnAdd);
  tr.appendChild(thAdd);

  thead.appendChild(tr);
  table.appendChild(thead);

  // ==========================
  // BODY
  // ==========================
  const tbody = document.createElement("tbody");

  await data.forEach(async (rowData) => {
    const tr = document.createElement("tr");

    if (typeof rowData.ID != "string") {
      tr.setAttribute("K_Item_ID", rowData.ID);
    } else {
      tr.setAttribute("K_Item_ID", "NewItem");
    }

    if (rowData.isDirty) {
      gridWrapper.classList.add("K_Dirty_Grid");
      tr.classList.add("K_Dirty_Tr");
    }

    for (const col of columns) {
      const td = document.createElement("td");
      td.style.width = col.width ?? "100%";
      td.style.padding = "0";

      let input;

      // ------------------------
      // INPUT TYPE
      // ------------------------
      switch (col.type) {
        case "number":
          input = document.createElement("input");
          input.type = "number";
          break;

        case "date":
          input = document.createElement("input");
          input.type = "text";
          input.placeholder = "تاریخ را وارد کنید";
          input.classList.add("p-date-picker");
          input.setAttribute("data-jdp", true);
          break;

        case "combobox":
          input = document.createElement("select");
          col.options?.forEach((opt) => {
            const option = document.createElement("option");
            option.value = opt;
            option.textContent = opt;
            input.appendChild(option);
          });
          break;

        case "lookup":
          input = document.createElement("select");
          input.setAttribute("lookup", true);

          input.setAttribute("lookupsite", col.lookupSite);
          input.setAttribute("lookuplist", col.lookupList);
          input.setAttribute("lookupcolumn", col.lookupColumn);

          // placeholder
          const placeholder = document.createElement("option");
          input.appendChild(placeholder);

          var url = `${col.lookupSite}/_api/web/lists/getbytitle('${col.lookupList}')/items?$select=${col.lookupColumn},Id`;

          if (col.filter) {
            url += `&$filter=${col.filter}`;
          }
          await fetch(url, {
            headers: {
              Accept: "application/json;odata=nometadata",
            },
          })
            .then((res) => res.json())
            .then((data) => {
              data.value.forEach((item) => {
                const option = document.createElement("option");
                option.value = item["Id"];
                option.textContent = item[col.lookupColumn];

                input.appendChild(option);
              });
            })
            .catch((err) => {
              console.error("Lookup load failed:", err);
            });
          break;

        default:
          input = document.createElement("input");
          input.setAttribute("input-type", "text");
          input.type = "text";
      }

      // ------------------------
      // UNIQUE ID FORMAT
      // ------------------------
      // K_Grid_Input_<gridName>_<actualName>
      if (typeof rowData.ID != "string")
        input.id = `K_Grid_Input_${gridName}_${col.name}_${rowData.ID}`;
      else input.id = `K_Grid_Input_${gridName}_${col.name}_NewItem`;

      // ------------------------
      // VALUE SYNC
      // ------------------------

      if (col.type == "lookup" && !input.id.includes("NewItem")) {
        if (rowData[col.name + "Id"] != "") {
          input.value =
            rowData[col.name + "Id"] == undefined
              ? ""
              : rowData[col.name + "Id"];
        } else {
          input.value = "";
        }
      } else {
        input.value = rowData[col.name] ?? "";
      }

      AllInputs.push(input);

      if (col.onchangefunction) {
        input.addEventListener("change", col.onchangefunction);
      }

      input.oninput = () => {
        rowData[col.name] = input.value;

        tr.classList.add("K_Dirty_Tr");

        rowData.isDirty = true;

        gridWrapper.classList.add("K_Dirty_Grid");
      };

      // ------------------------
      // STYLING
      // ------------------------
      input.style.width = "100%";
      input.style.boxSizing = "border-box";
      input.style.border = "1px solid gray";
      input.style.borderRadius = "6px";
      input.style.padding = "8px";
      input.style.textAlign = col.textAlign;
      if (col.disabled == true) {
        input.disabled = true;
        input.style.color;
      }

      td.appendChild(input);
      tr.appendChild(td);
    }

    // ==========================
    // EDIT BUTTON
    // ==========================
    const params = new URLSearchParams(window.location.search);
    const ItemID = params.get("ItemID");

    if (showEditButton) {
      const tdEdit = document.createElement("td");
      const btn = document.createElement("button");

      btn.onclick = (event) => {
        event.preventDefault();
        onEdit(rowData, [container.id, config, JSON.stringify(data)]);
      };

      if (ItemID == "NewItem") {
        var tooltip = document.createElement("span");

        btn.appendChild(tooltip);

        btn.style.position = "relative";

        tooltip.classList.add("tooltip-text");
        tooltip.style.visibility = "hidden";
        tooltip.style.position = "absolute";
        tooltip.style.width = "200px";
        tooltip.style.bottom = "125%";
        tooltip.style.left = "0px";
        tooltip.style.background = "#333";
        tooltip.style.color = "white";
        tooltip.style.padding = "6px 10px";
        tooltip.style.borderRadius = "4px";
        tooltip.style.fontSize = "18px";
        tooltip.style.whiteSpace = "nowarp";

        tooltip.innerText = "برای ویرایش لطفا فرم را یک بار ذخیره نمایید.";

        btn.addEventListener("mouseenter", () => {
          tooltip.style.visibility = "visible";
        });
        btn.addEventListener("mouseleave", () => {
          tooltip.style.visibility = "hidden";
        });
        btn.disabled = true;
      }

      btn.style.backgroundImage =
        "url(data:image/png;base64,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)";
      btn.style.backgroundSize = "20px 20px";
      btn.style.backgroundRepeat = "no-repeat";
      btn.style.backgroundPosition = "67% 50%";
      btn.style.cursor = "pointer";
      btn.style.border = "none";
      btn.style.backgroundColor = "transparent";
      btn.style.margin = "0";
      btn.style.width = "50px";
      btn.style.height = "50px";
      btn.style.padding = "0px";

      tdEdit.style.width = "50px";
      tdEdit.style.height = "50px";
      tdEdit.style.padding = "0px";

      tdEdit.appendChild(btn);
      tr.appendChild(tdEdit);

      tbody.appendChild(tr);
    }

    // ==========================
    // Delete BUTTON
    // ==========================
    if (showDelteButton) {
      const tdEdit = document.createElement("td");
      const btn = document.createElement("button");

      btn.onclick = async (event) => {
        console.log(data);
        console.log(rowData["ID"]);
        event.preventDefault();

        var okToDelte = confirm("آیا از حذف مورد اطمینان دارید؟");
        if (okToDelte) {
          await DeleteListSelectedItem(
            config.dataSource.site,
            config.dataSource.listName,
            rowData["ID"]
          );
          data = data.filter((item) => item.ID != rowData["ID"]);
        }

        CreateGrid(container.id, config, data);
      };

      btn.innerHTML = "&#10006;";
      btn.style.backgroundSize = "20px 20px";
      btn.style.backgroundRepeat = "no-repeat";
      btn.style.backgroundPosition = "67% 50%";
      btn.style.cursor = "pointer";
      btn.style.border = "none";
      btn.style.backgroundColor = "transparent";
      btn.style.margin = "0";
      btn.style.width = "50px";
      btn.style.height = "50px";
      btn.style.padding = "0px";
      btn.style.paddingLeft = "30%";

      tdEdit.style.width = "50px";
      tdEdit.style.height = "50px";
      tdEdit.style.padding = "0px";

      tdEdit.appendChild(btn);
      tr.appendChild(tdEdit);

      tbody.appendChild(tr);
    }

    EndDatas();
  });

  if (data.length == 0) {
    EndDatas();
  }

  function EndDatas() {
    table.appendChild(tbody);
    gridWrapper.appendChild(table);
    parentWrapper.appendChild(gridWrapper);

    AllInputs.forEach((inp) => {
      inp.dispatchEvent(new Event("change", { bubbles: true }));
    });
  }
}

async function setRowLookupOptions(element, column, filter) {
  var tr = element.parentNode.parentNode;

  var idParts = element.id.split("_");
  idParts[4] = column;

  var newId = idParts.join("_");

  var filterSelect = tr.querySelector(`#${newId}`);

  const lookupSite = filterSelect.getAttribute("lookupSite");
  const lookupList = filterSelect.getAttribute("lookupList");
  const lookupColumn = filterSelect.getAttribute("lookupColumn");

  filterSelect.innerHTML = "";

  // placeholder
  const placeholder = document.createElement("option");
  filterSelect.appendChild(placeholder);

  var apiUrl = `${lookupSite}/_api/web/lists/getbytitle('${lookupList}')/items?$select=${lookupColumn},Id`;
  if (filter) {
    apiUrl += `&$filter=${filter}`;
  }

  const response = await fetch(apiUrl, {
    headers: {
      Accept: "application/json;odata=nometadata",
    },
  });

  data = await response.json();
  data.value.forEach((item) => {
    const option = document.createElement("option");
    option.value = item["Id"];
    option.textContent = item[lookupColumn];

    filterSelect.appendChild(option);
  });
}

async function setRowComboboxOptions(element, column, options) {
  var tr = element.parentNode.parentNode;

  var idParts = element.id.split("_");
  idParts[4] = column;

  var newId = idParts.join("_");

  var filterSelect = tr.querySelector(`#${newId}`);

  filterSelect.innerHTML = "";

  // placeholder
  const placeholder = document.createElement("option");
  filterSelect.appendChild(placeholder);

  options.forEach((item) => {
    const option = document.createElement("option");
    option.value = item;
    option.textContent = item;

    filterSelect.appendChild(option);
  });
}

function setRowInputValue(element, column, value) {
  var tr = element.parentNode.parentNode;

  var idParts = element.id.split("_");
  idParts[4] = column;

  var newId = idParts.join("_");

  var filterInput = tr.querySelector(`#${newId}`);

  filterInput.value = value;
}
