import {
  ConflictException,
  Injectable,
  NotFoundException,
} from '@nestjs/common';
import { TripsRepository } from './trips.repository';
import type { TripUpdateFields } from './trips.repository';
import type { CreateTripDto, Trip, UpdateTripDto } from './trip.types';

@Injectable()
export class TripsService {
  constructor(private readonly tripsRepository: TripsRepository) {}

  createTrip(ownerId: string, dto: CreateTripDto): Promise<Trip> {
    return this.tripsRepository.createTrip(ownerId, dto);
  }

  listTripsForUser(userId: string): Promise<Trip[]> {
    return this.tripsRepository.listForUser(userId);
  }

  async getTrip(tripId: string): Promise<Trip> {
    const trip = await this.tripsRepository.findById(tripId);
    if (!trip) throw new NotFoundException('Trip not found');
    return trip;
  }

  async updateTrip(tripId: string, dto: UpdateTripDto): Promise<Trip> {
    const patch: Partial<TripUpdateFields> = {};
    if (dto.name !== undefined) patch.name = dto.name;
    if (dto.description !== undefined) patch.description = dto.description;
    if (dto.startDate !== undefined) patch.start_date = dto.startDate;
    if (dto.endDate !== undefined) patch.end_date = dto.endDate;
    if (dto.status !== undefined) patch.status = dto.status;
    if (dto.planningStage !== undefined)
      patch.planning_stage = dto.planningStage;
    if (dto.currency !== undefined) patch.currency = dto.currency;

    const updated = await this.tripsRepository.updateWithVersionCheck(
      tripId,
      dto.version,
      patch,
    );
    if (!updated) {
      throw new ConflictException(
        'Trip was modified by someone else. Reload and retry.',
      );
    }
    return updated;
  }

  async deleteTrip(tripId: string): Promise<void> {
    await this.tripsRepository.delete(tripId);
  }
}
