import {
  Body,
  Controller,
  Delete,
  Get,
  HttpStatus,
  Param,
  Patch,
  Post,
  Query,
  Req,
  Res,
  UseGuards,
  UsePipes,
} from '@nestjs/common';
import { Request, Response } from 'express';
import { getPermissionContext } from '../../common/access-control/permission-request.util';
import { CurrentUser } from '../../common/decorators/current-user.decorator';
import { ZodValidationPipe } from '../../common/pipes/zod-validation.pipe';
import { JwtAuthGuard } from '../owner/guards/jwt.guard';
import { LoginThrottlerGuard } from '../owner/guards/login-throttle.guard';
import {
  createMemberDto,
  createMemberSchema,
  filterMembersDto,
  filterMembersSchema,
  signinMemberDto,
  signinMemberSchema,
  updateMemberSchema,
} from './members.dto';
import { MembersService } from './members.service';

@Controller('members')
export class MembersController {
  constructor(private readonly service: MembersService) {}

  @UseGuards(LoginThrottlerGuard)
  @UsePipes(new ZodValidationPipe(signinMemberSchema))
  @Post('signin')
  async login(
    @Body() data: signinMemberDto,
    @Req() req: Request,
    @Res() res: Response,
  ) {
    const clientIp =
      (req.headers['x-forwarded-for'] as string)?.split(',')[0]?.trim() ||
      req.ip ||
      req.socket.remoteAddress ||
      '127.0.0.1';
    const result = await this.service.signinMember(data, clientIp);
    return res.status(HttpStatus.OK).json(result);
  }

  @UseGuards(JwtAuthGuard)
  @UsePipes(new ZodValidationPipe(createMemberSchema))
  @Post('create')
  async create(
    @Body() data: createMemberDto,
    @CurrentUser() owner_id: string,
    @Req() req: Request,
    @Res() res: Response,
  ) {
    const result = await this.service.createMember(
      data,
      owner_id,
      getPermissionContext(req.user as any),
    );
    return res.status(HttpStatus.OK).json(result);
  }

  @UseGuards(JwtAuthGuard)
  @Get('all')
  async getAll(
    @CurrentUser() owner_id: string,
    @Query('data_scope') dataScope: 'own' | 'all' | undefined,
    @Req() req: Request,
    @Res() res: Response,
  ) {
    const result = await this.service.getMembers(
      owner_id,
      getPermissionContext(req.user as any),
      dataScope,
    );
    return res.status(HttpStatus.OK).json(result);
  }

  @UseGuards(JwtAuthGuard)
  @UsePipes(new ZodValidationPipe(filterMembersSchema))
  @Get('filter')
  async getByFilteres(
    @Query() query: filterMembersDto,
    @CurrentUser() owner_id: string,
    @Req() req: Request,
    @Res() res: Response,
  ) {
    const result = await this.service.getMembersByFilters(
      query,
      owner_id,
      getPermissionContext(req.user as any),
    );
    return res.status(HttpStatus.OK).json(result);
  }

  @UseGuards(JwtAuthGuard)
  @Get('find/:memberId')
  async findMember(
    @Param('memberId') memberId: string,
    @CurrentUser() owner_id: string,
    @Req() req: Request,
    @Res() res: Response,
  ) {
    const result = await this.service.getMemberById(
      memberId,
      owner_id,
      getPermissionContext(req.user as any),
    );
    return res.status(HttpStatus.OK).json(result);
  }

  @UseGuards(JwtAuthGuard)
  @UsePipes(new ZodValidationPipe(updateMemberSchema))
  @Patch('update/:memberId')
  async updateMember(
    @Body() data: createMemberDto,
    @Param('memberId') memberId: string,
    @CurrentUser() owner_id: string,
    @Req() req: Request,
    @Res() res: Response,
  ) {
    const result = await this.service.updateMember(
      memberId,
      data,
      owner_id,
      getPermissionContext(req.user as any),
    );
    return res.status(HttpStatus.OK).json(result);
  }

  @UseGuards(JwtAuthGuard)
  @Delete('delete/:memberId')
  async delete(
    @Param('memberId') memberId: string,
    @CurrentUser() owner_id: string,
    @Req() req: Request,
    @Res() res: Response,
  ) {
    const result = await this.service.deleteMember(
      memberId,
      owner_id,
      getPermissionContext(req.user as any),
    );
    return res.status(HttpStatus.OK).json(result);
  }
}
