import {
  Controller,
  Get,
  Post,
  Put,
  Delete,
  Patch,
  Body,
  Param,
  Query,
  UseGuards,
  Request,
  HttpCode,
  HttpStatus,
} from '@nestjs/common';
import { CommentService } from './comment.service';
import {
  CreateCommentDto,
  UpdateCommentDto,
  CommentResponseDto,
  FindCommentsDto,
  CreateReactionDto,
} from './comment.dto';
import { JwtAuthGuard } from '../auth/jwt-auth.guard';
import { RolesGuard } from '../auth/roles.guard';
import { Roles } from '../auth/roles.decorator';
import { Public } from '../auth/public.decorator';
import { UserRole } from '../entities';
import type { RequestWithUser } from '../auth/types';

@Controller('comments')
export class CommentController {
  constructor(private readonly commentService: CommentService) {}

  @Post()
  @UseGuards(JwtAuthGuard)
  async create(
    @Body() createCommentDto: CreateCommentDto,
    @Request() req: RequestWithUser,
  ): Promise<CommentResponseDto> {
    return this.commentService.create(createCommentDto, req.user.id);
  }

  @Get()
  @Public()
  async findAll(
    @Query() findCommentsDto: FindCommentsDto,
  ): Promise<CommentResponseDto[]> {
    return this.commentService.findAll(findCommentsDto);
  }

  @Get(':id')
  @Public()
  async findOne(@Param('id') id: string): Promise<CommentResponseDto> {
    return this.commentService.findOne(id);
  }

  @Put(':id')
  @UseGuards(JwtAuthGuard)
  async update(
    @Param('id') id: string,
    @Body() updateCommentDto: UpdateCommentDto,
    @Request() req: RequestWithUser,
  ): Promise<CommentResponseDto> {
    return this.commentService.update(
      id,
      updateCommentDto,
      req.user.id,
      req.user.role,
    );
  }

  @Delete(':id')
  @UseGuards(JwtAuthGuard)
  @HttpCode(HttpStatus.NO_CONTENT)
  async remove(
    @Param('id') id: string,
    @Request() req: RequestWithUser,
  ): Promise<void> {
    return this.commentService.remove(id, req.user.id, req.user.role);
  }

  @Post('reactions')
  @UseGuards(JwtAuthGuard)
  @HttpCode(HttpStatus.NO_CONTENT)
  async addReaction(
    @Body() createReactionDto: CreateReactionDto,
    @Request() req: RequestWithUser,
  ): Promise<void> {
    return this.commentService.addReaction(createReactionDto, req.user.id);
  }

  @Get('reactions/user')
  @Public()
  async getUserReaction(
    @Request() req: RequestWithUser,
    @Query('articleId') articleId?: string,
    @Query('liveBlogId') liveBlogId?: string,
    @Query('commentId') commentId?: string,
  ): Promise<{ type: string | null }> {
    // If user is not authenticated, return null
    if (!req.user?.id) {
      return { type: null };
    }

    const reaction = await this.commentService.getUserReaction(
      req.user.id,
      articleId,
      liveBlogId,
      commentId,
    );
    return { type: reaction };
  }

  @Get('reactions/counts')
  @Public()
  async getReactionCounts(
    @Query('articleId') articleId?: string,
    @Query('liveBlogId') liveBlogId?: string,
    @Query('commentId') commentId?: string,
  ): Promise<{ likes: number; dislikes: number }> {
    return this.commentService.getReactionCounts(
      articleId,
      liveBlogId,
      commentId,
    );
  }

  // Admin endpoints
  @Patch(':id/hide')
  @UseGuards(JwtAuthGuard, RolesGuard)
  @Roles(UserRole.ADMIN)
  async hideComment(@Param('id') id: string): Promise<CommentResponseDto> {
    return this.commentService.update(
      id,
      { isVisible: false },
      'admin',
      'admin',
    );
  }

  @Patch(':id/show')
  @UseGuards(JwtAuthGuard, RolesGuard)
  @Roles(UserRole.ADMIN)
  async showComment(@Param('id') id: string): Promise<CommentResponseDto> {
    return this.commentService.update(
      id,
      { isVisible: true },
      'admin',
      'admin',
    );
  }
}
