"""Obsidian vault source for mykb."""

import hashlib
from datetime import datetime, timezone
from pathlib import Path
from typing import Iterator
from urllib.parse import quote

from mykb.core.chunker import parse_markdown
from .base import BaseSource, SourceItem


def file_mtime_iso(path: Path) -> str | None:
    stat = path.stat()
    return datetime.fromtimestamp(stat.st_mtime, tz=timezone.utc).isoformat()


def file_ctime_iso(path: Path) -> str | None:
    stat = path.stat()
    return datetime.fromtimestamp(stat.st_ctime, tz=timezone.utc).isoformat()


def build_obsidian_uri(collection_path: Path, rel_path: str) -> str:
    """Build a source URI. For obsidian vaults, use obsidian:// scheme."""
    obsidian_config = collection_path / '.obsidian'
    if obsidian_config.exists():
        vault_name = collection_path.name
        encoded_path = quote(rel_path.replace('.md', ''), safe='/')
        return f'obsidian://open?vault={quote(vault_name)}&file={encoded_path}'
    return f'file://{collection_path / rel_path}'


class ObsidianSource(BaseSource):
    source_type = 'obsidian'

    def scan(self) -> Iterator[SourceItem]:
        base = Path(self.config['path'])
        mask = self.config.get('mask', '**/*.md')
        exclude = self.config.get('exclude', [])

        for file_path in base.glob(mask):
            if not file_path.is_file():
                continue
            rel = file_path.relative_to(base)
            if any(rel.match(pat) for pat in exclude):
                continue

            parsed = parse_markdown(file_path)
            rel_str = str(rel)

            yield SourceItem(
                source_type='obsidian',
                source_id=rel_str,
                source_uri=build_obsidian_uri(base, rel_str),
                title=parsed.title,
                content=parsed.content,
                category=parsed.category,
                tags=parsed.tags,
                created_at=file_ctime_iso(file_path),
                modified_at=file_mtime_iso(file_path),
                metadata=parsed.frontmatter,
            )

    def content_hash(self, item: SourceItem) -> str:
        return hashlib.md5(item.content.encode('utf-8')).hexdigest()[:12]
