import datetime
from src import logger
from dataclasses import dataclass


@dataclass
class Semester:
    logger.debug("Semester class loaded")

    _year: int | None = str(datetime.datetime.now().year)[2:]
    _semester: str | None = None
    _month: int | None = datetime.datetime.now().month
    value: str = None
    logger.debug(
        f"Initialized Semester class with values: month: {_month}, semester: {_semester}, year {_year}"
    )
    def __post_init__(self):
        if isinstance(self._year, str):
            self._year = int(self._year)
        if self._year is None:
            self._year = datetime.datetime.now().year[2:]
        if self._month is None:
            self._month = datetime.datetime.now().month
        if self._semester is None:
            self.generateSemester()
        self.computeValue()

    def __str__(self):
        return self.value

    def generateSemester(self):
        if self._month <= 3 or self._month > 9:
            self._semester = "WiSe"
        else:
            self._semester = "SoSe"

    @logger.catch
    def computeValue(self):
        # year is only last two digits
        year = self._year
        valueyear = str(year)
        if self._semester == "WiSe":
            if self._month < 4:
                valueyear = str(year - 1) + "/" + str(year)
            else:
                valueyear = str(year) + "/" + str(year + 1)
        self.value = f"{self._semester} {valueyear}"

    @logger.catch
    def offset(self, value: int) -> str:
        """Generate a new Semester object by offsetting the current semester by a given value

        Args:
            value (int): The value by which the semester should be offset

        Returns:
            str: the new semester value
        """
        assert isinstance(value, int), "Value must be an integer"
        if value == 0:
            return self
        if value > 0:
            if value % 2 == 0:
                return Semester(
                    self._year - value // 2, self._semester - value // 2 + 1
                )
            else:
                semester = self._semester
                semester = "SoSe" if semester == "WiSe" else "WiSe"
                return Semester(self._year + value // 2, semester)
        else:
            if value % 2 == 0:
                return Semester(self.year + value // 2, self._semester)
            else:
                semester = self._semester
                semester = "SoSe" if semester == "WiSe" else "WiSe"
                return Semester(self._year + value // 2, semester)

    def isPastSemester(self, semester) -> bool:
        """Checks if the current Semester is a past Semester compared to the given Semester

        Args:
            semester (str): The semester to compare to

        Returns:
            bool: True if the current semester is in the past, False otherwise
        """
        if self.year < semester.year:
            return True
        if self.year == semester.year:
            if self.semester == "WiSe" and semester.semester == "SoSe":
                return True
        return False

    def isFutureSemester(self, semester: "Semester") -> bool:
        """Checks if the current Semester is a future Semester compared to the given Semester

        Args:
            semester (str): The semester to compare to

        Returns:
            bool: True if the current semester is in the future, False otherwise
        """
        if self.year > semester.year:
            return True
        if self.year == semester.year:
            if self.semester == "SoSe" and semester.semester == "WiSe":
                return True
        return False

    def from_string(self, val):
        self.value = val
        self._year = int(val[-2:])
        self._semester = val[:4]
        return self

    @property
    def next(self):
        return self.offset(1)

    @property
    def previous(self):
        return self.offset(-1)

    @property
    def year(self):
        return self._year

    @property
    def semester(self):
        return self._semester
