"""
Origin data models - character backstory and starting conditions.

Origins are saved to the character and referenced by the AI DM throughout
the game to create personalized narrative experiences, quest hooks, and
story-driven interactions.
"""

from dataclasses import dataclass, field
from typing import Dict, List, Any


@dataclass
class StartingLocation:
    """
    Represents where a character begins their journey.

    Attributes:
        id: Unique location identifier
        name: Display name of the location
        region: Larger geographical area this location belongs to
        description: Brief description of the location
    """
    id: str
    name: str
    region: str
    description: str

    def to_dict(self) -> Dict[str, Any]:
        """Serialize to dictionary."""
        return {
            "id": self.id,
            "name": self.name,
            "region": self.region,
            "description": self.description,
        }

    @classmethod
    def from_dict(cls, data: Dict[str, Any]) -> 'StartingLocation':
        """Deserialize from dictionary."""
        return cls(
            id=data["id"],
            name=data["name"],
            region=data["region"],
            description=data["description"],
        )


@dataclass
class StartingBonus:
    """
    Represents mechanical benefits from an origin choice.

    Attributes:
        trait: Name of the trait/ability granted
        description: What the trait represents narratively
        effect: Mechanical game effect (stat bonuses, special abilities, etc.)
    """
    trait: str
    description: str
    effect: str

    def to_dict(self) -> Dict[str, Any]:
        """Serialize to dictionary."""
        return {
            "trait": self.trait,
            "description": self.description,
            "effect": self.effect,
        }

    @classmethod
    def from_dict(cls, data: Dict[str, Any]) -> 'StartingBonus':
        """Deserialize from dictionary."""
        return cls(
            trait=data["trait"],
            description=data["description"],
            effect=data["effect"],
        )


@dataclass
class Origin:
    """
    Represents a character's backstory and starting conditions.

    Origins are permanent character attributes that the AI DM uses to
    create personalized narratives, generate relevant quest hooks, and
    tailor NPC interactions throughout the game.

    Attributes:
        id: Unique origin identifier (e.g., "soul_revenant")
        name: Display name (e.g., "Soul Revenant")
        description: Full backstory text that explains the origin
        starting_location: Where the character begins their journey
        narrative_hooks: List of story elements the AI can reference
        starting_bonus: Mechanical benefits from this origin
    """
    id: str
    name: str
    description: str
    starting_location: StartingLocation
    narrative_hooks: List[str] = field(default_factory=list)
    starting_bonus: StartingBonus = None

    def to_dict(self) -> Dict[str, Any]:
        """
        Serialize origin to dictionary for JSON storage.

        Returns:
            Dictionary containing all origin data
        """
        return {
            "id": self.id,
            "name": self.name,
            "description": self.description,
            "starting_location": self.starting_location.to_dict(),
            "narrative_hooks": self.narrative_hooks,
            "starting_bonus": self.starting_bonus.to_dict() if self.starting_bonus else None,
        }

    @classmethod
    def from_dict(cls, data: Dict[str, Any]) -> 'Origin':
        """
        Deserialize origin from dictionary.

        Args:
            data: Dictionary containing origin data

        Returns:
            Origin instance
        """
        starting_location = StartingLocation.from_dict(data["starting_location"])
        starting_bonus = None
        if data.get("starting_bonus"):
            starting_bonus = StartingBonus.from_dict(data["starting_bonus"])

        return cls(
            id=data["id"],
            name=data["name"],
            description=data["description"],
            starting_location=starting_location,
            narrative_hooks=data.get("narrative_hooks", []),
            starting_bonus=starting_bonus,
        )

    def __repr__(self) -> str:
        """String representation of the origin."""
        return f"Origin({self.name}, starts at {self.starting_location.name})"
