import json
from datetime import date

from src.domain.assignment import Assignment
from src.errors.errors import *

class AssignmentsRepo:
    """
    Class that manages the assignments
    Reads and writes from a json file
    Attributes:
        __path: the path to the json file
        assignments: a list of assignments
    Methods:
        __load_from_file: loads the assignments from the json file
        __save_to_file: saves the assignments to the json file
        add_assignment: adds an assignment to the repository
        remove_assignment: removes an assignment from the repository
        update_assignment: updates an assignment from the repository
        list_assignments: returns a list of assignments
        get_assignment: returns an assignment
        is_an_assignment: returns True if the assignment is in the repository
    """
    def __init__(self, path: str) -> None:
        self.__path = path
        self.assignments = []
        self.__load_from_file()
    
    def __load_from_file(self) -> None:
        with open(self.__path, "r") as f:
            assignments = json.load(f)
            for assignment in assignments:
                self.assignments.append(Assignment(assignment["assignment_id"], assignment["description"], date(assignment["deadline"]["year"], assignment["deadline"]["month"], assignment["deadline"]["day"])))
    
    def __save_to_file(self) -> None:
        assignments = []
        for assignment in self.assignments:
            assignments.append(assignment.toJson())
        with open(self.__path, "w") as f:
            json.dump(assignments, f, indent=4)
    
    def add_assignment(self, assignment: Assignment) -> None:
        if assignment.get_assignment_id() in [assignment.get_assignment_id() for assignment in self.assignments]:
            raise AssignmentAlreadyExistsError("Assignment already exists")
        self.assignments.append(assignment)
        self.__save_to_file()
    
    def remove_assignment(self, assignment_id: str) -> None:
        for assignment in self.assignments:
            if assignment.get_assignment_id() == assignment_id:
                self.assignments.remove(assignment)
                self.__save_to_file()
                return
        raise AssignmentNotFoundError("Assignment not found")
    
    def update_assignment(self, assignment: Assignment) -> None:
        for assignment_in_list in self.assignments:
            if assignment_in_list.get_assignment_id() == assignment.get_assignment_id():
                assignment_in_list.set_description(assignment.get_description())
                assignment_in_list.set_deadline(assignment.get_deadline())
                self.__save_to_file()
                return
        raise AssignmentNotFoundError("Assignment not found")
    
    def list_assignments(self) -> list[Assignment]:
        return self.assignments
    
    def get_assignment(self, assignment_id: str) -> Assignment:
        for assignment in self.assignments:
            if assignment.get_assignment_id() == assignment_id:
                return assignment
        raise AssignmentNotFoundError("Assignment not found")
    
    def is_an_assignment(self, assignment_id: str) -> bool:
        for assignment in self.assignments:
            if assignment.get_assignment_id() == assignment_id:
                return True
        return False