import {
  Injectable,
  NotFoundException,
  ForbiddenException,
} from '@nestjs/common';
import { PrismaService } from '../../prisma/prisma.service';
import { CreatePresetCommentDto } from './dto/create-preset-comment.dto';
import { UpdatePresetCommentDto } from './dto/update-preset-comment.dto';
import { SyncPresetCommentsDto } from './dto/sync-preset-comments.dto';

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

  async create(
    createDto: CreatePresetCommentDto,
    judgeId: number,
    creatorId?: number,
  ) {
    // 验证活动是否存在
    const contest = await this.prisma.contest.findUnique({
      where: { id: createDto.contestId },
    });

    if (!contest) {
      throw new NotFoundException('活动不存在');
    }

    // 验证用户是否是该活动的评委
    const isJudge = await this.prisma.contestJudge.findFirst({
      where: {
        contestId: createDto.contestId,
        judgeId,
        validState: 1,
      },
    });

    if (!isJudge) {
      throw new ForbiddenException('您不是该活动的评委');
    }

    return this.prisma.presetComment.create({
      data: {
        contestId: createDto.contestId,
        judgeId,
        content: createDto.content,
        score: createDto.score,
        sortOrder: createDto.sortOrder ?? 0,
        creator: creatorId,
      },
    });
  }

  async findAll(contestId: number, judgeId: number) {
    return this.prisma.presetComment.findMany({
      where: {
        contestId,
        judgeId,
        validState: 1,
      },
      orderBy: [{ sortOrder: 'asc' }, { createTime: 'desc' }],
    });
  }

  async findOne(id: number, judgeId: number) {
    const comment = await this.prisma.presetComment.findFirst({
      where: {
        id,
        judgeId,
        validState: 1,
      },
    });

    if (!comment) {
      throw new NotFoundException('预设评语不存在');
    }

    return comment;
  }

  async update(
    id: number,
    updateDto: UpdatePresetCommentDto,
    judgeId: number,
    modifierId?: number,
  ) {
    await this.findOne(id, judgeId);

    return this.prisma.presetComment.update({
      where: { id },
      data: {
        ...updateDto,
        modifier: modifierId,
      },
    });
  }

  async remove(id: number, judgeId: number) {
    await this.findOne(id, judgeId);

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

  async batchDelete(ids: number[], judgeId: number) {
    // 验证所有评语都属于该评委
    const comments = await this.prisma.presetComment.findMany({
      where: {
        id: { in: ids },
        judgeId,
        validState: 1,
      },
    });

    if (comments.length !== ids.length) {
      throw new ForbiddenException('部分评语不存在或无权操作');
    }

    return this.prisma.presetComment.updateMany({
      where: {
        id: { in: ids },
        judgeId,
      },
      data: {
        validState: 2,
      },
    });
  }

  async sync(syncDto: SyncPresetCommentsDto, judgeId: number, creatorId?: number) {
    // 获取源活动的评语
    const sourceComments = await this.prisma.presetComment.findMany({
      where: {
        contestId: syncDto.sourceContestId,
        judgeId,
        validState: 1,
      },
    });

    if (sourceComments.length === 0) {
      throw new NotFoundException('源活动没有预设评语');
    }

    // 验证目标活动存在且当前用户是评委
    for (const targetContestId of syncDto.targetContestIds) {
      const contest = await this.prisma.contest.findUnique({
        where: { id: targetContestId },
      });

      if (!contest) {
        throw new NotFoundException(`活动 ${targetContestId} 不存在`);
      }

      const isJudge = await this.prisma.contestJudge.findFirst({
        where: {
          contestId: targetContestId,
          judgeId,
          validState: 1,
        },
      });

      if (!isJudge) {
        throw new ForbiddenException(`您不是活动 ${contest.contestName} 的评委`);
      }
    }

    // 为每个目标活动创建评语副本
    const results = [];
    for (const targetContestId of syncDto.targetContestIds) {
      for (const comment of sourceComments) {
        const created = await this.prisma.presetComment.create({
          data: {
            contestId: targetContestId,
            judgeId,
            content: comment.content,
            score: comment.score,
            sortOrder: comment.sortOrder,
            creator: creatorId,
          },
        });
        results.push(created);
      }
    }

    return {
      message: '同步成功',
      count: results.length,
    };
  }

  async getJudgeContests(judgeId: number) {
    const contestJudges = await this.prisma.contestJudge.findMany({
      where: {
        judgeId,
        validState: 1,
        contest: {
          validState: 1,
        },
      },
      include: {
        contest: {
          select: {
            id: true,
            contestName: true,
            contestState: true,
            status: true,
          },
        },
      },
      orderBy: {
        createTime: 'desc',
      },
    });

    return contestJudges.map((cj) => cj.contest);
  }

  async incrementUseCount(id: number, judgeId: number) {
    await this.findOne(id, judgeId);

    return this.prisma.presetComment.update({
      where: { id },
      data: {
        useCount: {
          increment: 1,
        },
      },
    });
  }
}
