// Function to sort an array of objects by parentId
import { groupBy } from "lodash";

const sortByParentId = (arr) => {
  let parentId = "-1";
  const sortedList = [];
  const byParentsIdsList = groupBy(arr, "kanbanparent");

  while (byParentsIdsList[parentId]) {
    sortedList.push(...byParentsIdsList[parentId]);
    parentId = byParentsIdsList[parentId][byParentsIdsList[parentId].length - 1].id;
  }

  if (byParentsIdsList["null"]) {
    sortedList.push(...byParentsIdsList["null"]);
  }

  // Ensure all items are included in the sorted list
  if (arr.length !== sortedList.length) {
    arr.forEach((origItem) => {
      if (!sortedList.some((s) => s.id === origItem.id)) {
        sortedList.push(origItem);
      }
    });
  }

  return sortedList;
};

// Function to create board data based on statuses and jobs, with optional filtering
export const createBoardData = ({ statuses, data, filter, cardSettings }) => {
  const { search, employeeId, alert, unassigned } = filter;

  const lanes = statuses.map((status) => ({
    id: status,
    title: status,
    cards: []
  }));

  let filteredJobs =
    (search === "" || !search) && !employeeId ? data : data.filter((job) => checkFilter(search, employeeId, job));

  // Apply "Unassigned" filter
  if (unassigned) {
    filteredJobs = filteredJobs.filter(
      (job) => !job.employee_body && !job.employee_prep && !job.employee_refinish && !job.employee_csr
    );
  }

  // Filter jobs by selectedMdInsCos if it has values
  if (cardSettings?.selectedMdInsCos?.length > 0) {
    filteredJobs = filteredJobs.filter((job) => cardSettings.selectedMdInsCos.includes(job.ins_co_nm));
  }

  // Filter jobs by selectedEstimators if it has values
  if (cardSettings?.selectedEstimators?.length > 0) {
    filteredJobs = filteredJobs.filter((job) =>
      cardSettings.selectedEstimators.includes(`${job.est_ct_fn} ${job.est_ct_ln}`)
    );
  }

  // Filter jobs by alert if alert filter is true
  if (alert) {
    filteredJobs = filteredJobs.filter((job) => job.production_vars?.alert);
  }

  const DataGroupedByStatus = groupBy(filteredJobs, "status");

  Object.keys(DataGroupedByStatus).forEach((statusGroupKey) => {
    try {
      const lane = lanes.find((l) => l.id === statusGroupKey);
      if (!lane) return;

      lane.cards = sortByParentId(DataGroupedByStatus[statusGroupKey]).map((job) => {
        const { id, title, description, due_date, ...metadata } = job;
        return {
          id,
          title,
          description,
          label: due_date || "",
          metadata
        };
      });
    } catch (error) {
      console.error("Error while creating board card", error);
    }
  });

  return { lanes };
};

// Function to check if a job matches the search and/or employeeId filter
const checkFilter = (search, employeeId, job) => {
  const lowerSearch = search?.toLowerCase() ?? "";

  const matchesSearch =
    lowerSearch &&
    [
      job.ro_number,
      job.ownr_fn,
      job.ownr_co_nm,
      job.ownr_ln,
      job.status,
      job.v_make_desc,
      job.v_model_desc,
      job.clm_no,
      job.plate_no
    ].some((field) => field?.toLowerCase().includes(lowerSearch));

  const matchesEmployeeId =
    employeeId && [job.employee_body, job.employee_prep, job.employee_csr, job.employee_refinish].includes(employeeId);

  return matchesSearch || matchesEmployeeId;
};
