import { Prisma, WorkTime, WorkTimeStaging } from '@prisma/client';

export class WorkTimeLoader {
  public static determineLoadOperations(
    stagingWorkTimes: WorkTimeStaging[],
    finalWorkTimes: WorkTime[],
  ): {
    deleted: string[];
    updated: Prisma.WorkTimeCreateInput[];
    created: Prisma.WorkTimeCreateInput[];
  } {
    const deletedWorkTimes = finalWorkTimes.filter(
      (finalWorkTime) =>
        !stagingWorkTimes.find(
          (stagingWorkTime) => `${stagingWorkTime.id}` === finalWorkTime.id,
        ),
    );
    const workTimesToInsert = stagingWorkTimes.filter(
      ({ id }) =>
        !!id &&
        !deletedWorkTimes.find(
          (deletedWorkTime) => deletedWorkTime.id === `${id}`,
        ),
    );
    const newWorkTimes: Prisma.WorkTimeCreateInput[] = [];
    const updatedWorkTimes: Prisma.WorkTimeCreateInput[] = [];
    for (const stagingWorkTime of workTimesToInsert) {
      const finalWorkTime = finalWorkTimes.find(
        (finalWorkTime) => finalWorkTime.id === `${stagingWorkTime.id}`,
      );
      if (finalWorkTime) {
        updatedWorkTimes.push(this.workTimeStagingToFinal(stagingWorkTime));
      } else {
        newWorkTimes.push(this.workTimeStagingToFinal(stagingWorkTime));
      }
    }

    return {
      deleted: deletedWorkTimes.map(({ id }) => id),
      updated: updatedWorkTimes,
      created: newWorkTimes,
    };
  }

  private static workTimeStagingToFinal(
    worktime: WorkTimeStaging,
  ): Prisma.WorkTimeCreateInput {
    const {
      id,
      employeeId,
      firstname,
      surname,
      departmentName,
      startDate,
      endDate,
    } = worktime;

    return {
      firstname,
      surname,
      startDate,
      endDate,
      id: `${id}`,
      userId: `${employeeId}`,
      department: departmentName,
      pause: 0,
      duration: 0,
    };
  }
}
