import { Body, Controller, Delete, Get, Param, Patch, Post, Query, UseGuards } from '@nestjs/common';
import { ApiBearerAuth, ApiTags } from '@nestjs/swagger';
import { CurrentUser, CurrentUserPayload } from '../common/decorators/current-user.decorator';
import { JwtAuthGuard } from '../common/guards/jwt-auth.guard';
import {
  AbortUploadDto,
  CompleteUploadDto,
  InitiateUploadDto,
  ListOfflineMapsDto,
  PresignedPartDto,
  SyncS3MapsDto,
  UpdateOfflineMapDto,
  UpdateStatusDto,
} from './dto';
import { OfflineMapsService } from './offline-maps.service';

@ApiBearerAuth()
@ApiTags('Offline Maps')
@UseGuards(JwtAuthGuard)
@Controller('offline-maps')
export class OfflineMapsController {
  constructor(private readonly maps: OfflineMapsService) {}

  @Post('initiate-upload')
  initiate(@CurrentUser() user: CurrentUserPayload, @Body() dto: InitiateUploadDto) {
    return this.maps.initiateUpload(dto, user.sub);
  }

  @Post('presigned-part')
  presignedPart(@Body() dto: PresignedPartDto) {
    return this.maps.presignedPart(dto);
  }

  @Post('complete-upload')
  complete(@Body() dto: CompleteUploadDto) {
    return this.maps.completeUpload(dto);
  }

  @Post('abort-upload')
  abort(@Body() dto: AbortUploadDto) {
    return this.maps.abortUpload(dto);
  }

  @Post('sync-s3')
  syncS3(@CurrentUser() user: CurrentUserPayload, @Body() dto: SyncS3MapsDto) {
    return this.maps.syncFromS3(user.sub, dto);
  }

  @Get()
  list(@Query() query: ListOfflineMapsDto) {
    return this.maps.list(query);
  }

  @Get(':id')
  detail(@Param('id') id: string) {
    return this.maps.detail(id);
  }

  @Patch(':id')
  update(@Param('id') id: string, @Body() dto: UpdateOfflineMapDto) {
    return this.maps.update(id, dto);
  }

  @Patch(':id/file')
  initiateReplacement(@CurrentUser() user: CurrentUserPayload, @Param('id') id: string, @Body() dto: InitiateUploadDto) {
    return this.maps.initiateUpload(dto, user.sub, id);
  }

  @Post(':id/file/complete-upload')
  completeReplacement(@Body() dto: CompleteUploadDto) {
    return this.maps.completeUpload(dto, true);
  }

  @Patch(':id/status')
  status(@Param('id') id: string, @Body() dto: UpdateStatusDto) {
    return this.maps.updateStatus(id, dto.status);
  }

  @Delete(':id')
  softDelete(@Param('id') id: string) {
    return this.maps.softDelete(id);
  }

  @Delete(':id/hard')
  hardDelete(@Param('id') id: string) {
    return this.maps.hardDelete(id);
  }
}
