from __future__ import annotations
from datetime import datetime, timedelta
from typing import List, Optional, Literal
from uuid import UUID, uuid4
from pydantic import BaseModel, Field, HttpUrl

class SourceMeta(BaseModel):
    type: Literal["blog","hn","reddit","youtube","podcast","news"]
    url: Optional[HttpUrl] = None
    title: Optional[str] = None
    author: Optional[str] = None
    outlet_or_subreddit: Optional[str] = None
    published_at: Optional[datetime] = None
    updated_at: Optional[datetime] = None
    engagement: dict = Field(default_factory=dict)
    credibility_score: float = 0.5

class AtomEvidence(BaseModel):
    source: SourceMeta
    span: Optional[str] = None
    url: Optional[HttpUrl] = None
    quote: Optional[str] = None
    confidence: float = 0.8

AtomType = Literal["definition","claim","example","step","qa","quote","figure","code","theorem","proof","pitfall","recipe"]

class SemanticAtom(BaseModel):
    id: UUID = Field(default_factory=uuid4)
    kind: AtomType
    title: Optional[str] = None
    text: str
    media: List[str] = Field(default_factory=list)
    evidence: List[AtomEvidence] = Field(default_factory=list)
    prerequisites: List[UUID] = Field(default_factory=list)
    est_duration: timedelta = Field(default=timedelta(seconds=15))
    bloom: Optional[Literal["remember","understand","apply","analyze","evaluate","create"]] = None
    topic_tags: List[str] = Field(default_factory=list)
    confidence: float = 0.8

class AtomGraph(BaseModel):
    atoms: List[SemanticAtom]

class GranularitySpec(BaseModel):
    target_duration: Optional[timedelta] = None
    max_tokens_per_atom: Optional[int] = 80
    atom_types: Optional[List[AtomType]] = None
    target_atom_count: Optional[int] = None
    bloom_target: Optional[List[str]] = None
    media_constraints: Optional[List[str]] = None
    preserve_dependencies: bool = True
    keep_citations: bool = True

class StructuredDoc(BaseModel):
    source: SourceMeta
    text: str
    sections: List[dict] = []
    extras: dict = {}
