import {
  Controller,
  Get,
  Post,
  Body,
  Patch,
  Param,
  Delete,
  Req,
  Query,
  Res,
  UseGuards,
  UseInterceptors,
} from "@nestjs/common";
import { BuddiesService } from "./buddies.service";
import { CreateBuddyDto } from "./dto/create-buddy.dto";
import { UpdateBuddyDto } from "./dto/update-buddy.dto";
import { Request, Response } from "express";
import { UserDecorator } from "src/common/decorator/user.decorator";
import { UserAuthGuard } from "src/common/guards/jwt-auth.guard";
import { RolesGuard } from "src/common/guards/roles.guard";
import { RoleEnum } from "src/common/enums/constant.enum";
import { Roles } from "src/common/decorator/roles.decorator";
import { SearchBuddiesDto } from "./dto/search-buddies.dto";
import { LanguageInterceptor } from "src/common/interceptor/language.interceptor";

@Controller("buddies")
export class BuddiesController {
  constructor(private readonly buddiesService: BuddiesService) {}

  @Post()
  @UseGuards(UserAuthGuard, RolesGuard)
  @Roles(RoleEnum.ADMIN, RoleEnum.USER)
  @Get("finder")
  async getNearbyBuddies(
    @Req() req: Request,
    @Res() res: Response,
    @UserDecorator() user: any,
    @Query("radius") radius: number,
  ) {
    return this.buddiesService.findNearbyBuddies(
      user._id,
      Number(radius || 1),
      req,
      res,
    );
  }

  @UseGuards(UserAuthGuard, RolesGuard)
  @Roles(RoleEnum.ADMIN, RoleEnum.USER)
  @Post("search")
  @UseInterceptors(LanguageInterceptor)
  async searchBuddies(
    @Req() req: Request,
    @Res() res: Response,
    @UserDecorator() user: any,
    @Body() body: SearchBuddiesDto,
  ) {
    let lang = (req as any)?.lang;
    return this.buddiesService.searchBuddies(user._id, body, req, res, lang);
  }

  @UseGuards(UserAuthGuard, RolesGuard)
  @Roles(RoleEnum.ADMIN, RoleEnum.USER)
  @Get("global-search")
  @UseInterceptors(LanguageInterceptor)
  async globalSearch(
    @Query("query") query: string,
    @Req() req: Request,
    @UserDecorator() user: any,
    @Res() res: Response,
    @Query("page") page = 1,
    @Query("limit") limit = 20,
  ) {
    let lang = (req as any)?.lang;
    return this.buddiesService.globalSearch(
      user._id,
      query,
      Number(page),
      Number(limit),
      req,
      res,
      lang,
    );
  }

  @UseGuards(UserAuthGuard, RolesGuard)
  @Roles(RoleEnum.ADMIN, RoleEnum.USER)
  @Get("profile/:buddyId")
  @UseInterceptors(LanguageInterceptor)
  async getBuddyProfile(
    @Param("buddyId") buddyId: string,
    @UserDecorator() user: any,
    @Req() req: Request,
    @Res() res: Response,
  ) {
    let lang = (req as any)?.lang;
    return this.buddiesService.getBuddyProfile(
      user._id,
      buddyId,
      req,
      res,
      lang,
    );
  }

  @UseGuards(UserAuthGuard, RolesGuard)
  @Roles(RoleEnum.ADMIN, RoleEnum.USER)
  @Post("request")
  async sendBuddyRequest(
    @UserDecorator() user: any,
    @Body("receiverId") receiverId: string,
    @Req() req: Request,
    @Res() res: Response,
  ) {
    return this.buddiesService.sendBuddyRequest(user._id, receiverId, req, res);
  }

  @UseGuards(UserAuthGuard, RolesGuard)
  @Roles(RoleEnum.ADMIN, RoleEnum.USER)
  @Get("requests/recent")
  @UseInterceptors(LanguageInterceptor)
  async getBuddyRequests(
    @UserDecorator() user: any,
    @Req() req: Request,
    @Res() res: Response,
  ) {
    let lang = (req as any)?.lang;
    return this.buddiesService.getBuddyRecentRequests(user._id, req, res, lang);
  }

  @UseGuards(UserAuthGuard, RolesGuard)
  @Roles(RoleEnum.ADMIN, RoleEnum.USER)
  @Get("requests/pending")
  @UseInterceptors(LanguageInterceptor)
  async getBuddyPendingRequests(
    @UserDecorator() user: any,
    @Req() req: Request,
    @Res() res: Response,
    @Query("page") page = 1,
    @Query("limit") limit = 20,
  ) {
    let lang = (req as any)?.lang;
    return this.buddiesService.getBuddyPendingRequests(
      user._id,
      req,
      res,
      lang,
      Number(page),
      Number(limit),
    );
  }

  @UseGuards(UserAuthGuard)
  @Delete("unsend-request/:receiverId")
  unsendBuddyRequest(
    @UserDecorator() user: any,
    @Param("receiverId") receiverId: string,
    @Req() req: Request,
    @Res() res: Response,
  ) {
    return this.buddiesService.unsendBuddyRequest(
      user._id,
      receiverId,
      req,
      res,
    );
  }

  @UseGuards(UserAuthGuard, RolesGuard)
  @Roles(RoleEnum.ADMIN, RoleEnum.USER)
  @Patch("request/:id")
  async updateRequest(
    @Param("id") requestId: string,
    @Body("status") status: string,
    @UserDecorator() user: any,
    @Req() req: Request,
    @Res() res: Response,
  ) {
    return this.buddiesService.updateBuddyRequest(
      user._id,
      requestId,
      status,
      req,
      res,
    );
  }
}
