import {
  BadRequestException,
  Body,
  Controller,
  Get,
  Param,
  ParseUUIDPipe,
  Post,
  Query,
  Req,
  UseGuards,
} from '@nestjs/common';
import { BlogService } from './blog.service';
import { UserService } from 'src/user/user.service';
import { createBlogCommentDto } from './dto/create.blogcomment.dto';
import { Throttle, ThrottlerGuard } from '@nestjs/throttler';
import { BlogPermission } from './blog.permission.enum';
import { OptionalAuthGuard } from 'src/auth/guards/optional-auth.guard';

@Controller('blog')
export class BlogController {
  constructor(
    private readonly blogService: BlogService,
    private readonly userService: UserService,
  ) { }

  @Get()
  getBlogs() {
    return this.blogService.list();
  }

  @Get(':id')
  async getBlog(
    @Param('id', new ParseUUIDPipe({ version: '4' })) id: string,
    @Query('p') password?: string,
  ) {
    const blog = await this.blogService.findById(id);
    if (!blog) throw new BadRequestException('文章不存在或无权限访问');

    if (!blog.permissions.includes(BlogPermission.Public)) {
      // 无公开权限，则进一步检查是否有密码保护
      if (!blog.permissions.includes(BlogPermission.ByPassword)) {
        throw new BadRequestException('文章不存在或无权限访问');
      } else {
        // 判断密码是否正确
        if (
          !password ||
          this.blogService.hashPassword(password) !== blog.password_hash
        ) {
          throw new BadRequestException('文章不存在或无权限访问');
        }
      }
    }

    const blogDataRes = await fetch(`${blog.contentUrl}`);
    const blogContent = await blogDataRes.text();

    await this.blogService.incrementViewCount(id);
    return {
      id: blog.id,
      title: blog.title,
      createdAt: blog.createdAt,
      content: blogContent,
    };
  }

  @Get(':id/comments')
  async getBlogComments(
    @Param('id', new ParseUUIDPipe({ version: '4' })) id: string,
  ) {
    const blog = await this.blogService.findById(id);
    if (!blog) throw new BadRequestException('文章不存在');

    /** @todo 对文章可读性进行更详细的判定 */

    if (
      !blog.permissions.includes(BlogPermission.Public) &&
      !blog.permissions.includes(BlogPermission.ByPassword)
    ) {
      throw new BadRequestException('文章不存在或未公开');
    }

    return await this.blogService.getComments(blog);
  }

  // 该接口允许匿名评论，但仍需验证userId合法性
  @UseGuards(ThrottlerGuard, OptionalAuthGuard)
  @Throttle({ default: { limit: 5, ttl: 60000 } })
  @Post(':id/comment')
  async createBlogComment(
    @Param('id', new ParseUUIDPipe({ version: '4' })) id: string,
    @Body() commentData: createBlogCommentDto,
    @Req() req,
  ) {
    const { userId } = req.user || {};
    const blog = await this.blogService.findById(id);
    if (!blog) throw new BadRequestException('文章不存在');

    if (!blog.permissions.includes(BlogPermission.AllowComments)) {
      throw new BadRequestException('作者关闭了该文章的评论功能');
    }

    const user = userId ? await this.userService.findOne({ userId }) : null;

    const ip = req.headers['x-forwarded-for'] || req.ip;
    // 获取IP归属地
    let address = '未知';
    if (!['::1'].includes(ip)) {
      const addressRes = await (
        await fetch(
          `https://mesh.if.iqiyi.com/aid/ip/info?version=1.1.1&ip=${ip}`,
        )
      ).json();
      if (addressRes?.code == 0) {
        const country: string = addressRes?.data?.countryCN || '未知';
        const province: string = addressRes?.data?.provinceCN || '中国';
        if (country !== '中国') {
          // 非中国，显示国家
          address = country;
        } else {
          // 中国，显示省份
          address = province;
        }
      }
    }

    const comment = {
      ...commentData,
      blog,
      user,
      ip,
      address,
    };

    return await this.blogService.createComment(comment);
  }
}
