import {
  Body,
  Controller,
  Delete,
  Get,
  Param,
  Patch,
  Post,
  UsePipes,
  ValidationPipe,
  Query,
  UseGuards,
  UseInterceptors,
} from '@nestjs/common';
import { WorkspaceService } from './workspace.service';
import { ApiBearerAuth, ApiOperation, ApiTags } from '@nestjs/swagger';
import {
  ChangeWorkspaceDTO,
  CreateWorkspaceDTO,
  WorkspaceDTO,
  WorkspaceQueryDTO,
} from './dto/workspace-dto';
import { WorkspaceEntity } from '../entities/workspace.entity';
import {
  ApiOkResponseListWithTotal,
  ApiResultListWithTotal,
} from 'src/common/types/api-result';
import {
  ProjectAccess,
  ProjectAccessInterceptor,
  RequestProjectAccess,
} from 'src/utils/project-access';
import { WorkspaceReorderDTO } from './dto/workspace-reorder-dto';
import { OptTokenOrJwtAuthGuard } from '../guards/opt-token-or-jwt.auth.guard';

@ApiTags('workspace')
@Controller('workspaces')
@UseGuards(OptTokenOrJwtAuthGuard)
@UseInterceptors(ProjectAccessInterceptor)
@ApiBearerAuth()
export class WorkspaceController {
  constructor(private readonly workspaceService: WorkspaceService) {}

  @Get()
  @ApiOperation({
    summary: 'Get workspace list',
  })
  @ApiOkResponseListWithTotal(WorkspaceDTO)
  @UsePipes(
    new ValidationPipe({
      transform: true,
      transformOptions: { enableImplicitConversion: true },
    }),
  )
  async getWorkspaces(
    @Query() filterData: WorkspaceQueryDTO,
    @RequestProjectAccess() projectAccess: ProjectAccess,
  ): Promise<ApiResultListWithTotal<WorkspaceDTO>> {
    return await this.workspaceService.getWorkspacesOfProject(
      filterData,
      projectAccess,
    );
  }

  @Post()
  @ApiOperation({
    summary: 'Create workspace',
  })
  async createWorkspace(
    @Body() params: CreateWorkspaceDTO,
    @RequestProjectAccess() projectAccess: ProjectAccess,
  ): Promise<WorkspaceEntity & { rights: number }> {
    return await this.workspaceService.checkAndCreateWorkspace(
      params,
      projectAccess,
    );
  }

  @Patch(':id')
  @ApiOperation({
    summary: 'Change workspace',
  })
  async changeWorkspace(
    @Param('id') id: string,
    @Body() params: ChangeWorkspaceDTO,
    @RequestProjectAccess() projectAccess: ProjectAccess,
  ): Promise<WorkspaceEntity> {
    return await this.workspaceService.changeWorkspace(
      id,
      params,
      projectAccess,
    );
  }

  @Delete(':id')
  @ApiOperation({
    summary: 'Delete workspace',
  })
  async deleteWorkspace(
    @Param('id') id: string,
    @RequestProjectAccess() projectAccess: ProjectAccess,
  ): Promise<void> {
    await this.workspaceService.deleteWorkspace(id, projectAccess);
  }

  @Post('reorder')
  @ApiOperation({
    summary: 'Reorder workspaces',
  })
  @UseInterceptors(ProjectAccessInterceptor)
  async reorderColumns(
    @Body() params: WorkspaceReorderDTO,
    @RequestProjectAccess() projectAccess: ProjectAccess,
  ): Promise<{ ids: string[] }> {
    return {
      ids: await this.workspaceService.reorder(params, projectAccess),
    };
  }
}
