"""Tests for UseCase Pydantic models."""
import hashlib
from datetime import UTC, datetime

import pytest

from ai_usecases_explorer.models.usecase import (
    Novelty,
    ScenarioType,
    UseCase,
    make_id,
)


class TestMakeId:
    def test_returns_12_char_hex(self) -> None:
        result = make_id("https://example.com/post/123")
        assert len(result) == 12
        assert all(c in "0123456789abcdef" for c in result)

    def test_deterministic(self) -> None:
        url = "https://news.ycombinator.com/item?id=12345"
        assert make_id(url) == make_id(url)

    def test_different_urls_different_ids(self) -> None:
        assert make_id("https://example.com/a") != make_id("https://example.com/b")

    def test_matches_sha256_prefix(self) -> None:
        url = "https://example.com"
        expected = hashlib.sha256(url.encode()).hexdigest()[:12]
        assert make_id(url) == expected


class TestScenarioType:
    def test_all_values_are_chinese_strings(self) -> None:
        for member in ScenarioType:
            assert isinstance(member.value, str)

    def test_has_expected_members(self) -> None:
        names = {m.name for m in ScenarioType}
        assert "LOCAL_DATA_INTEGRATION" in names
        assert "CODE_GEN_REVIEW" in names
        assert "WORKFLOW_AUTOMATION" in names
        assert "OTHER" in names

    def test_other_fallback(self) -> None:
        assert ScenarioType.OTHER == "其他"


class TestNovelty:
    def test_values(self) -> None:
        assert Novelty.NEW == "new"
        assert Novelty.SIMILAR == "similar"
        assert Novelty.REPEAT == "repeat"


class TestUseCase:
    def _valid_payload(self) -> dict:
        now = datetime.now(tz=UTC)
        return {
            "id": "abc123def456",
            "title": "Using Claude to analyse local CSV data",
            "summary": "User connects Claude Code to local CSVs. Avoids manual Excel steps.",
            "source_url": "https://reddit.com/r/ClaudeAI/comments/xyz",
            "source_platform": "reddit",
            "author": "user123",
            "published_at": now,
            "collected_at": now,
            "scenario_type": ScenarioType.LOCAL_DATA_INTEGRATION,
            "tools_used": ["Claude Code", "Python", "pandas"],
            "has_local_data": True,
            "has_workflow_opt": True,
            "value_score": 0.85,
            "is_real_value": True,
            "novelty": Novelty.NEW,
            "similar_to_ids": [],
            "raw_content": "Original post content here...",
        }

    def test_valid_usecase_creates_successfully(self) -> None:
        uc = UseCase(**self._valid_payload())
        assert uc.title == "Using Claude to analyse local CSV data"
        assert uc.has_local_data is True
        assert uc.value_score == 0.85

    def test_value_score_clamped_to_0_1(self) -> None:
        payload = self._valid_payload()
        payload["value_score"] = 1.5
        with pytest.raises(Exception):
            UseCase(**payload)

    def test_value_score_below_zero_rejected(self) -> None:
        payload = self._valid_payload()
        payload["value_score"] = -0.1
        with pytest.raises(Exception):
            UseCase(**payload)

    def test_source_platform_hackernews(self) -> None:
        payload = self._valid_payload()
        payload["source_platform"] = "hackernews"
        uc = UseCase(**payload)
        assert uc.source_platform == "hackernews"

    def test_tools_used_is_list(self) -> None:
        uc = UseCase(**self._valid_payload())
        assert isinstance(uc.tools_used, list)

    def test_similar_to_ids_defaults_empty(self) -> None:
        payload = self._valid_payload()
        payload["similar_to_ids"] = []
        uc = UseCase(**payload)
        assert uc.similar_to_ids == []

    def test_scenario_type_accepts_enum(self) -> None:
        uc = UseCase(**self._valid_payload())
        assert uc.scenario_type == ScenarioType.LOCAL_DATA_INTEGRATION

    def test_scenario_type_accepts_string_value(self) -> None:
        payload = self._valid_payload()
        payload["scenario_type"] = "本地数据集成"
        uc = UseCase(**payload)
        assert uc.scenario_type == ScenarioType.LOCAL_DATA_INTEGRATION

    def test_novelty_accepts_string_value(self) -> None:
        payload = self._valid_payload()
        payload["novelty"] = "new"
        uc = UseCase(**payload)
        assert uc.novelty == Novelty.NEW

    def test_serialises_to_dict(self) -> None:
        uc = UseCase(**self._valid_payload())
        d = uc.model_dump()
        assert d["id"] == "abc123def456"
        assert d["novelty"] == "new"
