import { Injectable, NotFoundException, ConflictException, BadRequestException, ForbiddenException } from '@nestjs/common';
import { PrismaService } from '../../prisma/prisma.service';
import { NotificationService } from '../notifications/notification.service';

const SENSITIVE_WORDS = ['敏感词1', '敏感词2', '广告', '诈骗', '违法', '赌博'];

function containsSensitiveWord(text: string): string | null {
  const lower = text.toLowerCase();
  for (const word of SENSITIVE_WORDS) {
    if (lower.includes(word)) return word;
  }
  return null;
}

@Injectable()
export class CommunityService {
  constructor(
    private prisma: PrismaService,
    private notificationService: NotificationService,
  ) {}

  async findPosts(params: { page?: number; pageSize?: number; tag?: string; circleId?: number; userId?: number }) {
    const page = Number(params.page ?? 1);
    const pageSize = Math.min(Number(params.pageSize ?? 20), 50);
    const where: any = { status: 'PUBLISHED' };
    if (params.tag) where.tags = { contains: params.tag };
    if (params.circleId) where.circleId = params.circleId;
    if (params.userId) where.userId = params.userId;

    const [items, total] = await Promise.all([
      this.prisma.post.findMany({
        where,
        skip: (page - 1) * pageSize,
        take: pageSize,
        orderBy: { createdAt: 'desc' },
        include: { user: { select: { id: true, nickname: true, avatar: true } } },
      }),
      this.prisma.post.count({ where }),
    ]);

    return { items, total, page, pageSize };
  }

  async findPostById(id: number) {
    const post = await this.prisma.post.findUnique({
      where: { id },
      include: {
        user: { select: { id: true, nickname: true, avatar: true } },
        comments: {
          where: { status: 'PUBLISHED' },
          include: {
            user: { select: { id: true, nickname: true, avatar: true } },
            replies: {
              where: { status: 'PUBLISHED' },
              include: { user: { select: { id: true, nickname: true, avatar: true } } },
            },
          },
        },
      },
    });

    if (post) {
      await this.prisma.post.update({
        where: { id },
        data: { viewCount: { increment: 1 } },
      });
    }

    return post;
  }

  async createPost(userId: number, data: { title: string; content: string; tags?: string; circleId?: number }) {
    const post = await this.prisma.post.create({
      data: {
        userId,
        title: data.title,
        content: data.content,
        tags: data.tags,
        circleId: data.circleId,
      },
      include: { user: { select: { id: true, nickname: true, avatar: true } } },
    });

    await this.prisma.user.update({
      where: { id: userId },
      data: { postCount: { increment: 1 } },
    });

    return post;
  }

  async updatePost(userId: number, postId: number, data: { title?: string; content?: string; tags?: string }) {
    const post = await this.prisma.post.findUnique({ where: { id: postId } });
    if (!post) throw new NotFoundException('帖子不存在');
    if (post.userId !== userId) throw new BadRequestException('无权编辑此帖子');

    return this.prisma.post.update({
      where: { id: postId },
      data,
      include: { user: { select: { id: true, nickname: true, avatar: true } } },
    });
  }

  async deletePost(userId: number, postId: number) {
    const post = await this.prisma.post.findUnique({ where: { id: postId } });
    if (!post) throw new NotFoundException('帖子不存在');
    if (post.userId !== userId) throw new BadRequestException('无权删除此帖子');

    await this.prisma.post.delete({ where: { id: postId } });

    await this.prisma.user.update({
      where: { id: userId },
      data: { postCount: { decrement: 1 } },
    });

    return { deleted: true };
  }

  async addComment(userId: number, postId: number, content: string, parentId?: number) {
    const post = await this.prisma.post.findUnique({ where: { id: postId } });
    if (!post) throw new NotFoundException('帖子不存在');

    if (parentId) {
      const parentComment = await this.prisma.comment.findUnique({ where: { id: parentId } });
      if (!parentComment || parentComment.postId !== postId) {
        throw new BadRequestException('父评论不存在');
      }
    }

    const matchedWord = containsSensitiveWord(content);
    const status = matchedWord ? 'REJECTED' : 'PENDING_REVIEW';

    const comment = await this.prisma.comment.create({
      data: { userId, postId, content, parentId, status },
      include: { user: { select: { id: true, nickname: true, avatar: true } } },
    });

    if (matchedWord) {
      return { ...comment, rejected: true, reason: `评论包含敏感词「${matchedWord}」` };
    }

    await this.prisma.post.update({
      where: { id: postId },
      data: { commentCount: { increment: 1 } },
    });

    if (post.userId !== userId) {
      await this.notificationService.create({
        userId: post.userId,
        type: 'comment',
        title: `${comment.user.nickname || '用户'} 评论了你的帖子`,
        content: content.slice(0, 100),
        link: `/community/${postId}`,
        relatedId: postId,
      });
    }

    return comment;
  }

  async toggleLike(userId: number, postId: number) {
    const existing = await this.prisma.postLike.findFirst({ where: { userId, postId } });

    if (existing) {
      await this.prisma.postLike.delete({ where: { id: existing.id } });
      await this.prisma.post.update({
        where: { id: postId },
        data: { likeCount: { decrement: 1 } },
      });
      return { liked: false };
    } else {
      await this.prisma.postLike.create({ data: { userId, postId } });
      await this.prisma.post.update({
        where: { id: postId },
        data: { likeCount: { increment: 1 } },
      });

      const post = await this.prisma.post.findUnique({ where: { id: postId }, select: { userId: true, title: true } });
      if (post && post.userId !== userId) {
        await this.notificationService.create({
          userId: post.userId,
          type: 'like',
          title: `有人赞了你的帖子「${post.title.slice(0, 30)}」`,
          link: `/community/${postId}`,
          relatedId: postId,
        });
      }

      return { liked: true };
    }
  }

  async checkLike(userId: number, postId: number) {
    const existing = await this.prisma.postLike.findFirst({ where: { userId, postId } });
    return { liked: !!existing };
  }

  async getFeed(userId: number, params: { page?: number; pageSize?: number }) {
    const page = Number(params.page ?? 1);
    const pageSize = Math.min(Number(params.pageSize ?? 20), 50);

    const following = await this.prisma.follow.findMany({
      where: { followerId: userId },
      select: { followingId: true },
    });
    const followingIds = following.map(f => f.followingId);

    const where: any = { status: 'PUBLISHED' };
    if (followingIds.length > 0) {
      where.userId = { in: followingIds };
    }

    const [items, total] = await Promise.all([
      this.prisma.post.findMany({
        where,
        skip: (page - 1) * pageSize,
        take: pageSize,
        orderBy: { createdAt: 'desc' },
        include: { user: { select: { id: true, nickname: true, avatar: true } } },
      }),
      this.prisma.post.count({ where }),
    ]);

    return { items, total, page, pageSize };
  }

  async followUser(followerId: number, followingId: number) {
    if (followerId === followingId) throw new BadRequestException('不能关注自己');

    const existing = await this.prisma.follow.findUnique({
      where: { followerId_followingId: { followerId, followingId } },
    });
    if (existing) throw new ConflictException('已关注该用户');

    await this.prisma.follow.create({ data: { followerId, followingId } });
    await this.prisma.user.update({ where: { id: followerId }, data: { followingCount: { increment: 1 } } });
    await this.prisma.user.update({ where: { id: followingId }, data: { followerCount: { increment: 1 } } });

    const follower = await this.prisma.user.findUnique({ where: { id: followerId }, select: { nickname: true } });
    await this.notificationService.create({
      userId: followingId,
      type: 'follow',
      title: `${follower?.nickname || '用户'} 关注了你`,
      link: `/users/${followerId}`,
      relatedId: followerId,
    });

    return { followed: true };
  }

  async unfollowUser(followerId: number, followingId: number) {
    const existing = await this.prisma.follow.findUnique({
      where: { followerId_followingId: { followerId, followingId } },
    });
    if (!existing) throw new NotFoundException('未关注该用户');

    await this.prisma.follow.delete({ where: { id: existing.id } });
    await this.prisma.user.update({ where: { id: followerId }, data: { followingCount: { decrement: 1 } } });
    await this.prisma.user.update({ where: { id: followingId }, data: { followerCount: { decrement: 1 } } });

    return { followed: false };
  }

  async checkFollow(followerId: number, followingId: number) {
    const existing = await this.prisma.follow.findUnique({
      where: { followerId_followingId: { followerId, followingId } },
    });
    return { followed: !!existing };
  }

  async getFollowers(userId: number, params: { page?: number; pageSize?: number }) {
    const page = Number(params.page ?? 1);
    const pageSize = Math.min(Number(params.pageSize ?? 20), 50);

    const [items, total] = await Promise.all([
      this.prisma.follow.findMany({
        where: { followingId: userId },
        skip: (page - 1) * pageSize,
        take: pageSize,
        include: { follower: { select: { id: true, nickname: true, avatar: true, followerCount: true, followingCount: true } } },
        orderBy: { createdAt: 'desc' },
      }),
      this.prisma.follow.count({ where: { followingId: userId } }),
    ]);

    return { items: items.map(i => i.follower), total, page, pageSize };
  }

  async getFollowing(userId: number, params: { page?: number; pageSize?: number }) {
    const page = Number(params.page ?? 1);
    const pageSize = Math.min(Number(params.pageSize ?? 20), 50);

    const [items, total] = await Promise.all([
      this.prisma.follow.findMany({
        where: { followerId: userId },
        skip: (page - 1) * pageSize,
        take: pageSize,
        include: { following: { select: { id: true, nickname: true, avatar: true, followerCount: true, followingCount: true } } },
        orderBy: { createdAt: 'desc' },
      }),
      this.prisma.follow.count({ where: { followerId: userId } }),
    ]);

    return { items: items.map(i => i.following), total, page, pageSize };
  }

  async getUserProfile(userId: number) {
    const user = await this.prisma.user.findUnique({
      where: { id: userId, deletedAt: null },
      select: {
        id: true, nickname: true, avatar: true, bio: true,
        followerCount: true, followingCount: true, postCount: true,
        createdAt: true,
      },
    });
    if (!user) throw new NotFoundException('用户不存在');
    return user;
  }

  async findCircles(category?: string) {
    const where: any = {};
    if (category) where.tags = { contains: category };

    return this.prisma.circle.findMany({
      where,
      include: { _count: { select: { members: true, posts: true } } },
      orderBy: { createdAt: 'desc' },
    });
  }

  async findCircleById(id: number) {
    const circle = await this.prisma.circle.findUnique({
      where: { id },
      include: {
        _count: { select: { members: true, posts: true } },
        creator: { select: { id: true, nickname: true, avatar: true } },
      },
    });
    if (!circle) throw new NotFoundException('圈子不存在');
    return circle;
  }

  async findCirclePosts(circleId: number, params: { page?: number; pageSize?: number }) {
    return this.findPosts({ ...params, circleId });
  }

  async createCircle(userId: number, data: { name: string; description?: string; tags?: string }) {
    const existing = await this.prisma.circle.findFirst({ where: { name: data.name } });
    if (existing) throw new ConflictException('圈子名称已存在');

    return this.prisma.circle.create({
      data: { name: data.name, description: data.description, tags: data.tags, creatorId: userId },
      include: { _count: { select: { members: true } } },
    });
  }

  async joinCircle(userId: number, circleId: number) {
    const circle = await this.prisma.circle.findUnique({ where: { id: circleId } });
    if (!circle) throw new NotFoundException('圈子不存在');

    const existing = await this.prisma.circleMember.findUnique({
      where: { circleId_userId: { circleId, userId } },
    });
    if (existing) throw new ConflictException('已是圈子成员');

    return this.prisma.circleMember.create({ data: { circleId, userId } });
  }

  async leaveCircle(userId: number, circleId: number) {
    const existing = await this.prisma.circleMember.findUnique({
      where: { circleId_userId: { circleId, userId } },
    });
    if (!existing) throw new BadRequestException('不是圈子成员');

    await this.prisma.circleMember.delete({ where: { id: existing.id } });
    return { left: true };
  }

  async checkCircleMembership(userId: number, circleId: number) {
    const existing = await this.prisma.circleMember.findUnique({
      where: { circleId_userId: { circleId, userId } },
    });
    return { isMember: !!existing };
  }
}
