import {
  DyflexisEmployee,
  EmployeeDyflexisStaging,
  Prisma,
} from '@prisma/client';

export class EmployeeDyflexisLoader {
  public static determineLoadOperations(
    stagingEmployees: EmployeeDyflexisStaging[],
    finalEmployees: DyflexisEmployee[],
  ): {
    deleted: number[];
    updated: Prisma.DyflexisEmployeeCreateInput[];
    created: Prisma.DyflexisEmployeeCreateInput[];
  } {
    const deletedEmployees = finalEmployees.filter(
      (finalEmployee) =>
        !stagingEmployees.find(
          (stagingEmployee) => stagingEmployee.id === finalEmployee.id,
        ),
    );

    const employeesToInsert = stagingEmployees.filter(
      ({ id }) =>
        !!id &&
        !deletedEmployees.find((deletedEmployee) => deletedEmployee.id === id),
    );
    const newEmployees: Prisma.DyflexisEmployeeCreateInput[] = [];
    const updatedEmployees: Prisma.DyflexisEmployeeCreateInput[] = [];

    for (const stagingEmployee of employeesToInsert) {
      const finalEmployee = finalEmployees.find(
        (finalEmployee) => finalEmployee.id === stagingEmployee.id,
      );
      if (finalEmployee) {
        updatedEmployees.push(this.employeeStagingToFinal(stagingEmployee));
      } else {
        newEmployees.push(this.employeeStagingToFinal(stagingEmployee));
      }
    }
    return {
      deleted: deletedEmployees.map(({ id }) => id),
      updated: updatedEmployees,
      created: newEmployees,
    };
  }

  private static employeeStagingToFinal(
    employee: EmployeeDyflexisStaging,
  ): Prisma.DyflexisEmployeeCreateInput {
    const {
      id,
      firstname,
      surname,
      contractStart,
      contractEnd,
      contractHoursWeek,
      contractSalaryHour,
    } = employee;

    return {
      id,
      firstname,
      surname,
      contractStart,
      contractEnd,
      contractHoursWeek,
      contractSalaryHour,
    };
  }
}
