import { Injectable, NotFoundException, ForbiddenException } from '@nestjs/common';
import { PrismaService } from '../../prisma/prisma.service';
import { CreateGroupDto, UpdateGroupDto } from './dto/group.dto';

@Injectable()
export class GroupsService {
  constructor(private prisma: PrismaService) {}

  async findAll(userId: string) {
    const groups = await this.prisma.group.findMany({
      where: {
        OR: [
          { type: 'PUBLIC' },
          { type: 'PREMIUM' },
          { members: { some: { userId } } },
        ],
      },
      include: {
        _count: { select: { members: true, messages: true } },
        members: { where: { userId }, select: { userId: true }, take: 1 },
      },
      orderBy: { createdAt: 'desc' },
    });
    // Add isMember convenience flag
    return groups.map((g) => ({ ...g, isMember: g.members.length > 0 }));
  }

  async findOne(id: string, userId: string) {
    const group = await this.prisma.group.findUnique({
      where: { id },
      include: {
        members: {
          include: { user: { select: { id: true, name: true, profilePicture: true } } },
        },
        _count: { select: { members: true, messages: true } },
      },
    });
    if (!group) throw new NotFoundException('Group not found');

    if (group.type !== 'PUBLIC') {
      const isMember = group.members.some((m) => m.userId === userId);
      if (!isMember) throw new ForbiddenException('Access denied');
    }

    return group;
  }

  async create(dto: CreateGroupDto, createdById: string) {
    const group = await this.prisma.group.create({
      data: { ...dto, createdById },
    });
    await this.prisma.groupMember.create({
      data: { groupId: group.id, userId: createdById, role: 'moderator' },
    });
    return group;
  }

  async update(id: string, dto: UpdateGroupDto) {
    return this.prisma.group.update({ where: { id }, data: dto });
  }

  async delete(id: string) {
    return this.prisma.group.delete({ where: { id } });
  }

  async join(groupId: string, userId: string) {
    const group = await this.prisma.group.findUnique({ where: { id: groupId } });
    if (!group) throw new NotFoundException('Group not found');
    if (group.type === 'PRIVATE') throw new ForbiddenException('This group is invite-only');

    return this.prisma.groupMember.upsert({
      where: { groupId_userId: { groupId, userId } },
      update: {},
      create: { groupId, userId },
    });
  }

  async leave(groupId: string, userId: string) {
    return this.prisma.groupMember.delete({
      where: { groupId_userId: { groupId, userId } },
    });
  }

  async addMember(groupId: string, userId: string, role = 'member') {
    return this.prisma.groupMember.upsert({
      where: { groupId_userId: { groupId, userId } },
      update: { role },
      create: { groupId, userId, role },
    });
  }

  async removeMember(groupId: string, userId: string) {
    return this.prisma.groupMember.delete({
      where: { groupId_userId: { groupId, userId } },
    });
  }
}
