async function saveDirtyGrids(Parentid) {
  debugger
  const params = new URLSearchParams(window.location.search);
  if (Parentid) {
    var ParentID = Parentid;
  } else {
    var ParentID = params.get("ItemID");
  }

  const grids = document.querySelectorAll(".K_Dirty_Grid");

  for (const grid of grids) {
    const siteUrl = grid.getAttribute("siteurl");
    const listName = grid.getAttribute("listname");
    const ParentList = grid.getAttribute("parentlist");

    if (!siteUrl || !listName) {
      console.warn("Grid missing SiteURL or ListName:", grid);
      continue;
    }

    const rows = grid.querySelectorAll(".K_Dirty_Tr");

    for (const tr of rows) {
      const itemId = tr.getAttribute("K_Item_ID");
      const body = {};

      // defaults columns
      if (grid.getAttribute("defaultColumns")) {
        defaultColumns = JSON.parse(grid.getAttribute("defaultcolumns"));

        for (const dcol of defaultColumns) {
          for (
            var dcolIndex = 0;
            dcolIndex < Object.entries(dcol).length;
            dcolIndex++
          ) {
            const [key, value] = Object.entries(dcol)[dcolIndex];
            body[key] = value;
          }
        }
      }

      // default global columns
      debugger
      if (grid.getAttribute("defaultglobalcolumns")) {
        defaultGlobalColumns = JSON.parse(
          grid.getAttribute("defaultglobalcolumns")
        );

        for (const dcol of defaultGlobalColumns) {
          for (
            var dcolIndex = 0;
            dcolIndex < Object.entries(dcol).length;
            dcolIndex++
          ) {
            const [key, value] = Object.entries(dcol)[dcolIndex];
            body[key] = document.getElementById("Form").getAttribute(value);
          }
        }
      }

      // collect inputs
      const inputs = tr.querySelectorAll("[id^='K_Grid_Input_']");

      inputs.forEach((input) => {
        const id = input.id;

        const parts = id.split("_");

        const columnName = parts[4];
        if (input.classList.contains("p-date-picker")) {
          datesArray = input.value.split("/");

          if (input.value != "") {
            body[columnName] = new Date(
              farvardin.solarToGregorian(
                parseInt(datesArray[0]),
                parseInt(datesArray[1]),
                parseInt(datesArray[2])
              )
            );
          }
        } else if (input.getAttribute("lookup")) {
          body[columnName + "Id"] = input.value;
        } else {
          body[columnName] = input.value;
        }
      });

      if (itemId.includes("NewItem")) {
        await spAddItem(siteUrl, listName, body, ParentID, ParentList);
      } else if (!isNaN(itemId)) {
        await spUpdateItem(siteUrl, listName, itemId, body);
      }
    }
  }
}

async function spAddItem(siteUrl, listName, body, ParentID, ParentList) {
  body["__metadata"] = { type: await getListItemType(siteUrl, listName) };

  if (ParentID) {
    body[ParentList + "Id"] = ParentID;
  }
  const endpoint = `${siteUrl}/_api/web/lists/getByTitle('${listName}')/items`;

  const result = 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(body),
  });

  if (!result.ok) {
    console.error("ADD FAILED:", await result.text());
  } else {
    console.log("Item Added:", await result.json());
  }
}

async function spUpdateItem(siteUrl, listName, itemId, body) {
  body["__metadata"] = { type: await getListItemType(siteUrl, listName) };

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

  const result = await fetch(endpoint, {
    method: "POST",
    headers: {
      Accept: "application/json;odata=verbose",
      "Content-Type": "application/json;odata=verbose",
      "IF-MATCH": "*",
      "X-HTTP-Method": "MERGE",
      "X-RequestDigest": document.getElementById("__REQUESTDIGEST").value,
    },
    body: JSON.stringify(body),
  });

  if (!result.ok) {
    console.error("UPDATE FAILED:", await result.text());
  } else {
    console.log("Item Updated");
  }
}

async function getListItemType(siteUrl, listName) {
  const endpoint = `${siteUrl}/_api/web/lists/getByTitle('${listName}')?$select=ListItemEntityTypeFullName`;

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

  const data = await response.json();
  return data.d.ListItemEntityTypeFullName;
}

async function saveDirtyInputsToSharePoint(siteUrl, listName) {
  const params = new URLSearchParams(window.location.search);
  let itemId = params.get("ItemID");

  // find only the editable inputs
  const inputs = document.querySelectorAll(".K_Dirty_Input");

  const payload = {};

  for(var inp=0; inp<inputs.length; inp++) {
    var input = inputs[inp];
    if (input.getAttribute("save") == "true") {
      const parts = input.id.split("_");
      if (parts.length !== 2) return;

      const fieldName = parts[1];

      if (input.classList.contains("kform-radio-group")) {
        const allOptions = document.querySelectorAll(
          "[id^='" + input.id + "_']"
        );
        let checkedOption = "";
        allOptions.forEach((opt) => {
          if (opt.checked) checkedOption = opt.value;
        });
        payload[fieldName] = checkedOption;
      } else if (input.classList.contains("kform-multilookup")) {
        payload[fieldName + "Id"] = { results: input.getValue() };
      } else if (input.classList.contains("kform-lookup-select")) {
        if (input.getAttribute("saveId") == "true") {
          if (input.value == "") {
            payload[fieldName] = null;
          } else {
            payload[fieldName] = input.value;
          }
        } else if (input.getAttribute("saveId") == "false") {
          if (input.value == "") {
            payload[fieldName.replace("Id", "")] = null;
          } else {
            payload[fieldName.replace("Id", "")] = input.value;
          }
        }
      } else if (input.classList.contains("p-date-picker")) {
        datesArray = input.value.split("/");

        if (input.value != "") {
          payload[fieldName] = new Date(
            farvardin.solarToGregorian(
              parseInt(datesArray[0]),
              parseInt(datesArray[1]),
              parseInt(datesArray[2])
            )
          );
        }
      } else if (input.getAttribute("input-type") == "userpicker") {
        payload[fieldName] = await ensureUser(
          _spPageContextInfo.webAbsoluteUrl,
          input.dataset.login
        );
      } else if (input.getAttribute("type") == "number") {
        inputValue = input.value;
        if (inputValue == "") {
          inputValue = null;
        }
        payload[fieldName] = inputValue;
      } else {
        payload[fieldName] = input.value;
      }
    }
  };

  payload.__metadata = { type: await getListItemType(siteUrl, listName) };

  let endpoint = `${siteUrl}/_api/web/lists/getbytitle('${listName}')/items`;
  let method = "POST"; // default to create

  if (itemId && itemId !== "NewItem") {
    endpoint += `(${itemId})`;
    method = "MERGE"; // update existing
  }

  const response = await fetch(endpoint, {
    method: method,
    headers: {
      Accept: "application/json;odata=verbose",
      "Content-Type": "application/json;odata=verbose",
      "X-RequestDigest": document.getElementById("__REQUESTDIGEST").value,
      "IF-MATCH": "*",
      "X-HTTP-Method": method === "MERGE" ? "MERGE" : undefined,
    },
    body: JSON.stringify(payload),
  });

  // Only parse JSON if there is content
  let data = null;
  const text = await response.text();
  if (text) {
    data = JSON.parse(text);
  }

  if (!response.ok) {
    throw new Error("Failed to save item: " + text);
  }

  // Return new ID if created, else existing ID
  return itemId === "NewItem" ? data?.d?.ID : itemId;
}

async function K_Save(Close, siteUrl, listName) {
  showLoader();
  var itemId = await saveDirtyInputsToSharePoint(siteUrl, listName);
  await saveDirtyGrids(itemId);
  if (Close) {
    if (window.parent.document.getElementById("FormOverlay") != null) {
      window.parent.document.body.removeChild(
        window.parent.document.getElementById("FormOverlay")
      );
    } else {
      location.reload();
    }
  }
}

async function ensureUser(siteUrl, loginName) {
  const res = await fetch(`${siteUrl}/_api/web/ensureuser`, {
    method: "POST",
    headers: {
      Accept: "application/json;odata=verbose",
      "Content-Type": "application/json;odata=verbose",
      "X-RequestDigest": document.getElementById("__REQUESTDIGEST").value,
    },
    body: JSON.stringify({ logonName: loginName }),
  });

  const data = await res.json();
  return data.d.Id;
}
