import { Body, Controller, Get, Param, Patch, Post, Query, Req, Res, UseGuards } from '@nestjs/common';
import type { Request, Response } from 'express';
import { AuthenticatedUser } from '../auth/auth.types';
import { AuthGuard } from '../common/auth.guard';
import { RequirePermission } from '../common/permission.decorator';
import { PermissionGuard } from '../common/permission.guard';
import { CreateUserDto } from './dto/create-user.dto';
import { UpdateUserDto } from './dto/update-user.dto';
import { UsersService } from './users.service';
import { CompleteInvitationDto } from './dto/complete-invitation.dto';

@Controller('users')
export class UsersController {
  constructor(private readonly usersService: UsersService) {}

  @UseGuards(AuthGuard, PermissionGuard)
  @Get()
  @RequirePermission('users', 'view')
  findAll(
    @Query('page') page?: string,
    @Query('limit') limit?: string,
    @Query('search') search?: string,
    @Query('roleId') roleId?: string,
    @Query('status') status?: string,
  ) {
    return this.usersService.findAll({
      page: page ? Number(page) : 1,
      limit: limit ? Number(limit) : 10,
      search,
      roleId,
      status,
    });
  }

  @UseGuards(AuthGuard, PermissionGuard)
  @Get('export')
  @RequirePermission('users', 'view')
  async exportCsv(
    @Res() response: Response,
    @Query('search') search?: string,
    @Query('roleId') roleId?: string,
    @Query('status') status?: string,
  ) {
    const csv = await this.usersService.exportCsv({ search, roleId, status });
    response.setHeader('Content-Type', 'text/csv; charset=utf-8');
    response.setHeader('Content-Disposition', 'attachment; filename="users-export.csv"');
    response.send(csv);
  }

  @UseGuards(AuthGuard, PermissionGuard)
  @Post('invite')
  @RequirePermission('users', 'manage')
  invite(
    @Req() request: Request & { user: AuthenticatedUser },
    @Body() dto: CreateUserDto,
  ) {
    return this.usersService.invite(dto, request.user, request.ip);
  }

  @UseGuards(AuthGuard, PermissionGuard)
  @Patch(':id')
  @RequirePermission('users', 'manage')
  update(
    @Req() request: Request & { user: AuthenticatedUser },
    @Param('id') id: string,
    @Body() dto: UpdateUserDto,
  ) {
    return this.usersService.update(id, dto, request.user, request.ip);
  }

  @Get('invitations/:token')
  getInvitation(@Param('token') token: string) {
    return this.usersService.getInvitation(token);
  }

  @Post('invitations/:token/complete')
  completeInvitation(
    @Req() request: Request,
    @Param('token') token: string,
    @Body() dto: CompleteInvitationDto,
  ) {
    return this.usersService.completeInvitation(token, dto, request.ip);
  }
}
