import { Employee, EmployeeDispoLiveStaging, Prisma } from '@prisma/client';

export class EmployeeDispoliveLoader {
  public static determineLoadOperations(
    stagingEmployees: EmployeeDispoLiveStaging[],
    finalEmployees: Employee[],
  ): {
    deleted: string[];
    updated: Prisma.EmployeeCreateInput[];
    created: Prisma.EmployeeCreateInput[];
  } {
    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.EmployeeCreateInput[] = [];
    const updatedEmployees: Prisma.EmployeeCreateInput[] = [];

    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: EmployeeDispoLiveStaging,
  ): Prisma.EmployeeCreateInput {
    const {
      id,
      name,
      surname,
      personnelNumber,
      qualification,
      personTransportCertificate,
    } = employee;

    return {
      id,
      name,
      surname,
      personnelNumber,
      qualification,
      personTransportCertificate,
    };
  }
}
