import {
  Body,
  Controller,
  Delete,
  Get,
  Param,
  ParseUUIDPipe,
  Patch,
  Post,
  UseGuards,
} from '@nestjs/common';
import { ApiOperation, ApiResponse, ApiTags } from '@nestjs/swagger';

import {
  createBackupRequestSchema,
  restoreBackupRequestSchema,
  updateBackupScheduleSchema,
} from '@hexahost/contracts';

import { CurrentUser } from '../../auth/decorators/current-user.decorator';
import { SessionGuard } from '../../auth/guards/session.guard';

import { BackupsService } from './backups.service';

@ApiTags('servers')
@Controller('servers/:serverId/backups')
@UseGuards(SessionGuard)
export class BackupsController {
  constructor(private readonly backupsService: BackupsService) {}

  @Get()
  @ApiOperation({ summary: 'List server backups' })
  list(
    @CurrentUser() user: { id: string },
    @Param('serverId', ParseUUIDPipe) serverId: string,
  ) {
    return this.backupsService.listBackups(user.id, serverId);
  }

  @Post()
  @ApiOperation({ summary: 'Create a manual backup' })
  create(
    @CurrentUser() user: { id: string },
    @Param('serverId', ParseUUIDPipe) serverId: string,
    @Body() body: unknown,
  ) {
    const input = createBackupRequestSchema.parse(body ?? {});
    return this.backupsService.createBackup(user.id, serverId, input);
  }

  @Get('schedule')
  @ApiOperation({ summary: 'Get backup schedule' })
  getSchedule(
    @CurrentUser() user: { id: string },
    @Param('serverId', ParseUUIDPipe) serverId: string,
  ) {
    return this.backupsService.getSchedule(user.id, serverId);
  }

  @Patch('schedule')
  @ApiOperation({ summary: 'Update backup schedule' })
  updateSchedule(
    @CurrentUser() user: { id: string },
    @Param('serverId', ParseUUIDPipe) serverId: string,
    @Body() body: unknown,
  ) {
    const input = updateBackupScheduleSchema.parse(body);
    return this.backupsService.updateSchedule(user.id, serverId, input);
  }

  @Get(':backupId/download-url')
  @ApiOperation({ summary: 'Get a presigned download URL for a backup' })
  downloadUrl(
    @CurrentUser() user: { id: string },
    @Param('serverId', ParseUUIDPipe) serverId: string,
    @Param('backupId', ParseUUIDPipe) backupId: string,
  ) {
    return this.backupsService.getDownloadUrl(user.id, serverId, backupId);
  }

  @Post(':backupId/restore')
  @ApiOperation({ summary: 'Restore a backup' })
  restore(
    @CurrentUser() user: { id: string },
    @Param('serverId', ParseUUIDPipe) serverId: string,
    @Param('backupId', ParseUUIDPipe) backupId: string,
    @Body() body: unknown,
  ) {
    restoreBackupRequestSchema.parse(body);
    return this.backupsService.restoreBackup(user.id, serverId, backupId);
  }

  @Delete(':backupId')
  @ApiOperation({ summary: 'Delete a backup' })
  deleteBackup(
    @CurrentUser() user: { id: string },
    @Param('serverId', ParseUUIDPipe) serverId: string,
    @Param('backupId', ParseUUIDPipe) backupId: string,
  ) {
    return this.backupsService.deleteBackup(user.id, serverId, backupId);
  }
}
