"""classification 单测.

domain 层素材分类模块纯逻辑，0 外部依赖。
覆盖：4个枚举 + ClassificationJob 工厂/校验。
"""

from __future__ import annotations

from packages.domain.classification import (
    AssetClassification,
    AssetLibraryKind,
    ClassificationJob,
    ClassificationJobStatus,
    IngestJobStatus,
)


class TestAssetLibraryKind:
    """AssetLibraryKind 枚举测试."""

    def test_three_values(self):
        """视频/配音/图片三类."""
        assert len(AssetLibraryKind) == 3

    def test_video(self):
        assert AssetLibraryKind.VIDEO == "video"

    def test_voice(self):
        assert AssetLibraryKind.VOICE == "voice"

    def test_image(self):
        assert AssetLibraryKind.IMAGE == "image"

    def test_str_compatible(self):
        """StrEnum 字符串兼容."""
        assert AssetLibraryKind.VIDEO == "video"


class TestIngestJobStatus:
    """IngestJobStatus 枚举测试."""

    def test_four_statuses(self):
        assert len(IngestJobStatus) == 4

    def test_pending(self):
        assert IngestJobStatus.PENDING == "pending"

    def test_processing(self):
        assert IngestJobStatus.PROCESSING == "processing"

    def test_completed(self):
        assert IngestJobStatus.COMPLETED == "completed"

    def test_failed(self):
        assert IngestJobStatus.FAILED == "failed"


class TestClassificationJobStatus:
    """ClassificationJobStatus 枚举测试."""

    def test_four_statuses(self):
        assert len(ClassificationJobStatus) == 4

    def test_pending(self):
        assert ClassificationJobStatus.PENDING == "pending"

    def test_processing(self):
        assert ClassificationJobStatus.PROCESSING == "processing"

    def test_completed(self):
        assert ClassificationJobStatus.COMPLETED == "completed"

    def test_failed(self):
        assert ClassificationJobStatus.FAILED == "failed"

    def test_same_values_as_ingest(self):
        """两种任务状态值相同."""
        assert set(ClassificationJobStatus) == set(IngestJobStatus)


class TestAssetClassification:
    """AssetClassification 枚举测试."""

    def test_nine_categories(self):
        """9个分类."""
        assert len(AssetClassification) == 9

    def test_scenic(self):
        assert AssetClassification.SCENIC == "scenic"

    def test_product(self):
        assert AssetClassification.PRODUCT == "product"

    def test_person(self):
        assert AssetClassification.PERSON == "person"

    def test_animal(self):
        assert AssetClassification.ANIMAL == "animal"

    def test_food(self):
        assert AssetClassification.FOOD == "food"

    def test_tech(self):
        assert AssetClassification.TECH == "tech"

    def test_sport(self):
        assert AssetClassification.SPORT == "sport"

    def test_music(self):
        assert AssetClassification.MUSIC == "music"

    def test_other(self):
        assert AssetClassification.OTHER == "other"

    def test_all_values_unique(self):
        """所有分类值唯一."""
        values = [c.value for c in AssetClassification]
        assert len(values) == len(set(values))


class TestClassificationJobCreate:
    """ClassificationJob.create 测试."""

    def test_create_valid(self):
        """正常创建."""
        job = ClassificationJob.create(project_id="proj1", asset_id="asset1")
        assert job.project_id == "proj1"
        assert job.asset_id == "asset1"
        assert job.status == ClassificationJobStatus.PENDING
        assert job.classification == ""
        assert job.confidence == 0.0
        assert job.error_message == ""
        assert isinstance(job.id, str)
        assert len(job.id) > 0

    def test_create_strips(self):
        """project_id 和 asset_id 会 strip."""
        job = ClassificationJob.create(project_id="  proj1  ", asset_id="  asset1  ")
        assert job.project_id == "proj1"
        assert job.asset_id == "asset1"

    def test_create_empty_project_id(self):
        """空 project_id 无效."""
        try:
            ClassificationJob.create(project_id="", asset_id="a1")
            assert False
        except ValueError as e:
            assert "project_id" in str(e)

    def test_create_whitespace_project_id(self):
        """纯空白 project_id 无效."""
        try:
            ClassificationJob.create(project_id="   ", asset_id="a1")
            assert False
        except ValueError as e:
            assert "project_id" in str(e)

    def test_create_empty_asset_id(self):
        """空 asset_id 无效."""
        try:
            ClassificationJob.create(project_id="p1", asset_id="")
            assert False
        except ValueError as e:
            assert "asset_id" in str(e)

    def test_create_whitespace_asset_id(self):
        """纯空白 asset_id 无效."""
        try:
            ClassificationJob.create(project_id="p1", asset_id="   ")
            assert False
        except ValueError as e:
            assert "asset_id" in str(e)

    def test_create_unique_id(self):
        """不同 job id 不同."""
        j1 = ClassificationJob.create("p", "a")
        j2 = ClassificationJob.create("p", "a")
        assert j1.id != j2.id

    def test_create_has_timestamps(self):
        """有创建和更新时间."""
        job = ClassificationJob.create("p", "a")
        assert job.created_at is not None
        assert job.updated_at is not None
