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

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

  // ==================== 校本课程包管理 ====================

  async findAll(tenantId?: number, createdBy?: number) {
    const where: any = {};
    if (tenantId) {
      where.tenantId = tenantId;
    }
    if (createdBy) {
      where.createdBy = createdBy;
    }

    return this.prisma.schoolCourse.findMany({
      where,
      include: {
        sourceCourse: {
          select: {
            id: true,
            name: true,
            coverImagePath: true,
          },
        },
        _count: {
          select: { lessons: true, reservations: true },
        },
      },
      orderBy: { createdAt: 'desc' },
    });
  }

  async findOne(id: number, tenantId?: number) {
    const where: any = { id };
    if (tenantId) {
      where.tenantId = tenantId;
    }

    const schoolCourse = await this.prisma.schoolCourse.findFirst({
      where,
      include: {
        sourceCourse: {
          select: {
            id: true,
            name: true,
            coverImagePath: true,
            description: true,
          },
        },
        lessons: {
          orderBy: { lessonType: 'asc' },
        },
        reservations: {
          orderBy: { createdAt: 'desc' },
          take: 10,
        },
      },
    });

    if (!schoolCourse) {
      throw new Error('校本课程包不存在');
    }

    return schoolCourse;
  }

  async create(
    tenantId: number,
    sourceCourseId: number,
    createdBy: number,
    data: {
      name: string;
      description?: string;
      changesSummary?: string;
    },
  ) {
    // 检查源课程是否存在
    const sourceCourse = await this.prisma.course.findUnique({
      where: { id: sourceCourseId },
      include: {
        courseLessons: {
          include: {
            steps: true,
          },
        },
      },
    });

    if (!sourceCourse) {
      throw new Error('源课程包不存在');
    }

    // 检查租户是否有权限
    const hasAccess = await this.checkTenantAccess(tenantId, sourceCourseId);
    if (!hasAccess) {
      throw new Error('无权访问该课程包');
    }

    // 创建校本课程包
    const schoolCourse = await this.prisma.schoolCourse.create({
      data: {
        tenantId,
        sourceCourseId,
        name: data.name,
        description: data.description,
        createdBy,
        changesSummary: data.changesSummary,
      },
    });

    // 复制源课程的课程
    for (const lesson of sourceCourse.courseLessons) {
      await this.prisma.schoolCourseLesson.create({
        data: {
          schoolCourseId: schoolCourse.id,
          sourceLessonId: lesson.id,
          lessonType: lesson.lessonType,
          objectives: lesson.objectives,
          preparation: lesson.preparation,
          extension: lesson.extension,
          reflection: lesson.reflection,
          stepsData: JSON.stringify(lesson.steps),
        },
      });
    }

    return this.findOne(schoolCourse.id);
  }

  async update(
    id: number,
    tenantId: number,
    data: {
      name?: string;
      description?: string;
      changesSummary?: string;
      status?: string;
    },
  ) {
    // 验证权限
    const existing = await this.prisma.schoolCourse.findFirst({
      where: { id, tenantId },
    });

    if (!existing) {
      throw new Error('校本课程包不存在或无权访问');
    }

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

  async delete(id: number, tenantId: number) {
    // 验证权限
    const existing = await this.prisma.schoolCourse.findFirst({
      where: { id, tenantId },
    });

    if (!existing) {
      throw new Error('校本课程包不存在或无权访问');
    }

    // 检查是否有预约
    const reservationCount = await this.prisma.schoolCourseReservation.count({
      where: { schoolCourseId: id, status: 'PENDING' },
    });

    if (reservationCount > 0) {
      throw new Error(`有 ${reservationCount} 个待进行的预约，无法删除`);
    }

    await this.prisma.schoolCourse.delete({
      where: { id },
    });

    return { success: true };
  }

  // ==================== 校本课程管理 ====================

  async findLessons(schoolCourseId: number, tenantId: number) {
    // 验证权限
    const schoolCourse = await this.prisma.schoolCourse.findFirst({
      where: { id: schoolCourseId, tenantId },
    });

    if (!schoolCourse) {
      throw new Error('校本课程包不存在或无权访问');
    }

    return this.prisma.schoolCourseLesson.findMany({
      where: { schoolCourseId },
      orderBy: { lessonType: 'asc' },
    });
  }

  async updateLesson(
    schoolCourseId: number,
    lessonId: number,
    tenantId: number,
    data: {
      objectives?: string;
      preparation?: string;
      extension?: string;
      reflection?: string;
      changeNote?: string;
      stepsData?: string;
    },
  ) {
    // 验证权限
    const schoolCourse = await this.prisma.schoolCourse.findFirst({
      where: { id: schoolCourseId, tenantId },
    });

    if (!schoolCourse) {
      throw new Error('校本课程包不存在或无权访问');
    }

    return this.prisma.schoolCourseLesson.update({
      where: { id: lessonId },
      data,
    });
  }

  // ==================== 预约管理 ====================

  async findReservations(schoolCourseId: number, tenantId: number) {
    // 验证权限
    const schoolCourse = await this.prisma.schoolCourse.findFirst({
      where: { id: schoolCourseId, tenantId },
    });

    if (!schoolCourse) {
      throw new Error('校本课程包不存在或无权访问');
    }

    return this.prisma.schoolCourseReservation.findMany({
      where: { schoolCourseId },
      orderBy: { scheduledDate: 'asc' },
    });
  }

  async createReservation(
    schoolCourseId: number,
    tenantId: number,
    data: {
      teacherId: number;
      classId: number;
      scheduledDate: string;
      scheduledTime?: string;
      note?: string;
    },
  ) {
    // 验证权限
    const schoolCourse = await this.prisma.schoolCourse.findFirst({
      where: { id: schoolCourseId, tenantId },
    });

    if (!schoolCourse) {
      throw new Error('校本课程包不存在或无权访问');
    }

    // 验证教师和班级属于该租户
    const [teacher, class_] = await Promise.all([
      this.prisma.teacher.findFirst({
        where: { id: data.teacherId, tenantId },
      }),
      this.prisma.class.findFirst({
        where: { id: data.classId, tenantId },
      }),
    ]);

    if (!teacher) {
      throw new Error('教师不存在或不属于该学校');
    }
    if (!class_) {
      throw new Error('班级不存在或不属于该学校');
    }

    const reservation = await this.prisma.schoolCourseReservation.create({
      data: {
        schoolCourseId,
        teacherId: data.teacherId,
        classId: data.classId,
        scheduledDate: data.scheduledDate,
        scheduledTime: data.scheduledTime,
        note: data.note,
        status: 'PENDING',
      },
    });

    // 更新使用次数
    await this.prisma.schoolCourse.update({
      where: { id: schoolCourseId },
      data: { usageCount: { increment: 1 } },
    });

    return reservation;
  }

  async updateReservationStatus(
    reservationId: number,
    tenantId: number,
    status: string,
  ) {
    const reservation = await this.prisma.schoolCourseReservation.findFirst({
      where: { id: reservationId },
      include: { schoolCourse: true },
    });

    if (!reservation || reservation.schoolCourse.tenantId !== tenantId) {
      throw new Error('预约不存在或无权访问');
    }

    return this.prisma.schoolCourseReservation.update({
      where: { id: reservationId },
      data: { status },
    });
  }

  async cancelReservation(reservationId: number, tenantId: number) {
    return this.updateReservationStatus(reservationId, tenantId, 'CANCELLED');
  }

  // ==================== 辅助方法 ====================

  private async checkTenantAccess(tenantId: number, courseId: number) {
    // 检查直接授权
    const tenantCourse = await this.prisma.tenantCourse.findFirst({
      where: { tenantId, courseId, authorized: true },
    });

    if (tenantCourse) {
      return true;
    }

    // 检查套餐授权
    const tenantPackage = await this.prisma.tenantPackage.findFirst({
      where: {
        tenantId,
        status: 'ACTIVE',
        package: {
          courses: {
            some: { courseId },
          },
        },
      },
    });

    return !!tenantPackage;
  }

  // 获取可创建校本课程包的源课程列表
  async getSourceCourses(tenantId: number) {
    // 通过套餐获取课程
    const tenantPackages = await this.prisma.tenantPackage.findMany({
      where: { tenantId, status: 'ACTIVE' },
      include: {
        package: {
          include: {
            courses: {
              include: {
                course: {
                  select: {
                    id: true,
                    name: true,
                    coverImagePath: true,
                    description: true,
                    duration: true,
                  },
                },
              },
            },
          },
        },
      },
    });

    const courses = new Map();
    for (const tp of tenantPackages) {
      for (const pc of tp.package.courses) {
        if (!courses.has(pc.course.id)) {
          courses.set(pc.course.id, pc.course);
        }
      }
    }

    return Array.from(courses.values());
  }
}
