import {
  Body,
  Controller,
  DefaultValuePipe,
  Delete,
  Get,
  HttpCode,
  HttpStatus,
  Param,
  ParseIntPipe,
  ParseUUIDPipe,
  Patch,
  Post,
  Query,
  UseGuards,
} from '@nestjs/common';
import { ApiOperation, ApiResponse, ApiTags } from '@nestjs/swagger';
import { JwtAuthGuard } from '../auth/guards/jwt-auth.guard';
import { CurrentUser } from '../auth/decorators/current-user.decorator';
import type { PublicUser } from '../user/user.service';
import type { PaginatedResult } from '../../common/pagination/pagination';
import { ProjectService, type ProjectResponse } from './project.service';
import { CreateProjectDto } from './dto/create-project.dto';
import { UpdateProjectDto } from './dto/update-project.dto';

// 프로젝트 컨트롤러 — 모든 엔드포인트 인증 필요
@ApiTags('Project')
@Controller('projects')
@UseGuards(JwtAuthGuard)
export class ProjectController {
  constructor(private readonly projectService: ProjectService) {}

  @Get()
  @ApiOperation({ summary: '프로젝트 전체 목록 (페이지네이션)' })
  @ApiResponse({ status: 200, description: '목록 조회 성공' })
  findAll(
    @Query('page', new DefaultValuePipe(1), ParseIntPipe) page: number,
    @Query('size', new DefaultValuePipe(20), ParseIntPipe) size: number,
    @Query('sort') sort?: string,
    @Query('q') q?: string,
  ): Promise<PaginatedResult<ProjectResponse>> {
    return this.projectService.findAll(page, size, { sort, q });
  }

  @Post()
  @HttpCode(HttpStatus.CREATED)
  @ApiOperation({ summary: '프로젝트 생성' })
  @ApiResponse({ status: 201, description: '생성 성공' })
  create(
    @Body() dto: CreateProjectDto,
    @CurrentUser() user: PublicUser,
  ): Promise<ProjectResponse> {
    return this.projectService.create(dto, user.id);
  }

  @Get(':projectId')
  @ApiOperation({ summary: '프로젝트 단건 조회' })
  @ApiResponse({ status: 200, description: '조회 성공' })
  @ApiResponse({
    status: 404,
    description: '프로젝트를 찾을 수 없음 (RES_001)',
  })
  findOne(
    @Param('projectId', ParseUUIDPipe) projectId: string,
    @CurrentUser() user: PublicUser,
  ): Promise<ProjectResponse> {
    return this.projectService.findOne(projectId, user.id);
  }

  @Patch(':projectId')
  @ApiOperation({ summary: '프로젝트 수정 (admin)' })
  @ApiResponse({ status: 200, description: '수정 성공' })
  @ApiResponse({ status: 403, description: '권한 없음 (AUTH_003)' })
  update(
    @Param('projectId', ParseUUIDPipe) projectId: string,
    @Body() dto: UpdateProjectDto,
    @CurrentUser() user: PublicUser,
  ): Promise<ProjectResponse> {
    return this.projectService.update(projectId, user.id, dto);
  }

  @Delete(':projectId')
  @HttpCode(HttpStatus.OK)
  @ApiOperation({ summary: '프로젝트 삭제 (소유자, 시스템 프로젝트 제외)' })
  @ApiResponse({ status: 200, description: '삭제 성공' })
  @ApiResponse({ status: 403, description: '권한 없음 (AUTH_003)' })
  async remove(
    @Param('projectId', ParseUUIDPipe) projectId: string,
    @CurrentUser() user: PublicUser,
  ): Promise<null> {
    await this.projectService.remove(projectId, user.id);
    return null;
  }
}
