import { getDataRowId, getParentId } from "./rowUtils";

export function setNewValueToData(data, colId, rowId, value) {
  let targetObject = data;
  if (rowId && rowId.length) {
    const indices = rowId.split(".").map(Number);
    for (let i = 0; i < indices.length; i++) {
      const index = indices[i];
      if (targetObject && targetObject[index] !== undefined) {
        targetObject = targetObject[index];
      } else {
        console.error(`Индекс ${index} не найден на уровне ${i}`);
        return false;
      }

      // Если это не последний индекс, переходим в subRows
      if (i < indices.length - 1) {
        if (targetObject.subRows && Array.isArray(targetObject.subRows)) {
          targetObject = targetObject.subRows;
        } else {
          console.error(`Нет subRows для перехода на уровне ${i}`);
          return false;
        }
      }
    }
  }

  const keys = colId.split(".");
  const lastKey = keys.pop();

  // Идем по вложенности path
  let current = targetObject;
  for (let i = 0; i < keys.length; i++) {
    const key = keys[i];
    if (!current[key]) {
      current[key] = {};
    }
    current = current[key];
  }

  current[lastKey] = value;

  return true;
}

export function updateCells(data, newRows) {
  const updatedRows = structuredClone(data);

  function deepMerge(target, source) {
    if (!source || typeof source !== "object") {
      return source;
    }
    if (!target || typeof target !== "object") {
      target = {};
    }

    Object.keys(source).forEach((key) => {
      if (
        source[key] &&
        typeof source[key] === "object" &&
        !Array.isArray(source[key])
      ) {
        target[key] = deepMerge(target[key], source[key]);
      } else {
        target[key] = source[key];
      }
    });

    return target;
  }

  newRows.forEach((update) => {
    const [rowType, depth, sortOrder, newData] = update;

    // Рекурсивная функция для поиска и обновления строки
    function findAndUpdate(rows) {
      for (let i = 0; i < rows.length; i++) {
        const row = rows[i];

        if (
          row.row_type === rowType &&
          row.depth === depth &&
          row.sort_order === sortOrder
        ) {
          if (newData && typeof newData === "object") {
            Object.keys(newData).forEach((key) => {
              if (row.data && row.data[key] !== undefined) {
                row.data[key] = deepMerge(row.data[key], newData[key]);
              } else if (row[key]) {
                row[key] = newData[key];
              }
            });
          }
          return true;
        }

        if (
          row.subRows &&
          Array.isArray(row.subRows) &&
          row.subRows.length > 0
        ) {
          const found = findAndUpdate(row.subRows);
          if (found) return true;
        }
      }
      return false;
    }

    findAndUpdate(updatedRows);
  });
  return updatedRows;
}

export function addRootRow(data, newRowRoot) {
  function updateSortOrder(rows) {
    for (let i = 0; i < rows.length; i++) {
      const row = rows[i];
      row.sort_order = row.sort_order + 1;
      if (row.subRows && Array.isArray(row.subRows) && row.subRows.length > 0) {
        const found = updateSortOrder(row.subRows);
      }
    }
  }
  updateSortOrder(data);
  const [row_type, depth, sort_order, dataRow] = newRowRoot;
  const newRowObject = {
    row_type: row_type,
    depth: depth,
    sort_order: sort_order,
    subRows: [],
    data: dataRow,
  };

  newRowObject.subRows = data;

  return [newRowObject];
}

export function insertCell(data, newRow, parent_id) {
  const updatedRows = JSON.parse(JSON.stringify(data));
  const [row_type, depth, sort_order, dataRow] = newRow;
  const newRowObject = {
    row_type: row_type,
    depth: depth,
    sort_order: sort_order,
    subRows: [],
    data: dataRow,
  };

  // Если expense_item_id === null, добавляем в конец
  if (parent_id === null) {
    updatedRows.push(newRowObject);
    return updatedRows;
  }

  let adding = false;
  function findAndUpdate(rows) {
    for (let i = 0; i < rows.length; i++) {
      const row = rows[i];

      if (
        (row.sort_order >= newRowObject.sort_order) &
        (row.data.line_id != newRowObject.data.line_id)
      ) {
        row.sort_order = row.sort_order + 1;
      }

      if (!adding & (getParentId(row.data.header) === parent_id)) {
        if (!("subRows" in row)) {
          row.subRows = [];
        }
        row.subRows.push(newRowObject);
        adding = true;
      }

      if (row.subRows && Array.isArray(row.subRows) && row.subRows.length > 0) {
        const found = findAndUpdate(row.subRows);
      }
    }
  }
  findAndUpdate(updatedRows);
  return updatedRows;
}

export function insertProjectRow(data, newRow, program_id) {
  const updatedRows = structuredClone(data);
  const [row_type, depth, sort_order, dataRow] = newRow;
  const newRowObject = {
    row_type: row_type,
    depth: depth,
    sort_order: sort_order,
    subRows: [],
    data: dataRow,
  };

  let adding = false;
  function findAndUpdate(rows) {
    for (let i = 0; i < rows.length; i++) {
      const row = rows[i];

      if (
        (row.sort_order >= newRowObject.sort_order) &
        (row.data.line_id != newRowObject.data.line_id)
      ) {
        row.sort_order = row.sort_order + 1;
      }

      if (!adding & (row.data.header.program_id === program_id)) {
        if (!("subRows" in row)) {
          row.subRows = [];
        }
        row.subRows.push(newRowObject);
        adding = true;
      }

      if (row.subRows && Array.isArray(row.subRows) && row.subRows.length > 0) {
        const found = findAndUpdate(row.subRows);
      }
    }
  }
  findAndUpdate(updatedRows);
  return updatedRows;
}

export function deleteRow(data, lineId) {
  const updatedRows = JSON.parse(JSON.stringify(data));

  let rowDeleteSortOrder = false;
  function findAndDelete(rows) {
    for (let i = 0; i < rows.length; i++) {
      const row = rows[i];
      const rowId = getDataRowId(row.data);

      if (rowId == lineId) {
        rowDeleteSortOrder = row.sort_order;
        rows.splice(i, 1);
        i--;
      }

      if ((rowDeleteSortOrder > 0) & (row.sort_order >= rowDeleteSortOrder)) {
        row.sort_order = row.sort_order - 1;
      }

      if (row.subRows && Array.isArray(row.subRows) && row.subRows.length > 0) {
        findAndDelete(row.subRows);
      }
    }
  }
  findAndDelete(updatedRows);
  return updatedRows;
}
