"""Base source abstraction for mykb."""

from abc import ABC, abstractmethod
from dataclasses import dataclass, field
from typing import Iterator


@dataclass
class SourceItem:
    """Source 产出的统一中间格式，一个 item 对应一篇原始文档/条目。"""

    source_type: str  # "obsidian", "twitter", "telegram"
    source_id: str  # 源内唯一标识（文件相对路径 / tweet ID / message ID）
    source_uri: str  # 可打开的 URI（obsidian:// / https://x.com/... / tg://...）
    title: str
    content: str  # 纯文本或 Markdown
    category: str  # "note", "tweet", "message" 等
    tags: list[str] = field(default_factory=list)
    created_at: str | None = None
    modified_at: str | None = None
    metadata: dict = field(default_factory=dict)  # source 特有字段


class BaseSource(ABC):
    """数据源基类。"""

    # source type 标识，子类必须定义
    source_type: str

    def __init__(self, collection_name: str, config: dict):
        self.collection_name = collection_name
        self.config = config

    @abstractmethod
    def scan(self) -> Iterator[SourceItem]:
        """扫描数据源，yield 每个条目。"""

    @abstractmethod
    def content_hash(self, item: SourceItem) -> str:
        """返回内容哈希，用于增量检测。"""

    def item_state_key(self, item: SourceItem) -> str:
        """状态跟踪的 key，默认用 collection:source_id。"""
        return f'{self.collection_name}:{item.source_id}'
