"""
Learning Node Models
Pydantic models for educational content nodes
"""
from enum import Enum
from typing import Optional
from pydantic import BaseModel, Field


class LearningTheme(str, Enum):
    """Available learning themes for geographic education."""
    TOPOGRAPHIE = "topographie"
    LANDNUTZUNG = "landnutzung"
    ORIENTIERUNG = "orientierung"
    GEOLOGIE = "geologie"
    HYDROLOGIE = "hydrologie"
    VEGETATION = "vegetation"


class NodeType(str, Enum):
    """Type of learning node interaction."""
    QUESTION = "question"  # Multiple choice or open question
    OBSERVATION = "observation"  # Guided observation task
    EXPLORATION = "exploration"  # Free exploration with hints


class Position(BaseModel):
    """Geographic position for a learning node."""
    latitude: float = Field(..., ge=-90, le=90, description="Latitude in degrees")
    longitude: float = Field(..., ge=-180, le=180, description="Longitude in degrees")
    altitude: Optional[float] = Field(None, description="Altitude in meters")


class LearningNode(BaseModel):
    """
    A learning node (station) within a geographic area.

    Contains educational content tied to a specific location,
    including questions, hints, and explanations.
    """
    id: str = Field(..., description="Unique node identifier")
    aoi_id: str = Field(..., description="Parent AOI identifier")
    title: str = Field(..., min_length=1, max_length=100, description="Node title")
    theme: LearningTheme = Field(..., description="Learning theme")
    position: dict = Field(..., description="Geographic position")
    question: str = Field(..., description="Learning question or task")
    hints: list[str] = Field(default_factory=list, description="Progressive hints")
    answer: str = Field(..., description="Correct answer or expected observation")
    explanation: str = Field(..., description="Didactic explanation")
    node_type: NodeType = Field(NodeType.QUESTION, description="Interaction type")
    points: int = Field(10, ge=1, le=100, description="Points awarded for completion")
    approved: bool = Field(False, description="Teacher-approved for student use")
    media: Optional[list[dict]] = Field(None, description="Associated media files")
    tags: Optional[list[str]] = Field(None, description="Content tags")
    difficulty: Optional[str] = Field(None, description="Difficulty level")
    grade_level: Optional[str] = Field(None, description="Target grade level")

    class Config:
        json_schema_extra = {
            "example": {
                "id": "node-001",
                "aoi_id": "550e8400-e29b-41d4-a716-446655440000",
                "title": "Höhenbestimmung",
                "theme": "topographie",
                "position": {"latitude": 47.7085, "longitude": 9.1925},
                "question": "Schätze die Höhe dieses Punktes über dem Meeresspiegel.",
                "hints": [
                    "Schau dir die Vegetation an.",
                    "Vergleiche mit dem Seespiegel des Bodensees (395m).",
                ],
                "answer": "Ca. 430 Meter über NN",
                "explanation": "Die Höhe lässt sich aus der Vegetation und der relativen Position zum Bodensee abschätzen.",
                "node_type": "question",
                "points": 10,
                "approved": True,
            }
        }


class LearningNodeRequest(BaseModel):
    """Request model for creating a learning node manually."""
    title: str = Field(..., min_length=1, max_length=100)
    theme: LearningTheme
    position: Position
    question: str
    hints: list[str] = Field(default_factory=list)
    answer: str
    explanation: str
    node_type: NodeType = NodeType.QUESTION
    points: int = Field(10, ge=1, le=100)
    tags: Optional[list[str]] = None
    difficulty: Optional[str] = Field(None, pattern="^(leicht|mittel|schwer)$")
    grade_level: Optional[str] = None


class LearningNodeBatch(BaseModel):
    """Batch of learning nodes for bulk operations."""
    nodes: list[LearningNode]
    total_points: int = 0

    def calculate_total_points(self) -> int:
        """Calculate total points from all nodes."""
        self.total_points = sum(node.points for node in self.nodes)
        return self.total_points


class LearningProgress(BaseModel):
    """Student progress through learning nodes."""
    student_id: str
    aoi_id: str
    completed_nodes: list[str] = Field(default_factory=list)
    total_points: int = 0
    started_at: Optional[str] = None
    completed_at: Optional[str] = None

    @property
    def completion_percentage(self) -> float:
        """Calculate completion percentage."""
        # Would need total node count for accurate calculation
        return len(self.completed_nodes) * 10  # Placeholder
