"""Tests for Obsidian Markdown report generation."""
from datetime import UTC, date, datetime
from pathlib import Path

import pytest

from ai_usecases_explorer.models.usecase import Novelty, ScenarioType, UseCase
from ai_usecases_explorer.reporters.obsidian import ObsidianReporter


def _usecase(
    id: str = "abc123def456",
    title: str = "Test Use Case",
    novelty: Novelty = Novelty.NEW,
    scenario: ScenarioType = ScenarioType.CODE_GEN_REVIEW,
    is_real_value: bool = True,
    tools: list[str] | None = None,
    author: str = "testuser",
    url: str = "https://example.com/post",
    platform: str = "hackernews",
    summary: str = "A test summary.",
) -> UseCase:
    now = datetime.now(tz=UTC)
    return UseCase(
        id=id,
        title=title,
        summary=summary,
        source_url=url,
        source_platform=platform,
        author=author,
        published_at=now,
        collected_at=now,
        scenario_type=scenario,
        tools_used=tools or ["Claude"],
        has_local_data=True,
        has_workflow_opt=True,
        value_score=0.8,
        is_real_value=is_real_value,
        novelty=novelty,
        similar_to_ids=[],
        raw_content="raw",
    )


@pytest.fixture
def reporter(tmp_path: Path) -> ObsidianReporter:
    return ObsidianReporter(output_dir=tmp_path)


class TestObsidianReporterGenerate:
    def test_returns_markdown_string(self, reporter: ObsidianReporter) -> None:
        usecases = [_usecase()]
        md = reporter.generate(usecases, report_date=date(2026, 2, 27))
        assert isinstance(md, str)

    def test_includes_date_in_header(self, reporter: ObsidianReporter) -> None:
        usecases = [_usecase()]
        md = reporter.generate(usecases, report_date=date(2026, 2, 27))
        assert "2026-02-27" in md

    def test_includes_scan_summary_line(self, reporter: ObsidianReporter) -> None:
        hn_item = _usecase("hn001", platform="hackernews", novelty=Novelty.NEW)
        reddit_item = _usecase("red001", platform="reddit", novelty=Novelty.SIMILAR)
        filtered_item = _usecase("low001", is_real_value=False, novelty=Novelty.REPEAT)
        usecases = [hn_item, reddit_item, filtered_item]
        md = reporter.generate(usecases, report_date=date(2026, 2, 27))
        # Should show counts
        assert "HN" in md or "hackernews" in md.lower()

    def test_new_section_contains_new_usecases(self, reporter: ObsidianReporter) -> None:
        new_uc = _usecase("new001", novelty=Novelty.NEW)
        similar_uc = _usecase("sim001", novelty=Novelty.SIMILAR)
        md = reporter.generate([new_uc, similar_uc], report_date=date(2026, 2, 27))
        assert "新场景" in md
        assert new_uc.title in md

    def test_similar_section_contains_similar_usecases(self, reporter: ObsidianReporter) -> None:
        similar_uc = _usecase("sim001", novelty=Novelty.SIMILAR)
        md = reporter.generate([similar_uc], report_date=date(2026, 2, 27))
        assert "已知场景" in md or "新案例" in md

    def test_filter_log_section_present(self, reporter: ObsidianReporter) -> None:
        usecases = [_usecase(is_real_value=False, novelty=Novelty.REPEAT)]
        md = reporter.generate(usecases, report_date=date(2026, 2, 27))
        assert "过滤" in md or "filter" in md.lower()

    def test_tools_shown_in_new_section(self, reporter: ObsidianReporter) -> None:
        new_uc = _usecase("new001", novelty=Novelty.NEW, tools=["Claude Code", "Python"])
        md = reporter.generate([new_uc], report_date=date(2026, 2, 27))
        assert "Claude Code" in md

    def test_empty_usecases_produces_valid_report(self, reporter: ObsidianReporter) -> None:
        md = reporter.generate([], report_date=date(2026, 2, 27))
        assert "2026-02-27" in md
        assert len(md) > 50

    def test_groups_similar_by_scenario_type(self, reporter: ObsidianReporter) -> None:
        uc1 = _usecase("s1", novelty=Novelty.SIMILAR, scenario=ScenarioType.CODE_GEN_REVIEW)
        uc2 = _usecase("s2", novelty=Novelty.SIMILAR, scenario=ScenarioType.WORKFLOW_AUTOMATION)
        md = reporter.generate([uc1, uc2], report_date=date(2026, 2, 27))
        assert ScenarioType.CODE_GEN_REVIEW.value in md
        assert ScenarioType.WORKFLOW_AUTOMATION.value in md


class TestObsidianReporterWrite:
    def test_writes_file_to_output_dir(self, reporter: ObsidianReporter, tmp_path: Path) -> None:
        usecases = [_usecase()]
        report_date = date(2026, 2, 27)
        path = reporter.write(usecases, report_date=report_date)
        assert path.exists()
        assert path.name == "2026-02-27.md"

    def test_written_file_contains_markdown(self, reporter: ObsidianReporter, tmp_path: Path) -> None:
        usecases = [_usecase()]
        path = reporter.write(usecases, report_date=date(2026, 2, 27))
        content = path.read_text(encoding="utf-8")
        assert "2026-02-27" in content

    def test_creates_output_dir_if_missing(self, tmp_path: Path) -> None:
        deep_dir = tmp_path / "a" / "b" / "c"
        reporter = ObsidianReporter(output_dir=deep_dir)
        path = reporter.write([], report_date=date(2026, 2, 27))
        assert path.exists()
