"""Data models for Anki notes and YAML serialization."""

from dataclasses import dataclass, field
from typing import Dict, Any, List, Optional
import re
from datetime import datetime
import yaml


@dataclass
class Note:
    """Represents an Anki note with all its fields and metadata."""

    id: int
    type: str  # Note type name
    deck: Optional[str] = None
    tags: List[str] = field(default_factory=list)
    fields: Dict[str, str] = field(default_factory=dict)  # field_name -> field_value

    def to_dict(self) -> Dict[str, Any]:
        """Convert note to dictionary representation."""
        return {
            "id": self.id,
            "type": self.type,
            "deck": self.deck,
            "tags": self.tags,
            "fields": self.fields,
        }

    @staticmethod
    def from_dict(data: Dict[str, Any]) -> "Note":
        """Create a Note from a dictionary representation."""
        # Handle datetime parsing
        created = data.get("created")
        if isinstance(created, str):
            created = datetime.fromisoformat(created)

        modified = data.get("modified")
        if isinstance(modified, str):
            modified = datetime.fromisoformat(modified)

        return Note(
            id=data["id"],
            type=data["type"],
            deck=data.get("deck"),
            tags=data.get("tags", []),
            fields=data.get("fields", {}),
        )

    def to_yaml(self) -> str:
        """Convert note to YAML string."""
        data = self.to_dict()
        return yaml.dump(data, default_flow_style=False, sort_keys=False)

    @staticmethod
    def from_yaml(yaml_str: str) -> "Note":
        """Load a Note from YAML string."""
        data = yaml.safe_load(yaml_str)
        return Note.from_dict(data)

    def get_summary(self) -> str:
        """Get a brief summary of the note for filename generation."""
        # Try to use front field if it exists, otherwise use first non-empty field
        if "Front" in self.fields:
            text = self.fields["Front"]
        else:
            text = next((v for v in self.fields.values() if v), "note")

        # Strip HTML tags to avoid filenames from markup text
        text = re.sub(r"<[^>]+>", " ", text)

        # Clean up and truncate
        text = text.replace("\n", " ")[:50].strip()
        return text or "note"
