import {
  Body,
  Controller,
  Delete,
  Get,
  Param,
  Patch,
  Post,
  Put,
  UseGuards,
} from '@nestjs/common';
import { OidcAuthGuard } from '../../../../libs/auth/src';
import type { AuthenticatedUser } from '../../../../libs/auth/src';
import {
  TripMembershipGuard,
  TripRoles,
  TripSettingsService,
  TripsService,
} from '../../../../libs/trips/src';
import type {
  CreateTripDto,
  Trip,
  TripSettings,
  UpdateTripDto,
  UpdateTripSettingsDto,
} from '../../../../libs/trips/src';
import { CurrentUser } from '../auth/current-user.decorator';

@Controller('trips')
@UseGuards(OidcAuthGuard)
export class TripsController {
  constructor(
    private readonly tripsService: TripsService,
    private readonly tripSettingsService: TripSettingsService,
  ) {}

  @Get()
  list(@CurrentUser() currentUser: AuthenticatedUser): Promise<Trip[]> {
    return this.tripsService.listTripsForUser(currentUser.id);
  }

  @Post()
  create(
    @CurrentUser() currentUser: AuthenticatedUser,
    @Body() dto: CreateTripDto,
  ): Promise<Trip> {
    return this.tripsService.createTrip(currentUser.id, dto);
  }

  @Get(':tripId')
  @UseGuards(TripMembershipGuard)
  getOne(@Param('tripId') tripId: string): Promise<Trip> {
    return this.tripsService.getTrip(tripId);
  }

  @Patch(':tripId')
  @UseGuards(TripMembershipGuard)
  @TripRoles('OWNER')
  update(
    @Param('tripId') tripId: string,
    @Body() dto: UpdateTripDto,
  ): Promise<Trip> {
    return this.tripsService.updateTrip(tripId, dto);
  }

  @Delete(':tripId')
  @UseGuards(TripMembershipGuard)
  @TripRoles('OWNER')
  remove(@Param('tripId') tripId: string): Promise<void> {
    return this.tripsService.deleteTrip(tripId);
  }

  @Get(':tripId/settings')
  @UseGuards(TripMembershipGuard)
  getSettings(@Param('tripId') tripId: string): Promise<TripSettings> {
    return this.tripSettingsService.getSettings(tripId);
  }

  @Put(':tripId/settings')
  @UseGuards(TripMembershipGuard)
  @TripRoles('OWNER')
  replaceSettings(
    @Param('tripId') tripId: string,
    @Body() dto: UpdateTripSettingsDto,
  ): Promise<TripSettings> {
    return this.tripSettingsService.replaceSettings(tripId, dto);
  }
}
