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

import {
  listFilesQuerySchema,
  readFileContentQuerySchema,
  updateFileContentSchema,
} from '@hexahost/contracts';

import { CurrentUser } from '../../auth/decorators/current-user.decorator';
import { SessionGuard } from '../../auth/guards/session.guard';
import { ZodValidationPipe } from '../../common/pipes/zod-validation.pipe';

import { FilesService } from './files.service';

@ApiTags('servers')
@Controller('servers/:serverId/files')
@UseGuards(SessionGuard)
export class FilesController {
  constructor(private readonly filesService: FilesService) {}

  @Get()
  @ApiOperation({ summary: 'List files in the server data directory' })
  @ApiResponse({ status: 200, description: 'Directory listing' })
  list(
    @CurrentUser() user: { id: string },
    @Param('serverId', ParseUUIDPipe) serverId: string,
    @Query(new ZodValidationPipe(listFilesQuerySchema)) query: { path: string },
  ) {
    return this.filesService.listFiles(user.id, serverId, query.path);
  }

  @Get('content')
  @ApiOperation({ summary: 'Read a text file from the server' })
  @ApiResponse({ status: 200, description: 'File content' })
  read(
    @CurrentUser() user: { id: string },
    @Param('serverId', ParseUUIDPipe) serverId: string,
    @Query(new ZodValidationPipe(readFileContentQuerySchema))
    query: { path: string },
  ) {
    return this.filesService.readFile(user.id, serverId, query.path);
  }

  @Put('content')
  @ApiOperation({ summary: 'Write a text file on the server' })
  @ApiResponse({ status: 200, description: 'Updated file content' })
  write(
    @CurrentUser() user: { id: string },
    @Param('serverId', ParseUUIDPipe) serverId: string,
    @Body(new ZodValidationPipe(updateFileContentSchema)) body: unknown,
  ) {
    return this.filesService.writeFile(
      user.id,
      serverId,
      body as Parameters<FilesService['writeFile']>[2],
    );
  }
}
