import { Prisma, Patient, PatientStaging } from '@prisma/client';

export class PatientLoader {
  public static determineLoadOperations(
    stagingPatients: PatientStaging[],
    finalPatients: Patient[],
  ): {
    deleted: string[];
    updated: Prisma.PatientCreateInput[];
    created: Prisma.PatientCreateInput[];
  } {
    const deletedPatients = finalPatients.filter(
      (finalPatient) =>
        !stagingPatients.find(
          (stagingPatient) => stagingPatient.id === finalPatient.id,
        ),
    );

    const patientsToInsert = stagingPatients.filter(
      ({ id }) =>
        !!id &&
        !deletedPatients.find((deletedPatient) => deletedPatient.id === id),
    );
    const newPatients: Prisma.PatientCreateInput[] = [];
    const updatedPatients: Prisma.PatientCreateInput[] = [];

    for (const stagingPatient of patientsToInsert) {
      const finalPatient = finalPatients.find(
        (finalPatient) => finalPatient.id === stagingPatient.id,
      );
      if (finalPatient) {
        updatedPatients.push(this.patientStagingToFinal(stagingPatient));
      } else {
        newPatients.push(this.patientStagingToFinal(stagingPatient));
      }
    }
    return {
      deleted: deletedPatients.map(({ id }) => id),
      updated: updatedPatients,
      created: newPatients,
    };
  }

  private static patientStagingToFinal(
    patient: PatientStaging,
  ): Prisma.PatientCreateInput {
    const {
      id,
      surname,
      name,
      street,
      zip,
      city,
      birthday,
      healthinsurance,
      healthinsuranceId,
      careDegree,
      disabilityMark1,
      disabilityMark2,
    } = patient;

    return {
      id,
      surname,
      name,
      street,
      zip,
      city,
      birthday,
      healthinsurance,
      healthinsuranceId,
      careDegree,
      disabilityMark1,
      disabilityMark2,
    };
  }
}
