from src.domain.grade import Grade
from src.errors.errors import *
import json

class GradesRepo:
    def __init__(self,path) -> None:
        self.__path = path
        self.grades = []
        self.__load_from_file()
    
    def __load_from_file(self) -> None:
        with open(self.__path,"r") as f:
            grades = json.load(f)
            for grade in grades:
                self.grades.append(Grade(grade["assignment_id"],grade["student_id"],grade["grade_value"]))
    
    def __save_to_file(self) -> None:
        grades = []
        for grade in self.grades:
            grades.append(grade.toJson())
        with open(self.__path,"w") as f:
            json.dump(grades,f,indent=4)
    
    def add_grade(self, grade: Grade) -> None:
        for grade_in_list in self.grades:
            if grade_in_list.get_student_id() == grade.get_student_id() and grade_in_list.get_assignment_id() == grade.get_assignment_id():
                raise GradeAlreadyExistsError("Grade already exists")
        self.grades.append(grade)
        self.__save_to_file()
    
    def remove_grade(self, student_id: int, assignment_id: str) -> None:
        for grade in self.grades:
            if grade.get_student_id() == student_id and grade.get_assignment_id() == assignment_id:
                self.grades.remove(grade)
                self.__save_to_file()
                return
        raise GradeNotFoundError("Grade not found")
    
    def update_grade(self, grade: Grade) -> None:
        for grade_in_list in self.grades:
            if grade_in_list.get_student_id() == grade.get_student_id() and grade_in_list.get_assignment_id() == grade.get_assignment_id():
                if grade.get_grade_value() != None:
                    grade_in_list.set_grade_value(grade.get_grade_value())
                    self.__save_to_file()
                    return
                else:
                    raise GradeValueAlreadySetError("Grade value already set")
        raise GradeNotFoundError("Grade not found")
    
    def list_grades(self) -> list[Grade]:
        return self.grades
    
    def is_a_grade(self, student_id: int, assignment_id: str) -> bool:
        for grade in self.grades:
            if grade.get_student_id() == student_id and grade.get_assignment_id() == assignment_id:
                return True
        return False