import {
  Controller,
  Get,
  Post,
  Body,
  Patch,
  Param,
  Delete,
  Query,
  UseGuards,
  HttpStatus,
  Req,
  Logger,
  UseInterceptors,
  UploadedFile,
} from '@nestjs/common';
import { ApiTags, ApiOperation, ApiResponse, ApiBearerAuth, ApiParam, ApiQuery, ApiBody, ApiConsumes } from '@nestjs/swagger';
import { BlogService } from './blog.service';
import { CreateBlogDto } from './dto/create-blog.dto';
import { IBlogResponseDto, IBlogResponsePaginationDto } from './dto/blog-response';
import { JwtAuthGuard } from 'common/guards/jwt-auth.guard';
import { UpdateBlogDto } from './dto/update-blog.dto';
import { QueryBlogDto } from './dto/query-blog.dto';
import { Role } from 'discord.js';
import { UserRole } from 'common/enum/UserRole.enum';
import { Roles } from 'common/decorators/role.decorator';
import { FileInterceptor } from '@nestjs/platform-express';

@ApiTags('blogs')
@Controller({ path: 'blogs', version: '1' })
export class BlogController {
  private readonly logger = new Logger(BlogController.name);
  constructor(private readonly blogService: BlogService) {}

  @Post()
  @UseGuards(JwtAuthGuard)
  @ApiBearerAuth()
  @ApiOperation({ summary: 'Create a new blog post' })
  @ApiBody({ type: CreateBlogDto })
  @ApiResponse({
    status: HttpStatus.CREATED,
    description: 'The blog has been successfully created',
    type: IBlogResponseDto,
  })
  async create(@Req() req: any, @Body() createBlogDto: CreateBlogDto) {
    return this.blogService.create(req.user.id, createBlogDto);
  }

  @Get()
  @ApiOperation({ summary: 'Get all blog posts' })
  @ApiQuery({ name: 'page', required: false, type: Number })
  @ApiQuery({ name: 'limit', required: false, type: Number })
  @ApiQuery({ name: 'sortBy', required: false, type: String })
  @ApiQuery({ name: 'sortDirection', required: false, type: String })
  @ApiQuery({ name: 'isPublished', required: false, type: Boolean })
  @ApiQuery({ name: 'language', required: false, type: String })
  @ApiQuery({ name: 'search', required: false, type: String })
  @ApiQuery({ name: 'tags', required: false, type: String })
  @ApiResponse({
    status: HttpStatus.OK,
    description: 'List of blog posts',
    type: IBlogResponsePaginationDto,
  })
  async findAll(@Query() queryParams: QueryBlogDto): Promise<IBlogResponsePaginationDto> {
    return this.blogService.findAll(queryParams);
  }

  @Get(':id')
  @ApiOperation({ summary: 'Get a blog post by ID' })
  @ApiParam({ name: 'id', type: Number })
  @ApiResponse({
    status: HttpStatus.OK,
    description: 'The blog post has been successfully retrieved',
    type: IBlogResponseDto,
  })
  async findOne(@Param('id') id: string): Promise<IBlogResponseDto> {
    return this.blogService.findOne(+id);
  }

  //  find byslug
  @Get('slug/:slug')
  @ApiOperation({ summary: 'Get a blog post by slug' })
  @ApiParam({ name: 'slug', type: String })
  @ApiResponse({
    status: HttpStatus.OK,
    description: 'The blog post has been successfully retrieved',
    type: IBlogResponseDto,
  })
  async findBySlug(@Param('slug') slug: string): Promise<IBlogResponseDto> {
    await this.blogService.incrementViewCount(slug);
    return this.blogService.findBySlug(slug);
  }

  @Patch(':id')
  @UseGuards(JwtAuthGuard)
  @Roles(UserRole.SUPER_ADMIN, UserRole.ADMIN)
  @ApiBearerAuth()
  @ApiOperation({ summary: 'Update a blog post by ID' })
  @ApiParam({ name: 'id', type: Number })
  @ApiBody({ type: UpdateBlogDto })
  @ApiResponse({
    status: HttpStatus.OK,
    description: 'The blog post has been successfully updated',
    type: IBlogResponseDto,
  })
  async update(@Req() req: any, @Param('id') id: string, @Body() updateBlogDto: UpdateBlogDto): Promise<IBlogResponseDto> {
    const { user } = req;

    return this.blogService.update(+id, user.id, updateBlogDto);
  }

  @Delete(':id')
  @UseGuards(JwtAuthGuard)
  @Roles(UserRole.SUPER_ADMIN, UserRole.ADMIN)
  @ApiBearerAuth()
  @ApiOperation({ summary: 'Delete a blog post by ID' })
  @ApiParam({ name: 'id', type: Number })
  @ApiResponse({
    status: HttpStatus.OK,
    description: 'The blog post has been successfully deleted',
  })
  async remove(@Param('id') id: string): Promise<void> {
    return this.blogService.remove(+id);
  }

  @Post('upload-blog-image')
  @UseGuards(JwtAuthGuard)
  @Roles(UserRole.SUPER_ADMIN, UserRole.ADMIN)
  @ApiBearerAuth()
  @UseInterceptors(FileInterceptor('image'))
  @ApiConsumes('multipart/form-data')
  @ApiBody({
    type: 'object',
    schema: {
      type: 'object',
      properties: {
        image: {
          type: 'string',
          format: 'binary',
        },
      },
    },
  })
  @ApiOperation({ summary: 'Upload a blog image' })
  @ApiResponse({
    status: HttpStatus.OK,
    description: 'The blog image has been successfully uploaded',
  })
  async uploadBlogImage(@Req() req: any, @UploadedFile() image: Express.Multer.File): Promise<{ imageUrl: string }> {
    const { user } = req;
    if (!user) {
      throw new Error('User not found');
    }
    const imageUrl = await this.blogService.uploadBlogCoverImage(image);
    return { imageUrl };
  }
}
