import { Injectable, NotFoundException, ForbiddenException, Logger } from '@nestjs/common';
import { PrismaService } from '../../database/prisma.service';
import { CreateGrowthRecordDto, UpdateGrowthRecordDto } from './dto/create-growth.dto';

@Injectable()
export class GrowthService {
  private readonly logger = new Logger(GrowthService.name);

  constructor(private prisma: PrismaService) {}

  private parseJsonArray(value: any): any[] {
    if (!value) return [];
    if (typeof value === 'string') {
      try {
        return JSON.parse(value);
      } catch {
        return [];
      }
    }
    return Array.isArray(value) ? value : [];
  }

  // ==================== 成长档案管理 ====================

  async findAll(tenantId: number, query: any) {
    const { page = 1, pageSize = 10, studentId, classId, recordType, keyword } = query;

    const skip = (page - 1) * pageSize;
    const take = +pageSize;

    const where: any = {
      tenantId: tenantId,
    };

    if (studentId) {
      where.studentId = +studentId;
    }

    if (classId) {
      where.classId = +classId;
    }

    if (recordType) {
      where.recordType = recordType;
    }

    if (keyword) {
      where.OR = [
        { title: { contains: keyword } },
        { content: { contains: keyword } },
      ];
    }

    const [items, total] = await Promise.all([
      this.prisma.growthRecord.findMany({
        where,
        skip,
        take,
        orderBy: { recordDate: 'desc' },
        include: {
          student: {
            select: {
              id: true,
              name: true,
              gender: true,
            },
          },
          class: {
            select: {
              id: true,
              name: true,
              grade: true,
            },
          },
        },
      }),
      this.prisma.growthRecord.count({ where }),
    ]);

    return {
      items: items.map((item) => ({
        ...item,
        images: this.parseJsonArray(item.images),
      })),
      total,
      page: +page,
      pageSize: +pageSize,
    };
  }

  /**
   * 教师端查询成长档案（带数据隔离）
   * 仅返回教师所教班级学生的档案
   */
  async findAllForTeacher(tenantId: number, teacherId: number, query: any) {
    const { page = 1, pageSize = 10, studentId, classId, recordType, keyword } = query;

    const skip = (page - 1) * pageSize;
    const take = +pageSize;

    // 获取教师关联的所有班级ID
    const classTeachers = await this.prisma.classTeacher.findMany({
      where: { teacherId },
      select: { classId: true },
    });

    const classIds = classTeachers.map((ct) => ct.classId);

    if (classIds.length === 0) {
      return {
        items: [],
        total: 0,
        page: +page,
        pageSize: +pageSize,
      };
    }

    const where: any = {
      tenantId: tenantId,
      classId: { in: classIds }, // 数据隔离：只查询教师所教班级的档案
    };

    if (studentId) {
      where.studentId = +studentId;
    }

    // 如果指定了 classId，需要验证是否在教师的班级列表中
    if (classId) {
      if (!classIds.includes(+classId)) {
        throw new ForbiddenException('您没有权限查看该班级的档案');
      }
      where.classId = +classId;
    }

    if (recordType) {
      where.recordType = recordType;
    }

    if (keyword) {
      where.OR = [
        { title: { contains: keyword } },
        { content: { contains: keyword } },
      ];
    }

    const [items, total] = await Promise.all([
      this.prisma.growthRecord.findMany({
        where,
        skip,
        take,
        orderBy: { recordDate: 'desc' },
        include: {
          student: {
            select: {
              id: true,
              name: true,
              gender: true,
            },
          },
          class: {
            select: {
              id: true,
              name: true,
              grade: true,
            },
          },
        },
      }),
      this.prisma.growthRecord.count({ where }),
    ]);

    return {
      items: items.map((item) => ({
        ...item,
        images: this.parseJsonArray(item.images),
      })),
      total,
      page: +page,
      pageSize: +pageSize,
    };
  }

  /**
   * 教师端查询单个档案（带数据隔离）
   */
  async findOneForTeacher(tenantId: number, teacherId: number, id: number) {
    const record = await this.prisma.growthRecord.findFirst({
      where: {
        id: id,
        tenantId: tenantId,
      },
      include: {
        student: {
          select: {
            id: true,
            name: true,
            gender: true,
            birthDate: true,
          },
        },
        class: {
          select: {
            id: true,
            name: true,
            grade: true,
          },
        },
      },
    });

    if (!record) {
      throw new NotFoundException('成长档案不存在');
    }

    // 验证教师是否有权限查看该班级的档案
    const classTeacher = await this.prisma.classTeacher.findFirst({
      where: { teacherId, classId: record.classId },
    });

    if (!classTeacher) {
      throw new ForbiddenException('您没有权限查看此档案');
    }

    return {
      ...record,
      images: this.parseJsonArray(record.images),
    };
  }

  /**
   * 教师端创建档案（带数据隔离验证）
   */
  async createForTeacher(tenantId: number, teacherId: number, dto: CreateGrowthRecordDto) {
    // 验证学生是否存在
    const student = await this.prisma.student.findFirst({
      where: {
        id: dto.studentId,
        tenantId: tenantId,
      },
    });

    if (!student) {
      throw new NotFoundException('学生不存在');
    }

    // 验证教师是否有权限为该班级创建档案
    const classId = dto.classId || student.classId;
    const classTeacher = await this.prisma.classTeacher.findFirst({
      where: { teacherId, classId },
    });

    if (!classTeacher) {
      throw new ForbiddenException('您没有权限为此班级创建档案');
    }

    const record = await this.prisma.growthRecord.create({
      data: {
        tenantId: tenantId,
        studentId: dto.studentId,
        classId: classId,
        recordType: dto.recordType,
        title: dto.title,
        content: dto.content,
        images: JSON.stringify(dto.images || []),
        recordDate: new Date(dto.recordDate),
        createdBy: teacherId,
      },
      include: {
        student: {
          select: {
            id: true,
            name: true,
          },
        },
        class: {
          select: {
            id: true,
            name: true,
          },
        },
      },
    });

    this.logger.log(`Growth record created by teacher: ${record.id}`);

    return {
      ...record,
      images: this.parseJsonArray(record.images),
    };
  }

  /**
   * 教师端更新档案（带数据隔离验证）
   */
  async updateForTeacher(tenantId: number, teacherId: number, id: number, dto: UpdateGrowthRecordDto) {
    const existing = await this.prisma.growthRecord.findFirst({
      where: {
        id: id,
        tenantId: tenantId,
      },
    });

    if (!existing) {
      throw new NotFoundException('成长档案不存在');
    }

    // 验证教师是否有权限更新该班级的档案
    const classTeacher = await this.prisma.classTeacher.findFirst({
      where: { teacherId, classId: existing.classId },
    });

    if (!classTeacher) {
      throw new ForbiddenException('您没有权限更新此档案');
    }

    const record = await this.prisma.growthRecord.update({
      where: { id: id },
      data: {
        title: dto.title,
        content: dto.content,
        images: dto.images ? JSON.stringify(dto.images) : undefined,
        recordDate: dto.recordDate ? new Date(dto.recordDate) : undefined,
      },
      include: {
        student: {
          select: {
            id: true,
            name: true,
          },
        },
        class: {
          select: {
            id: true,
            name: true,
          },
        },
      },
    });

    this.logger.log(`Growth record updated by teacher: ${id}`);

    return {
      ...record,
      images: this.parseJsonArray(record.images),
    };
  }

  /**
   * 教师端删除档案（带数据隔离验证）
   */
  async deleteForTeacher(tenantId: number, teacherId: number, id: number) {
    const existing = await this.prisma.growthRecord.findFirst({
      where: {
        id: id,
        tenantId: tenantId,
      },
    });

    if (!existing) {
      throw new NotFoundException('成长档案不存在');
    }

    // 验证教师是否有权限删除该班级的档案
    const classTeacher = await this.prisma.classTeacher.findFirst({
      where: { teacherId, classId: existing.classId },
    });

    if (!classTeacher) {
      throw new ForbiddenException('您没有权限删除此档案');
    }

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

    this.logger.log(`Growth record deleted by teacher: ${id}`);

    return { message: '删除成功' };
  }

  async findOne(tenantId: number, id: number) {
    const record = await this.prisma.growthRecord.findFirst({
      where: {
        id: id,
        tenantId: tenantId,
      },
      include: {
        student: {
          select: {
            id: true,
            name: true,
            gender: true,
            birthDate: true,
          },
        },
        class: {
          select: {
            id: true,
            name: true,
            grade: true,
          },
        },
      },
    });

    if (!record) {
      throw new NotFoundException('成长档案不存在');
    }

    return {
      ...record,
      images: this.parseJsonArray(record.images),
    };
  }

  async create(tenantId: number, userId: number, dto: CreateGrowthRecordDto) {
    // 验证学生是否存在
    const student = await this.prisma.student.findFirst({
      where: {
        id: dto.studentId,
        tenantId: tenantId,
      },
    });

    if (!student) {
      throw new NotFoundException('学生不存在');
    }

    const record = await this.prisma.growthRecord.create({
      data: {
        tenantId: tenantId,
        studentId: dto.studentId,
        classId: dto.classId || student.classId,
        recordType: dto.recordType,
        title: dto.title,
        content: dto.content,
        images: JSON.stringify(dto.images || []),
        recordDate: new Date(dto.recordDate),
        createdBy: userId,
      },
      include: {
        student: {
          select: {
            id: true,
            name: true,
          },
        },
        class: {
          select: {
            id: true,
            name: true,
          },
        },
      },
    });

    this.logger.log(`Growth record created: ${record.id}`);

    return {
      ...record,
      images: this.parseJsonArray(record.images),
    };
  }

  async update(tenantId: number, id: number, dto: UpdateGrowthRecordDto) {
    const existing = await this.prisma.growthRecord.findFirst({
      where: {
        id: id,
        tenantId: tenantId,
      },
    });

    if (!existing) {
      throw new NotFoundException('成长档案不存在');
    }

    const record = await this.prisma.growthRecord.update({
      where: { id: id },
      data: {
        title: dto.title,
        content: dto.content,
        images: dto.images ? JSON.stringify(dto.images) : undefined,
        recordDate: dto.recordDate ? new Date(dto.recordDate) : undefined,
      },
      include: {
        student: {
          select: {
            id: true,
            name: true,
          },
        },
        class: {
          select: {
            id: true,
            name: true,
          },
        },
      },
    });

    this.logger.log(`Growth record updated: ${id}`);

    return {
      ...record,
      images: this.parseJsonArray(record.images),
    };
  }

  async delete(tenantId: number, id: number) {
    const existing = await this.prisma.growthRecord.findFirst({
      where: {
        id: id,
        tenantId: tenantId,
      },
    });

    if (!existing) {
      throw new NotFoundException('成长档案不存在');
    }

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

    this.logger.log(`Growth record deleted: ${id}`);

    return { message: '删除成功' };
  }

  // ==================== 学生档案列表 ====================

  async findByStudent(tenantId: number, studentId: number, query: any) {
    const { page = 1, pageSize = 10 } = query;

    const skip = (page - 1) * pageSize;
    const take = +pageSize;

    // 验证学生是否存在
    const student = await this.prisma.student.findFirst({
      where: {
        id: studentId,
        tenantId: tenantId,
      },
    });

    if (!student) {
      throw new NotFoundException('学生不存在');
    }

    const [items, total] = await Promise.all([
      this.prisma.growthRecord.findMany({
        where: {
          studentId: studentId,
          tenantId: tenantId,
        },
        skip,
        take,
        orderBy: { recordDate: 'desc' },
      }),
      this.prisma.growthRecord.count({
        where: {
          studentId: studentId,
          tenantId: tenantId,
        },
      }),
    ]);

    return {
      items: items.map((item) => ({
        ...item,
        images: this.parseJsonArray(item.images),
      })),
      total,
      page: +page,
      pageSize: +pageSize,
    };
  }

  // ==================== 班级档案列表 ====================

  async findByClass(tenantId: number, classId: number, query: any) {
    const { page = 1, pageSize = 10, recordDate } = query;

    const skip = (page - 1) * pageSize;
    const take = +pageSize;

    // 验证班级是否存在
    const classEntity = await this.prisma.class.findFirst({
      where: {
        id: classId,
        tenantId: tenantId,
      },
    });

    if (!classEntity) {
      throw new NotFoundException('班级不存在');
    }

    const where: any = {
      classId: classId,
      tenantId: tenantId,
      recordType: 'CLASS',
    };

    if (recordDate) {
      where.recordDate = new Date(recordDate);
    }

    const [items, total] = await Promise.all([
      this.prisma.growthRecord.findMany({
        where,
        skip,
        take,
        orderBy: { recordDate: 'desc' },
        include: {
          student: {
            select: {
              id: true,
              name: true,
            },
          },
        },
      }),
      this.prisma.growthRecord.count({ where }),
    ]);

    return {
      items: items.map((item) => ({
        ...item,
        images: this.parseJsonArray(item.images),
      })),
      total,
      page: +page,
      pageSize: +pageSize,
    };
  }
}
