import { Injectable } from '@nestjs/common';
import { PrismaService } from '../../database/prisma.service';

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

  // ==================== 套餐管理 ====================

  async findAllPackages(params: {
    status?: string;
    page?: number;
    pageSize?: number;
  }) {
    const { status, page = 1, pageSize = 20 } = params;
    const skip = (page - 1) * pageSize;

    const where: any = {};
    if (status) {
      where.status = status;
    }

    const [items, total] = await Promise.all([
      this.prisma.coursePackage.findMany({
        where,
        include: {
          _count: {
            select: { courses: true, tenantPackages: true },
          },
        },
        orderBy: { createdAt: 'desc' },
        skip,
        take: pageSize,
      }),
      this.prisma.coursePackage.count({ where }),
    ]);

    return {
      items: items.map((pkg) => ({
        ...pkg,
        courseCount: pkg._count.courses,
        tenantCount: pkg._count.tenantPackages,
      })),
      total,
      page,
      pageSize,
    };
  }

  async findOnePackage(id: number) {
    const pkg = await this.prisma.coursePackage.findUnique({
      where: { id },
      include: {
        courses: {
          include: {
            course: {
              select: {
                id: true,
                name: true,
                coverImagePath: true,
                duration: true,
                gradeTags: true,
              },
            },
          },
          orderBy: { sortOrder: 'asc' },
        },
      },
    });

    if (!pkg) {
      throw new Error('套餐不存在');
    }

    return pkg;
  }

  async createPackage(data: {
    name: string;
    description?: string;
    price: number;
    discountPrice?: number;
    discountType?: string;
    gradeLevels: string[];
  }) {
    return this.prisma.coursePackage.create({
      data: {
        name: data.name,
        description: data.description,
        price: data.price,
        discountPrice: data.discountPrice,
        discountType: data.discountType,
        gradeLevels: JSON.stringify(data.gradeLevels),
        status: 'DRAFT',
      },
    });
  }

  async updatePackage(
    id: number,
    data: {
      name?: string;
      description?: string;
      price?: number;
      discountPrice?: number;
      discountType?: string;
      gradeLevels?: string[];
    },
  ) {
    const updateData: any = { ...data };
    if (data.gradeLevels) {
      updateData.gradeLevels = JSON.stringify(data.gradeLevels);
    }

    return this.prisma.coursePackage.update({
      where: { id },
      data: updateData,
    });
  }

  async deletePackage(id: number) {
    // 检查是否有租户正在使用
    const tenantCount = await this.prisma.tenantPackage.count({
      where: { packageId: id, status: 'ACTIVE' },
    });

    if (tenantCount > 0) {
      throw new Error(`有 ${tenantCount} 个租户正在使用该套餐，无法删除`);
    }

    return this.prisma.coursePackage.delete({
      where: { id },
    });
  }

  // ==================== 套餐课程管理 ====================

  async setPackageCourses(
    packageId: number,
    courses: { courseId: number; gradeLevel: string; sortOrder?: number }[],
  ) {
    // 删除现有关联
    await this.prisma.coursePackageCourse.deleteMany({
      where: { packageId },
    });

    // 创建新关联
    if (courses.length > 0) {
      await this.prisma.coursePackageCourse.createMany({
        data: courses.map((c, index) => ({
          packageId,
          courseId: c.courseId,
          gradeLevel: c.gradeLevel,
          sortOrder: c.sortOrder ?? index,
        })),
      });
    }

    // 更新套餐课程数
    await this.prisma.coursePackage.update({
      where: { id: packageId },
      data: { courseCount: courses.length },
    });

    return this.findOnePackage(packageId);
  }

  async addCourseToPackage(
    packageId: number,
    courseId: number,
    gradeLevel: string,
    sortOrder?: number,
  ) {
    // 检查是否已存在
    const existing = await this.prisma.coursePackageCourse.findUnique({
      where: {
        packageId_courseId: { packageId, courseId },
      },
    });

    if (existing) {
      throw new Error('该课程已在套餐中');
    }

    await this.prisma.coursePackageCourse.create({
      data: {
        packageId,
        courseId,
        gradeLevel,
        sortOrder: sortOrder ?? 0,
      },
    });

    // 更新套餐课程数
    const count = await this.prisma.coursePackageCourse.count({
      where: { packageId },
    });
    await this.prisma.coursePackage.update({
      where: { id: packageId },
      data: { courseCount: count },
    });

    return this.findOnePackage(packageId);
  }

  async removeCourseFromPackage(packageId: number, courseId: number) {
    await this.prisma.coursePackageCourse.delete({
      where: {
        packageId_courseId: { packageId, courseId },
      },
    });

    // 更新套餐课程数
    const count = await this.prisma.coursePackageCourse.count({
      where: { packageId },
    });
    await this.prisma.coursePackage.update({
      where: { id: packageId },
      data: { courseCount: count },
    });

    return this.findOnePackage(packageId);
  }

  // ==================== 套餐状态管理 ====================

  async submitPackage(id: number, userId: number) {
    const pkg = await this.prisma.coursePackage.findUnique({
      where: { id },
      include: { _count: { select: { courses: true } } },
    });

    if (!pkg) {
      throw new Error('套餐不存在');
    }

    if (pkg._count.courses === 0) {
      throw new Error('套餐必须包含至少一个课程包');
    }

    return this.prisma.coursePackage.update({
      where: { id },
      data: {
        status: 'PENDING_REVIEW',
        submittedAt: new Date(),
        submittedBy: userId,
      },
    });
  }

  async reviewPackage(
    id: number,
    userId: number,
    approved: boolean,
    comment?: string,
  ) {
    const pkg = await this.prisma.coursePackage.findUnique({
      where: { id },
    });

    if (!pkg) {
      throw new Error('套餐不存在');
    }

    if (pkg.status !== 'PENDING_REVIEW') {
      throw new Error('只有待审核状态的套餐可以审核');
    }

    return this.prisma.coursePackage.update({
      where: { id },
      data: {
        status: approved ? 'APPROVED' : 'REJECTED',
        reviewedAt: new Date(),
        reviewedBy: userId,
        reviewComment: comment,
      },
    });
  }

  async publishPackage(id: number) {
    const pkg = await this.prisma.coursePackage.findUnique({
      where: { id },
    });

    if (!pkg) {
      throw new Error('套餐不存在');
    }

    if (pkg.status !== 'APPROVED') {
      throw new Error('只有已审核通过的套餐可以发布');
    }

    return this.prisma.coursePackage.update({
      where: { id },
      data: {
        status: 'PUBLISHED',
        publishedAt: new Date(),
      },
    });
  }

  async offlinePackage(id: number) {
    return this.prisma.coursePackage.update({
      where: { id },
      data: {
        status: 'OFFLINE',
      },
    });
  }

  // ==================== 学校端查询 ====================

  async findTenantPackages(tenantId: number) {
    return this.prisma.tenantPackage.findMany({
      where: {
        tenantId,
        status: 'ACTIVE',
      },
      include: {
        package: {
          include: {
            courses: {
              include: {
                course: {
                  select: {
                    id: true,
                    name: true,
                    coverImagePath: true,
                  },
                },
              },
            },
          },
        },
      },
      orderBy: { createdAt: 'desc' },
    });
  }

  async renewTenantPackage(
    tenantId: number,
    packageId: number,
    endDate: string,
    pricePaid?: number,
  ) {
    const existing = await this.prisma.tenantPackage.findFirst({
      where: { tenantId, packageId },
    });

    if (existing) {
      return this.prisma.tenantPackage.update({
        where: { id: existing.id },
        data: {
          endDate,
          status: 'ACTIVE',
          pricePaid: pricePaid ?? existing.pricePaid,
        },
      });
    }

    return this.prisma.tenantPackage.create({
      data: {
        tenantId,
        packageId,
        startDate: new Date().toISOString().split('T')[0],
        endDate,
        status: 'ACTIVE',
        pricePaid: pricePaid ?? 0,
      },
    });
  }
}
