"""
This module provides resources for getting projects from the 42 API.
"""

from __future__ import annotations

from datetime import datetime

from pydantic import Field, field_validator

from fortytwo.resources.campus.campus import Campus
from fortytwo.resources.cursus.cursus import Cursus
from fortytwo.resources.model import Model


class ProjectReference(Model):
    """
    Lightweight representation of a project reference (used in parent/children).
    """

    id: int = Field(
        description="The unique identifier of the project.",
    )
    name: str = Field(
        description="The name of the project.",
    )
    slug: str = Field(
        description="The URL-friendly slug of the project.",
    )

    def __repr__(self) -> str:
        return f"<ProjectReference {self.name}>"

    def __str__(self) -> str:
        return self.name


class Project(Model):
    """
    This class provides a representation of a 42 project.
    """

    id: int = Field(
        description="The unique identifier of the project.",
    )
    name: str = Field(
        description="The name of the project.",
    )
    slug: str = Field(
        description="The URL-friendly slug of the project.",
    )
    difficulty: int = Field(
        default=0,
        description="The difficulty level of the project.",
    )

    @field_validator("difficulty", mode="before")
    @classmethod
    def _difficulty_none_to_zero(cls, difficulty: int | None) -> int:
        return difficulty if difficulty is not None else 0

    created_at: datetime = Field(
        description="The date and time the project was created.",
    )
    updated_at: datetime = Field(
        description="The date and time the project was last updated.",
    )
    exam: bool = Field(
        description="Whether the project is an exam.",
    )
    parent: ProjectReference | None = Field(
        default=None,
        description="The parent project reference.",
    )
    children: list[ProjectReference] = Field(
        default=[],
        description="The child project references.",
    )
    cursus: list[Cursus] = Field(
        default=[],
        description="The cursus this project belongs to.",
    )
    campus: list[Campus] = Field(
        default=[],
        description="The campuses where this project is available.",
    )

    def __repr__(self) -> str:
        return f"<Project {self.name}>"

    def __str__(self) -> str:
        return self.name
