import {
  Injectable,
  NotFoundException,
  ConflictException,
} from '@nestjs/common';
import { PrismaService } from '../../prisma/prisma.service';
import { CreateTeacherDto } from './dto/create-teacher.dto';
import { UpdateTeacherDto } from './dto/update-teacher.dto';
import * as bcrypt from 'bcrypt';

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

  async create(
    createTeacherDto: CreateTeacherDto,
    tenantId: number,
    creatorId?: number,
  ) {
    // 验证部门是否存在且属于该租户
    const department = await this.prisma.department.findFirst({
      where: {
        id: createTeacherDto.departmentId,
        tenantId,
        validState: 1,
      },
    });

    if (!department) {
      throw new NotFoundException('部门不存在或不属于该租户');
    }

    // 检查用户名是否已存在
    const existingUser = await this.prisma.user.findFirst({
      where: {
        tenantId,
        username: createTeacherDto.username,
      },
    });

    if (existingUser) {
      throw new ConflictException('用户名已存在');
    }

    // 如果提供了工号，检查工号是否已存在
    if (createTeacherDto.employeeNo) {
      const existingTeacher = await this.prisma.teacher.findFirst({
        where: {
          tenantId,
          employeeNo: createTeacherDto.employeeNo,
        },
      });

      if (existingTeacher) {
        throw new ConflictException('工号已存在');
      }
    }

    // 加密密码
    const hashedPassword = await bcrypt.hash(createTeacherDto.password, 10);

    // 创建 User 记录
    const userData: any = {
      username: createTeacherDto.username,
      password: hashedPassword,
      nickname: createTeacherDto.nickname,
      tenantId,
    };

    if (createTeacherDto.email) {
      userData.email = createTeacherDto.email;
    }

    if (createTeacherDto.avatar) {
      userData.avatar = createTeacherDto.avatar;
    }

    if (creatorId) {
      userData.creator = creatorId;
    }

    // 创建 Teacher 记录
    const teacherData: any = {
      departmentId: createTeacherDto.departmentId,
      tenantId,
    };

    if (createTeacherDto.employeeNo) {
      teacherData.employeeNo = createTeacherDto.employeeNo;
    }

    if (createTeacherDto.phone) {
      teacherData.phone = createTeacherDto.phone;
    }

    if (createTeacherDto.idCard) {
      teacherData.idCard = createTeacherDto.idCard;
    }

    if (createTeacherDto.gender) {
      teacherData.gender = createTeacherDto.gender;
    }

    if (createTeacherDto.birthDate) {
      teacherData.birthDate = new Date(createTeacherDto.birthDate);
    }

    if (createTeacherDto.hireDate) {
      teacherData.hireDate = new Date(createTeacherDto.hireDate);
    }

    if (createTeacherDto.subject) {
      teacherData.subject = createTeacherDto.subject;
    }

    if (createTeacherDto.title) {
      teacherData.title = createTeacherDto.title;
    }

    if (createTeacherDto.description) {
      teacherData.description = createTeacherDto.description;
    }

    if (creatorId) {
      teacherData.creator = creatorId;
    }

    // 使用事务创建 User 和 Teacher
    return this.prisma.$transaction(async (tx) => {
      const user = await tx.user.create({
        data: userData,
      });

      const teacher = await tx.teacher.create({
        data: {
          ...teacherData,
          userId: user.id,
        },
        include: {
          user: true,
          department: true,
        },
      });

      return teacher;
    });
  }

  async findAll(
    page: number = 1,
    pageSize: number = 10,
    tenantId?: number,
    departmentId?: number,
    nickname?: string,
    username?: string,
  ) {
    const skip = (page - 1) * pageSize;
    const where: any = { validState: 1 };

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

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

    // 支持通过用户昵称和用户名搜索
    if (nickname || username) {
      where.user = {};
      if (nickname) {
        where.user.nickname = { contains: nickname };
      }
      if (username) {
        where.user.username = { contains: username };
      }
    }

    const [list, total] = await Promise.all([
      this.prisma.teacher.findMany({
        where,
        skip,
        take: pageSize,
        orderBy: {
          createTime: 'desc',
        },
        include: {
          user: true,
          department: true,
        },
      }),
      this.prisma.teacher.count({ where }),
    ]);

    return {
      list,
      total,
      page,
      pageSize,
    };
  }

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

    const teacher = await this.prisma.teacher.findFirst({
      where,
      include: {
        user: true,
        department: true,
      },
    });

    if (!teacher) {
      throw new NotFoundException('教师不存在');
    }

    return teacher;
  }

  async findByUserId(userId: number, tenantId?: number) {
    const where: any = { userId, validState: 1 };
    if (tenantId) {
      where.tenantId = tenantId;
    }

    const teacher = await this.prisma.teacher.findFirst({
      where,
      include: {
        user: true,
        department: true,
      },
    });

    if (!teacher) {
      throw new NotFoundException('教师不存在');
    }

    return teacher;
  }

  async update(
    id: number,
    updateTeacherDto: UpdateTeacherDto,
    tenantId?: number,
    modifierId?: number,
  ) {
    // 验证教师是否存在
    const existingTeacher = await this.findOne(id, tenantId);

    // 如果更新部门，验证部门是否存在
    if (
      updateTeacherDto.departmentId &&
      updateTeacherDto.departmentId !== existingTeacher.departmentId
    ) {
      const department = await this.prisma.department.findFirst({
        where: {
          id: updateTeacherDto.departmentId,
          tenantId: tenantId || existingTeacher.tenantId,
          validState: 1,
        },
      });

      if (!department) {
        throw new NotFoundException('部门不存在或不属于该租户');
      }
    }

    // 如果更新工号，检查是否冲突
    if (
      updateTeacherDto.employeeNo &&
      updateTeacherDto.employeeNo !== existingTeacher.employeeNo
    ) {
      const existingByEmployeeNo = await this.prisma.teacher.findFirst({
        where: {
          tenantId: tenantId || existingTeacher.tenantId,
          employeeNo: updateTeacherDto.employeeNo,
          id: { not: id },
        },
      });

      if (existingByEmployeeNo) {
        throw new ConflictException('工号已存在');
      }
    }

    // 更新 Teacher 记录
    const teacherData: any = {};

    if (updateTeacherDto.departmentId !== undefined) {
      teacherData.departmentId = updateTeacherDto.departmentId;
    }

    if (updateTeacherDto.employeeNo !== undefined) {
      teacherData.employeeNo = updateTeacherDto.employeeNo;
    }

    if (updateTeacherDto.phone !== undefined) {
      teacherData.phone = updateTeacherDto.phone;
    }

    if (updateTeacherDto.idCard !== undefined) {
      teacherData.idCard = updateTeacherDto.idCard;
    }

    if (updateTeacherDto.gender !== undefined) {
      teacherData.gender = updateTeacherDto.gender;
    }

    if (updateTeacherDto.birthDate !== undefined) {
      teacherData.birthDate = new Date(updateTeacherDto.birthDate);
    }

    if (updateTeacherDto.hireDate !== undefined) {
      teacherData.hireDate = new Date(updateTeacherDto.hireDate);
    }

    if (updateTeacherDto.subject !== undefined) {
      teacherData.subject = updateTeacherDto.subject;
    }

    if (updateTeacherDto.title !== undefined) {
      teacherData.title = updateTeacherDto.title;
    }

    if (updateTeacherDto.description !== undefined) {
      teacherData.description = updateTeacherDto.description;
    }

    if (updateTeacherDto.validState !== undefined) {
      teacherData.validState = updateTeacherDto.validState;
    }

    if (modifierId) {
      teacherData.modifier = modifierId;
    }

    // 更新 User 记录
    const userData: any = {};

    if (updateTeacherDto.nickname !== undefined) {
      userData.nickname = updateTeacherDto.nickname;
    }

    if (updateTeacherDto.email !== undefined) {
      userData.email = updateTeacherDto.email;
    }

    if (updateTeacherDto.avatar !== undefined) {
      userData.avatar = updateTeacherDto.avatar;
    }

    if (updateTeacherDto.validState !== undefined) {
      userData.validState = updateTeacherDto.validState;
    }

    if (modifierId) {
      userData.modifier = modifierId;
    }

    // 使用事务更新 User 和 Teacher
    return this.prisma.$transaction(async (tx) => {
      if (Object.keys(userData).length > 0) {
        await tx.user.update({
          where: { id: existingTeacher.userId },
          data: userData,
        });
      }

      const teacher = await tx.teacher.update({
        where: { id },
        data: teacherData,
        include: {
          user: true,
          department: true,
        },
      });

      return teacher;
    });
  }

  async remove(id: number, tenantId?: number) {
    // 验证教师是否存在
    const teacher = await this.findOne(id, tenantId);

    // 删除教师会级联删除 User（通过 Prisma schema 的 onDelete: Cascade）
    return this.prisma.teacher.delete({
      where: { id },
    });
  }
}
