import { GET_ALL_JOBLINES_BY_PK } from "../../graphql/jobs-lines.queries";
import { gql } from "@apollo/client";
import _ from "lodash";

export const GetSupplementDelta = async (client, jobId, newLines) => {
  const {
    data: { joblines: existingLinesFromDb },
  } = await client.query({
    query: GET_ALL_JOBLINES_BY_PK,
    variables: { id: jobId },
  });

  const existingLines = _.cloneDeep(existingLinesFromDb);
  const linesToInsert = [];
  const linesToUpdate = [];

  newLines.forEach((newLine) => {
    const matchingIndex = existingLines.findIndex(
      (eL) => eL.unq_seq === newLine.unq_seq
    );

    //Should do a check to make sure there is only 1 matching unq sequence number.

    if (matchingIndex >= 0) {
      //Found a relevant matching line. Add it to lines to update.
      linesToUpdate.push({
        id: existingLines[matchingIndex].id,
        newData: { ...newLine, removed: false },
      });

      //Splice out item we found for performance.
      existingLines.splice(matchingIndex, 1);
    } else {
      //Didn't find a match. Must be a new line.
      linesToInsert.push(newLine);
    }
  });

  //Wahtever is left in the existing lines, are lines that should be removed.
  const insertQueries = linesToInsert.reduce((acc, value, idx) => {
    return acc + generateInsertQuery(value, idx, jobId);
  }, "");

  const updateQueries = linesToUpdate.reduce((acc, value, idx) => {
    return acc + generateUpdateQuery(value, idx);
  }, "");

  const removeQueries = existingLines
    .filter((l) => !l.manual_line)
    .reduce((acc, value, idx) => {
      return acc + generateRemoveQuery(value, idx);
    }, "");
  console.log(insertQueries, updateQueries, removeQueries);

  if ((insertQueries + updateQueries + removeQueries).trim() === "") {
    return new Promise((resolve, reject) => {
      resolve(null);
    });
  }

  return new Promise((resolve, reject) => {
    resolve(gql`
    mutation SUPPLEMENT_EST_LINES{
      ${insertQueries + updateQueries + removeQueries}
    }
    `);
  });
};

const generateInsertQuery = (lineToInsert, index, jobId) => {
  return `
  insert_joblines${index}: insert_joblines(objects: ${JSON.stringify({
    ...lineToInsert,
    jobid: jobId,
  }).replace(/"(\w+)"\s*:/g, "$1:")}) {
      returning {
        id
      }
    }`;
};

const generateUpdateQuery = (lineToUpdate, index) => {
  return `
  update_joblines${index}: update_joblines(where: { id: { _eq: "${
    lineToUpdate.id
  }" } }, _set: ${JSON.stringify(lineToUpdate.newData).replace(
    /"(\w+)"\s*:/g,
    "$1:"
  )}) {
    returning {
      id
    }
  }`;
};

const generateRemoveQuery = (lineToRemove, index) => {
  return `
  update_joblines_r${index}: update_joblines(where: {id: {_eq: "${lineToRemove.id}"}}, _set: {removed: true}) {
    returning{
      id
    }
  }`;
};
