import {
  Injectable,
  NotFoundException,
  BadRequestException,
} from '@nestjs/common';
import { PrismaService } from '../prisma/prisma.service';
import { CreateJudgeDto } from './dto/create-judge.dto';
import { UpdateJudgeDto } from './dto/update-judge.dto';
import { QueryJudgeDto } from './dto/query-judge.dto';
import * as bcrypt from 'bcrypt';

const JUDGE_ROLE_CODE = 'judge';

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

  /**
   * 获取超级租户ID（评委统一存储在超级租户下）
   */
  private async getSuperTenantId(): Promise<number> {
    const superTenant = await this.prisma.tenant.findFirst({
      where: {
        isSuper: 1,
        validState: 1,
      },
    });

    if (!superTenant) {
      throw new BadRequestException('系统未配置超级租户');
    }

    return superTenant.id;
  }

  /**
   * 确保评委角色存在，如果不存在则创建
   */
  private async ensureJudgeRole(tenantId: number): Promise<number> {
    let role = await this.prisma.role.findFirst({
      where: {
        code: JUDGE_ROLE_CODE,
        tenantId,
      },
    });

    if (!role) {
      role = await this.prisma.role.create({
        data: {
          tenantId,
          name: '评委',
          code: JUDGE_ROLE_CODE,
          description: '活动评委角色',
        },
      });
    }

    return role.id;
  }

  /**
   * 创建评委
   */
  async create(createJudgeDto: CreateJudgeDto, creatorId?: number) {
    const { organization, password, ...userData } = createJudgeDto;

    // 评委统一存储在超级租户下
    const superTenantId = await this.getSuperTenantId();

    // 确保评委角色存在
    const judgeRoleId = await this.ensureJudgeRole(superTenantId);

    // 生成用户名（如果没有提供）
    let username = createJudgeDto.username;
    if (!username) {
      // 使用手机号作为默认用户名
      username = createJudgeDto.phone;
    }

    // 检查用户名是否已存在（在超级租户下）
    const existingUser = await this.prisma.user.findFirst({
      where: {
        username,
        tenantId: superTenantId,
      },
    });

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

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

    // 创建用户并分配评委角色
    const user = await this.prisma.user.create({
      data: {
        ...userData,
        username,
        tenantId: superTenantId,
        organization, // 使用独立的所属单位字段
        password: hashedPassword,
        status: createJudgeDto.status || 'enabled',
        creator: creatorId,
        roles: {
          create: {
            roleId: judgeRoleId,
          },
        },
      },
      include: {
        roles: {
          include: {
            role: true,
          },
        },
      },
    });

    return user;
  }

  /**
   * 查询评委列表
   */
  async findAll(queryDto: QueryJudgeDto) {
    const { page = 1, pageSize = 10, organization, nickname, username, status } = queryDto;
    const skip = (page - 1) * pageSize;

    // 构建查询条件：必须有评委角色
    const where: any = {
      validState: 1,
      roles: {
        some: {
          role: {
            code: JUDGE_ROLE_CODE,
          },
        },
      },
    };

    if (organization) {
      where.organization = {
        contains: organization,
      };
    }

    if (nickname) {
      where.nickname = {
        contains: nickname,
      };
    }

    if (username) {
      where.username = {
        contains: username,
      };
    }

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

    const [list, total] = await Promise.all([
      this.prisma.user.findMany({
        where,
        skip,
        take: pageSize,
        include: {
          roles: {
            include: {
              role: true,
            },
          },
          // 获取关联的进行中活动
          contestJudges: {
            where: {
              validState: 1,
              contest: {
                validState: 1,
                status: 'ongoing',
              },
            },
            include: {
              contest: {
                select: {
                  id: true,
                  contestName: true,
                  status: true,
                },
              },
            },
          },
        },
        orderBy: { createTime: 'desc' },
      }),
      this.prisma.user.count({ where }),
    ]);

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

  /**
   * 获取评委详情
   */
  async findOne(id: number) {
    const user = await this.prisma.user.findFirst({
      where: {
        id,
        validState: 1,
        roles: {
          some: {
            role: {
              code: JUDGE_ROLE_CODE,
            },
          },
        },
      },
      include: {
        roles: {
          include: {
            role: true,
          },
        },
        contestJudges: {
          where: {
            validState: 1,
          },
          include: {
            contest: {
              select: {
                id: true,
                contestName: true,
                status: true,
                contestState: true,
              },
            },
          },
        },
      },
    });

    if (!user) {
      throw new NotFoundException('评委不存在');
    }

    return user;
  }

  /**
   * 更新评委信息
   */
  async update(id: number, updateJudgeDto: UpdateJudgeDto, modifierId?: number) {
    // 验证评委存在
    await this.findOne(id);

    const data: any = { ...updateJudgeDto };

    // 如果更新密码，需要加密
    if (updateJudgeDto.password) {
      data.password = await bcrypt.hash(updateJudgeDto.password, 10);
    }

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

    return this.prisma.user.update({
      where: { id },
      data,
      include: {
        roles: {
          include: {
            role: true,
          },
        },
      },
    });
  }

  /**
   * 删除评委（软删除）
   */
  async remove(id: number) {
    // 验证评委存在
    const judge = await this.findOne(id);

    // 检查是否有关联的进行中活动
    const ongoingContests = await this.prisma.contestJudge.count({
      where: {
        judgeId: id,
        validState: 1,
        contest: {
          validState: 1,
          status: 'ongoing',
        },
      },
    });

    if (ongoingContests > 0) {
      throw new BadRequestException('该评委正在参与进行中的活动，无法删除');
    }

    return this.prisma.user.update({
      where: { id },
      data: {
        validState: 2,
      },
    });
  }

  /**
   * 冻结/解冻评委
   */
  async toggleStatus(id: number, status: 'enabled' | 'disabled') {
    // 验证评委存在
    await this.findOne(id);

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

  /**
   * 批量删除评委
   */
  async batchRemove(ids: number[]) {
    // 检查是否有评委正在参与进行中的活动
    const judgesWithOngoingContests = await this.prisma.contestJudge.findMany({
      where: {
        judgeId: { in: ids },
        validState: 1,
        contest: {
          validState: 1,
          status: 'ongoing',
        },
      },
      select: {
        judgeId: true,
      },
    });

    if (judgesWithOngoingContests.length > 0) {
      throw new BadRequestException('部分评委正在参与进行中的活动，无法删除');
    }

    return this.prisma.user.updateMany({
      where: {
        id: { in: ids },
        validState: 1,
        roles: {
          some: {
            role: {
              code: JUDGE_ROLE_CODE,
            },
          },
        },
      },
      data: {
        validState: 2,
      },
    });
  }
}
