import {
  Controller,
  Post,
  Get,
  Put,
  Body,
  Param,
  UseGuards,
  Req,
} from '@nestjs/common';
import { LeaveService } from './leave.service';
import { Roles } from 'common/guards/decorators/roles.decorator';
import { RolesGuard } from 'common/guards/roles.guard';
import { JwtAuthGuard } from 'src/auth/jwt-auth.guard';
import { CreateLeaveRequestDto } from './dto/create-leave-request.dto';
import { UpdateLeaveBalanceDto } from './dto/leave-balance.dto';
import { UserRole } from 'common/enums/user.enum';
import { ApiBearerAuth, ApiParam, ApiTags, ApiQuery } from '@nestjs/swagger';
import { Query } from '@nestjs/common';
import { PaginationQueryDto } from 'common/dto/pagination-query.dto';

@ApiTags('Leave')
@ApiBearerAuth('access-token')
@Controller('leave')
@UseGuards(JwtAuthGuard)
export class LeaveController {
  constructor(private readonly leaveService: LeaveService) {}

  @Post('request')
  @Roles(UserRole.EMPLOYEE)
  createRequest(@Req() req, @Body() dto: CreateLeaveRequestDto) {
    const userId = req.user['userId'];
    return this.leaveService.createRequest(userId, dto);
  }

  @Get('requests')
  getUserRequests(@Req() req, @Query() query: PaginationQueryDto) {
    const userId = req.user['userId'];
    return this.leaveService.getUserRequests(userId, query);
  }

  @Get('balances')
  getUserBalances(@Req() req) {
    const userId = req.user['userId'];
    return this.leaveService.getUserBalances(userId);
  }

  @Get('all-requests')
  @Roles(UserRole.HR_ADMIN)
  @UseGuards(RolesGuard)
  @ApiQuery({ name: 'search', required: false })
  getAllRequests(@Query() query: PaginationQueryDto) {
    return this.leaveService.getAllRequests(query);
  }

  @Put('approve/:id')
  @Roles(UserRole.HR_ADMIN)
  @UseGuards(RolesGuard)
  @ApiParam({ name: 'id', description: 'The ID of the leave request to approve' })
  approve(@Param('id') id: number, @Req() req) {
    const hrId = req.user['userId'];
    return this.leaveService.approveRequest(id, hrId);
  }

  @Put('reject/:id')
  @Roles(UserRole.HR_ADMIN)
  @UseGuards(RolesGuard)
  @ApiParam({ name: 'id', description: 'The ID of the leave request to reject' })
  reject(@Param('id') id: number, @Req() req, @Body('reason') reason?: string) {
    const hrId = req.user['userId'];
    return this.leaveService.rejectRequest(id, hrId, reason);
  }

  @Post('assign-initial/:userId')
  @Roles(UserRole.HR_ADMIN)
  @UseGuards(RolesGuard)
  @ApiParam({ name: 'userId', description: 'The ID of the user to assign initial balance' })
  assignInitial(@Param('userId') userId: number) {
    return this.leaveService.assignInitialLeaveToUser(userId);
  }

  @Put('cancel/:id')
  @ApiParam({ name: 'id', description: 'The ID of the leave request to cancel' })
  cancel(@Param('id') id: number, @Req() req) {
    return this.leaveService.cancelRequest(id, req.user.userId);
  }

  @Get('user/:userId')
  @Roles(UserRole.HR_ADMIN)
  @UseGuards(RolesGuard)
  @ApiParam({ name: 'userId', description: 'The ID of the user to fetch requests for' })
  getUserRequestsByHR(@Param('userId') userId: number, @Query() query: PaginationQueryDto) {
    return this.leaveService.getUserRequests(userId, query);
  }

  @Put('balance/:userId/:leaveType')
  @Roles(UserRole.HR_ADMIN)
  @UseGuards(RolesGuard)
  @ApiParam({ name: 'userId', description: 'The ID of the user' })
  @ApiParam({ name: 'leaveType', description: 'The type of leave (ANNUAL, SICK, etc.)' })
  updateBalance(
    @Param('userId') userId: number,
    @Param('leaveType') leaveType: string,
    @Body() body: UpdateLeaveBalanceDto,
  ) {
    return this.leaveService.updateBalance(userId, leaveType as any, body.balance);
  }
}
