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

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

  async createOrganization(userId: number, data: { name: string; description?: string; contactName?: string; contactPhone?: string }) {
    const existing = await this.prisma.organization.findFirst({ where: { name: data.name } });
    if (existing) throw new ConflictException('组织名称已存在');

    const org = await this.prisma.organization.create({
      data: { name: data.name, description: data.description, contactName: data.contactName, contactPhone: data.contactPhone },
    });

    await this.prisma.organizationMember.create({
      data: { organizationId: org.id, userId, role: 'ADMIN' },
    });

    await this.prisma.organization.update({
      where: { id: org.id },
      data: { memberCount: { increment: 1 } },
    });

    return org;
  }

  async listOrganizations(page = 1, pageSize = 20) {
    page = Number(page);
    pageSize = Number(pageSize);
    const skip = (page - 1) * pageSize;
    const [items, total] = await Promise.all([
      this.prisma.organization.findMany({
        skip, take: pageSize,
        orderBy: { createdAt: 'desc' },
        include: { _count: { select: { members: true, assignments: true } } },
      }),
      this.prisma.organization.count(),
    ]);
    return { items, total, page, pageSize };
  }

  async getOrganization(id: number) {
    const org = await this.prisma.organization.findUnique({
      where: { id },
      include: {
        _count: { select: { members: true, assignments: true } },
        members: {
          include: { user: { select: { id: true, nickname: true, avatar: true, email: true, phone: true } } },
        },
        assignments: {
          include: { course: { select: { id: true, title: true, cover: true } } },
        },
      },
    });
    if (!org) throw new NotFoundException('组织不存在');
    return org;
  }

  async updateOrganization(id: number, data: { name?: string; description?: string; contactName?: string; contactPhone?: string }) {
    const org = await this.prisma.organization.findUnique({ where: { id } });
    if (!org) throw new NotFoundException('组织不存在');
    return this.prisma.organization.update({ where: { id }, data });
  }

  async addMember(orgId: number, adminId: number, userId: number, role = 'MEMBER') {
    const org = await this.prisma.organization.findUnique({ where: { id: orgId } });
    if (!org) throw new NotFoundException('组织不存在');

    const caller = await this.prisma.organizationMember.findUnique({
      where: { organizationId_userId: { organizationId: orgId, userId: adminId } },
    });
    if (!caller || caller.role !== 'ADMIN') throw new ForbiddenException('只有管理员可管理成员');

    const membership = await this.prisma.organizationMember.findUnique({
      where: { organizationId_userId: { organizationId: orgId, userId } },
    });
    if (membership) throw new ConflictException('该用户已是组织成员');

    await this.prisma.organizationMember.create({
      data: { organizationId: orgId, userId, role },
    });
    await this.prisma.organization.update({
      where: { id: orgId },
      data: { memberCount: { increment: 1 } },
    });
    return { added: true };
  }

  async removeMember(orgId: number, userId: number, callerId: number) {
    const membership = await this.prisma.organizationMember.findUnique({
      where: { organizationId_userId: { organizationId: orgId, userId } },
    });
    if (!membership) throw new NotFoundException('该用户不是组织成员');
    if (membership.role === 'ADMIN') throw new BadRequestException('不能移除管理员');

    const caller = await this.prisma.organizationMember.findUnique({
      where: { organizationId_userId: { organizationId: orgId, userId: callerId } },
    });
    if (!caller || caller.role !== 'ADMIN') throw new ForbiddenException('只有管理员可管理成员');

    await this.prisma.organizationMember.delete({ where: { id: membership.id } });
    await this.prisma.organization.update({
      where: { id: orgId },
      data: { memberCount: { decrement: 1 } },
    });
    return { removed: true };
  }

  async assignCourse(orgId: number, courseId: number, assignedBy: number, deadline?: string) {
    const [org, course] = await Promise.all([
      this.prisma.organization.findUnique({ where: { id: orgId } }),
      this.prisma.course.findUnique({ where: { id: courseId } }),
    ]);
    if (!org) throw new NotFoundException('组织不存在');
    if (!course) throw new NotFoundException('课程不存在');

    const existing = await this.prisma.courseAssignment.findFirst({
      where: { organizationId: orgId, courseId },
    });
    if (existing) throw new ConflictException('该课程已分配给此组织');

    return this.prisma.courseAssignment.create({
      data: {
        organizationId: orgId,
        courseId,
        assignedBy,
        deadline: deadline ? new Date(deadline) : undefined,
      },
      include: { course: { select: { id: true, title: true, cover: true } } },
    });
  }

  async removeAssignment(orgId: number, courseId: number) {
    const assignment = await this.prisma.courseAssignment.findFirst({
      where: { organizationId: orgId, courseId },
    });
    if (!assignment) throw new NotFoundException('未找到该课程分配');

    await this.prisma.courseAssignment.delete({ where: { id: assignment.id } });
    return { removed: true };
  }

  async getOrgProgress(orgId: number) {
    const members = await this.prisma.organizationMember.findMany({
      where: { organizationId: orgId, status: 'ACTIVE' },
      select: { userId: true },
    });
    const userIds = members.map(m => m.userId);

    const assignments = await this.prisma.courseAssignment.findMany({
      where: { organizationId: orgId },
      include: { course: { select: { id: true, title: true } } },
    });

    const courseIds = assignments.map(a => a.courseId);

    const records = await this.prisma.learnRecord.findMany({
      where: { userId: { in: userIds }, courseId: { in: courseIds } },
    });

    const totalLessons = await this.prisma.lesson.count({
      where: { chapter: { courseId: { in: courseIds } } },
    });

    const completedCount = records.filter(r => r.completed).length;
    const activeMembers = userIds.length;

    const progressByCourse = courseIds.map(courseId => {
      const courseLessons = records.filter(r => r.courseId === courseId);
      const uniqueLessons = new Set(courseLessons.map(r => r.lessonId));
      return {
        courseId,
        completedLessons: courseLessons.filter(r => r.completed).length,
        totalUniqueLessons: uniqueLessons.size,
      };
    });

    return {
      totalMembers: activeMembers,
      totalCourses: courseIds.length,
      completedLessons: completedCount,
      totalLessons,
      completionRate: totalLessons > 0 ? Math.round((completedCount / (totalLessons * Math.max(activeMembers, 1))) * 100) : 0,
      progressByCourse,
    };
  }

  async getMyOrganizations(userId: number) {
    const memberships = await this.prisma.organizationMember.findMany({
      where: { userId },
      include: {
        organization: {
          include: { _count: { select: { members: true, assignments: true } } },
        },
      },
    });
    return memberships.map(m => ({ ...m.organization, role: m.role }));
  }

  async getOrganizationReport(orgId: number) {
    const org = await this.getOrganization(orgId);
    const progress = await this.getOrgProgress(orgId);

    const memberProgress = await Promise.all(
      org.members.map(async (member) => {
        const records = await this.prisma.learnRecord.count({
          where: { userId: member.user.id, completed: true },
        });
        return { user: member.user, completedLessons: records };
      }),
    );

    return {
      organization: { id: org.id, name: org.name, memberCount: org._count.members },
      summary: progress,
      memberProgress,
      assignments: org.assignments,
    };
  }
}
