import { Injectable } from "@nestjs/common"
import { UpdateTripIntermediateStopDto } from "../dto/update-trip-intermediate-stop.dto"
import { TripIntermediateStopRepository } from "../repositories/trip-intermediate-stop.repository"
import { TripRepository } from "../../trips/repositories/trip.repository"
import { errorMessage, isEmpty, successMessage } from "src/utils/helpers"
import { failureResponse, successResponse } from "src/common/response/response"
import { code } from "src/common/response/response.code"
import { messageKey } from "src/constants/message-keys"
import { TripIntermediateStop } from "../entities/trip-intermediate-stop.entity"

@Injectable()
export class TripIntermediateStopsService {
  constructor(
    private readonly tripIntermediateStopRepository: TripIntermediateStopRepository,
    private readonly tripRepository: TripRepository,
  ) {}

  async findOne(trip_id: number) {
    const trip = await this.tripRepository.getByParams({
      where: {
        id: trip_id,
      },
      findOne: true,
    })

    if (isEmpty(trip)) {
      return failureResponse(
        code.BAD_REQUEST,
        errorMessage(messageKey.data_not_found, {
          ":data": "Trip",
        }),
      )
    }

    const tripStops = await this.tripIntermediateStopRepository.getByParams({
      where: {
        trip_id: trip_id,
      },
      select: [
        "id",
        "duration",
        "notes",
        "stop_address",
        "trip_id",
        "latitude",
        "longitude",
      ],
    })

    return successResponse(
      code.SUCCESS,
      successMessage(messageKey.data_retrieve, { ":data": "Trip" }),
      tripStops,
    )
  }

  async update(updateTripIntermediateStopDto: UpdateTripIntermediateStopDto) {
    const isTripExist: any = await this.tripRepository.getByParams({
      where: {
        id: updateTripIntermediateStopDto?.trip_id,
      },
      relations: ["intermediate_stop:id"],
      findOne: true,
    })

    if (isEmpty(isTripExist)) {
      return failureResponse(
        code.BAD_REQUEST,
        errorMessage(messageKey.data_not_found, {
          ":data": "Trip",
        }),
      )
    }

    for (const tripStop of updateTripIntermediateStopDto?.stops) {
      if (tripStop?.intermediate_stop_id && tripStop?.should_remove) {
        await this.tripIntermediateStopRepository.remove(
          { id: tripStop?.intermediate_stop_id },
          null,
          false,
        )
      } else if (tripStop?.intermediate_stop_id) {
        // eslint-disable-next-line @typescript-eslint/no-unused-vars
        const { should_remove, intermediate_stop_id, ...tripPayload } = tripStop

        const condition: any = { id: intermediate_stop_id }
        const tripIntermediateStop = new TripIntermediateStop()

        Object.assign(tripIntermediateStop, tripPayload)

        await this.tripIntermediateStopRepository.save(
          tripIntermediateStop,
          condition,
        )
      } else {
        const tripIntermediateStop = new TripIntermediateStop()

        Object.assign(tripIntermediateStop, tripStop)

        await this.tripIntermediateStopRepository.save(tripIntermediateStop)
      }
    }

    return successResponse(
      code.SUCCESS,
      successMessage(messageKey.data_update, {
        ":data": "Trip ",
      }),
    )
  }

  async remove(id: number) {
    const isTripStopExist =
      await this.tripIntermediateStopRepository.getByParams({
        where: {
          id: id,
        },
        findOne: true,
      })

    if (isEmpty(isTripStopExist)) {
      return failureResponse(
        code.BAD_REQUEST,
        errorMessage(messageKey.data_not_found, {
          ":data": "Trip",
        }),
      )
    }

    await this.tripIntermediateStopRepository.remove({ id }, null, false)

    return successResponse(
      code.SUCCESS,
      successMessage(messageKey.data_removed, { ":data": "Trip stop" }),
    )
  }
}
