import { useCourseSessionDetailQuery } from "@/composables";
import { itGet } from "@/fetchHelpers";
import type {
  Assignment,
  AssignmentCompletion,
  CourseSessionUser,
  UserAssignmentCompletionStatus,
} from "@/types";
import { sum } from "d3";
import pick from "lodash/pick";

export interface GradedUser {
  user: CourseSessionUser;
  points: number;
  maxPoints: number;
  passed: boolean;
}

export async function loadAssignmentCompletionStatusData(
  assignmentId: string,
  courseSessionId: string,
  learningContentId: string
) {
  const courseSessionDetailResult = useCourseSessionDetailQuery();

  const assignmentCompletionData = (await itGet(
    `/api/assignment/${assignmentId}/${courseSessionId}/status/`
  )) as UserAssignmentCompletionStatus[];

  const members = courseSessionDetailResult.filterMembers();

  const gradedUsers: GradedUser[] = [];
  const assignmentSubmittedUsers: CourseSessionUser[] = [];
  for (const csu of members) {
    const userAssignmentStatus = assignmentCompletionData.find(
      (s) =>
        s.assignment_user_id === csu.user_id &&
        s.learning_content_page_id === learningContentId
    );
    if (
      userAssignmentStatus?.completion_status === "SUBMITTED" ||
      userAssignmentStatus?.completion_status === "EVALUATION_IN_PROGRESS" ||
      userAssignmentStatus?.completion_status === "EVALUATION_SUBMITTED"
    ) {
      assignmentSubmittedUsers.push(csu);
    }
    if (userAssignmentStatus?.completion_status === "EVALUATION_SUBMITTED") {
      gradedUsers.push({
        user: csu,
        points: userAssignmentStatus.evaluation_points ?? 0,
        maxPoints: userAssignmentStatus.evaluation_max_points ?? 0,
        passed: userAssignmentStatus.evaluation_passed ?? false,
      });
    }
  }
  return {
    assignmentSubmittedUsers: assignmentSubmittedUsers,
    gradedUsers: gradedUsers,
    total: members.length,
  };
}

export function maxAssignmentPoints(assignment: Assignment) {
  return sum(assignment.evaluation_tasks.map((task) => task.value.max_points));
}

export function userAssignmentPoints(
  assignment: Assignment,
  assignmentCompletion: AssignmentCompletion
) {
  const evaluationTaskIds = assignment.evaluation_tasks.map((task) => {
    return task.id;
  });

  return sum(
    // transform the object of { [expert_id]: { expert_data: { points } } } to an array
    // of [ [expert_id, { expert_data: { points } }], ... ] so that we can easily sum
    // the points of the user
    Object.entries(pick(assignmentCompletion.completion_data, evaluationTaskIds)).map(
      (entry) => {
        return entry[1]?.expert_data?.points ?? 0;
      }
    )
  );
}

export function pointsToGrade(points: number, maxPoints: number) {
  // round to half-grades
  const grade = Math.round((points / maxPoints) * 10);
  const halfGrade = grade / 2;
  return Math.min(halfGrade, 5) + 1;
}
