from django.db.models import Count, Q

from account.decorators import super_admin_required, teacher_admin_required
from account.models import AdminType, User
from judge.tasks import judge_task
from problem.models import Problem
from utils.api import APIView

from ..models import JudgeStatus, Submission


def get_real_name(username, class_name):
    if class_name and username.startswith("ks"):
        return username[len(f"ks{class_name}") :]
    return username


class SubmissionRejudgeAPI(APIView):
    @super_admin_required
    def get(self, request):
        id = request.GET.get("id")
        if not id:
            return self.error("Parameter error, id is required")
        try:
            submission = Submission.objects.select_related("problem").get(id=id, contest_id__isnull=True)
        except Submission.DoesNotExist:
            return self.error("Submission does not exists")
        submission.statistic_info = {}
        submission.save()

        judge_task.send(submission.id, submission.problem.id)
        return self.success()


class SubmissionStatisticsAPI(APIView):
    @teacher_admin_required
    def get(self, request):
        start = request.GET.get("start")
        end = request.GET.get("end")

        if not end:
            return self.error("end is required")

        filters = {"contest_id__isnull": True, "create_time__lte": end}
        if start:
            filters["create_time__gte"] = start
        submissions = Submission.objects.filter(**filters).select_related("problem__created_by")

        problem_id = request.GET.get("problem_id")

        if problem_id:
            try:
                problem = Problem.objects.get(_id__iexact=problem_id, contest_id__isnull=True, visible=True)
            except Problem.DoesNotExist:
                return self.error("Problem doesn't exist")
            submissions = submissions.filter(problem=problem)

        username = request.GET.get("username")

        all_users_dict = {}
        if username:
            submissions = submissions.filter(username__icontains=username)
            all_users_dict = {
                user["username"]: user["class_name"]
                for user in User.objects.filter(
                    username__icontains=username,
                    is_disabled=False,
                    admin_type=AdminType.REGULAR_USER,
                ).values("username", "class_name")
            }

        # 优化：一次性获取所有统计数据
        submission_stats = submissions.aggregate(
            total_count=Count("id"),
            accepted_count=Count("id", filter=Q(result__in=[JudgeStatus.ACCEPTED, JudgeStatus.AST_CHECK_FAILED])),
        )
        submission_count = submission_stats["total_count"]
        accepted_count = submission_stats["accepted_count"]
        correct_rate = round(accepted_count / submission_count * 100, 2) if submission_count else 0

        # 优化：获取用户提交统计
        user_submissions = (
            submissions.values("username")
            .annotate(
                submission_count=Count("id"),
                accepted_count=Count("id", filter=Q(result__in=[JudgeStatus.ACCEPTED, JudgeStatus.AST_CHECK_FAILED])),
            )
            .order_by("-submission_count")
        )

        # 获取所有有提交记录的用户的class_name信息
        submitted_usernames = {item["username"] for item in user_submissions}
        if submitted_usernames:
            submitted_users_dict = {user["username"]: user["class_name"] for user in User.objects.filter(username__in=submitted_usernames).values("username", "class_name")}
        else:
            submitted_users_dict = {}

        # 预先收集每个用户的提交ID和结果，按时间倒序
        submission_items_by_user = {}
        for submission in submissions.values("username", "id", "result").order_by("-create_time"):
            username_key = submission["username"]
            submission_id = str(submission["id"])
            submission_items_by_user.setdefault(username_key, []).append(
                {
                    "id": submission_id,
                    "result": submission["result"],
                }
            )

        # 处理有提交记录的用户
        accepted = []

        for item in user_submissions:
            username_key = item["username"]

            if item["accepted_count"] > 0:
                rate = round(item["accepted_count"] / item["submission_count"] * 100, 2)
                accepted.append(
                    {
                        "username": username_key,
                        "class_name": submitted_users_dict.get(username_key),
                        "submission_count": item["submission_count"],
                        "accepted_count": item["accepted_count"],
                        "correct_rate": f"{rate}%",
                        "submission_items": submission_items_by_user.get(username_key, []),
                    }
                )

        # 处理无提交记录的用户，只返回姓名列表
        unaccepted = []
        if all_users_dict:
            unaccepted_usernames = set(all_users_dict.keys()) - submitted_usernames
            for username in unaccepted_usernames:
                class_name = all_users_dict[username]
                real_name = get_real_name(username, class_name)
                unaccepted.append({"username": username, "real_name": real_name})

        # 计算人数完成率
        person_count = len(all_users_dict) if all_users_dict else 0
        person_rate = 0
        if person_count:
            person_rate = min(100, round(len(accepted) / person_count * 100, 2))
            # 处理已删除用户但提交记录仍存在的情况
            if person_count < len(accepted):
                person_count = len(accepted)

        return self.success(
            {
                "submission_count": submission_count,
                "accepted_count": accepted_count,
                "correct_rate": f"{correct_rate}%",
                "person_count": person_count,
                "person_rate": f"{person_rate}%",
                "data": accepted,
                "data_unaccepted": unaccepted,
            }
        )
