import { Prisma, Tour, TourStaging } from '@prisma/client';

export class TourLoader {
  public static determineLoadOperations(
    stagingTours: TourStaging[],
    finalTours: Tour[],
  ): {
    deleted: string[];
    updated: Prisma.TourCreateInput[];
    created: Prisma.TourCreateInput[];
  } {
    const deletedTours = finalTours.filter(
      (finalTour) =>
        !stagingTours.find(
          (stagingTour) => stagingTour.operationId === finalTour.operationId,
        ),
    );
    const toursToInsert = stagingTours.filter(
      ({ id, operationId }) =>
        !!id &&
        !deletedTours.find(
          (deletedTour) => deletedTour.operationId === operationId,
        ),
    );
    const newTours: Prisma.TourCreateInput[] = [];
    const updatedTours: Prisma.TourCreateInput[] = [];
    for (const stagingTour of toursToInsert) {
      const finalTour = finalTours.find(
        (finalTour) => finalTour.operationId === stagingTour.operationId,
      );
      if (finalTour) {
        updatedTours.push(
          this.tourStagingToFinal(stagingTour, finalTour.ticketId),
        );
      } else {
        newTours.push(this.tourStagingToFinal(stagingTour));
      }
    }

    return {
      deleted: deletedTours.map(({ operationId }) => operationId),
      updated: updatedTours,
      created: newTours,
    };
  }

  private static tourStagingToFinal(tour: TourStaging, ticketId?: string) {
    const {
      id,
      done,
      direction,
      carName,
      operationId,
      driverId,
      driverName,
      codriverId,
      codriverName,
      patientId,
      patientName,
      patientSurname,
      patientStreet,
      patientZip,
      patientCity,
      healthInsurance,
      healthInsuranceNumber,
      type,
      category,
      transportType,
      ordinanceType,
      rangeEndDate,
      startInstitution,
      startStreet,
      startZip,
      startCity,
      targetInstitution,
      targetStreet,
      targetZip,
      targetCity,
      startDate,
      check,
      occupiedKm,
      totalKm,
      startBegin,
      startEnd,
      target,
      targetBegin,
      empty,
      hasInfection,
      infectionName,
      revenueDispoLive,
      revenue,
      revenueDeviation,
      consumptionCosts,
      billDate,
      billNumber,
      createdAt,
      updatedAt
    } = tour;

    return {
      id,
      done,
      direction,
      carName,
      operationId,
      driverId,
      driverName,
      codriverId,
      codriverName,
      patientId,
      patientName,
      patientSurname,
      patientStreet,
      patientZip,
      patientCity,
      healthInsurance,
      healthInsuranceNumber,
      type,
      category,
      transportType,
      ordinanceType,
      rangeEndDate,
      startInstitution,
      startStreet,
      startZip,
      startCity,
      targetInstitution,
      targetStreet,
      targetZip,
      targetCity,
      startDate,
      check,
      occupiedKm,
      totalKm,
      startBegin,
      startEnd,
      target,
      targetBegin,
      empty,
      hasInfection,
      infectionName,
      revenueDispoLive,
      revenue,
      revenueDeviation,
      consumptionCosts,
      billDate,
      billNumber,
      createdAt,
      updatedAt,
      ...(ticketId ? { ticketId } : {}),
    };
  }
}
