"""
EditTemplate 剪辑模板领域模型单元测试
"""

import pytest

from packages.domain.edit_template import EditTemplate, EditTemplateStatus
from packages.domain.editing_mode import EditingMode


class TestEditTemplateStatus:
    """EditTemplateStatus 枚举测试"""

    def test_status_values(self):
        assert EditTemplateStatus.ACTIVE == "active"
        assert EditTemplateStatus.INACTIVE == "inactive"


class TestEditTemplateCreate:
    """create 工厂方法测试"""

    def test_create_minimal(self):
        template = EditTemplate.create(name="测试模板")
        assert template.id is not None
        assert len(template.id) == 32
        assert template.name == "测试模板"
        assert template.description == ""
        assert template.template_type == "default"
        assert template.editing_mode == EditingMode.ONE_TAKE.value
        assert template.config == {}
        assert template.preview_url == ""
        assert template.sort_weight == 0
        assert template.status == EditTemplateStatus.ACTIVE
        assert template.version == 1
        assert template.created_at is not None
        assert template.updated_at is not None

    def test_create_with_all_fields(self):
        template = EditTemplate.create(
            name="口播模板",
            description="适合口播类视频",
            template_type="talking_head",
            editing_mode=EditingMode.VOICE_OVER.value,
            config={"aspect_ratio": "9:16", "duration": 60},
            preview_url="https://example.com/preview.mp4",
            sort_weight=100,
            status=EditTemplateStatus.INACTIVE,
            version=3,
        )
        assert template.name == "口播模板"
        assert template.description == "适合口播类视频"
        assert template.template_type == "talking_head"
        assert template.editing_mode == EditingMode.VOICE_OVER.value
        assert template.config == {"aspect_ratio": "9:16", "duration": 60}
        assert template.preview_url == "https://example.com/preview.mp4"
        assert template.sort_weight == 100
        assert template.status == EditTemplateStatus.INACTIVE
        assert template.version == 3

    def test_create_strips_whitespace(self):
        template = EditTemplate.create(
            name="  我的模板  ",
            description="  描述  ",
            template_type="  ",
            editing_mode="  ",
            preview_url="  url  ",
        )
        assert template.name == "我的模板"
        assert template.description == "描述"
        assert template.template_type == "default"  # 空字符串回退到default
        assert template.editing_mode == EditingMode.ONE_TAKE.value  # 空回退
        assert template.preview_url == "url"

    def test_create_empty_name_raises(self):
        with pytest.raises(ValueError, match="模板名称不能为空"):
            EditTemplate.create(name="   ")

    def test_create_invalid_editing_mode_raises(self):
        with pytest.raises(ValueError, match="无效的 editing_mode"):
            EditTemplate.create(name="测试", editing_mode="invalid_mode")

    def test_create_config_none(self):
        template = EditTemplate.create(name="test", config=None)
        assert template.config == {}
        # 两个模板不共享同一个 dict
        t2 = EditTemplate.create(name="test2")
        assert template.config is not t2.config

    def test_create_all_editing_modes(self):
        """所有合法 editing_mode 都能创建"""
        for mode in EditingMode:
            template = EditTemplate.create(name=f"test_{mode.value}", editing_mode=mode.value)
            assert template.editing_mode == mode.value


class TestEditTemplateActivateDeactivate:
    """激活/停用测试"""

    def test_activate_from_inactive(self):
        template = EditTemplate.create(name="test", status=EditTemplateStatus.INACTIVE)
        old_updated = template.updated_at
        template.activate()
        assert template.status == EditTemplateStatus.ACTIVE
        assert template.updated_at >= old_updated

    def test_activate_from_active(self):
        template = EditTemplate.create(name="test")
        template.activate()
        assert template.status == EditTemplateStatus.ACTIVE

    def test_deactivate_from_active(self):
        template = EditTemplate.create(name="test")
        template.deactivate()
        assert template.status == EditTemplateStatus.INACTIVE

    def test_deactivate_from_inactive(self):
        template = EditTemplate.create(name="test", status=EditTemplateStatus.INACTIVE)
        template.deactivate()
        assert template.status == EditTemplateStatus.INACTIVE


class TestEditTemplateIsActive:
    """is_active 属性测试"""

    def test_is_active_true(self):
        template = EditTemplate.create(name="test")
        assert template.is_active is True

    def test_is_active_false(self):
        template = EditTemplate.create(name="test", status=EditTemplateStatus.INACTIVE)
        assert template.is_active is False


class TestEditTemplateBumpVersion:
    """版本号递增测试"""

    def test_bump_version_increments(self):
        template = EditTemplate.create(name="test", version=1)
        old_updated = template.updated_at
        template.bump_version()
        assert template.version == 2
        assert template.updated_at >= old_updated

    def test_bump_version_multiple(self):
        template = EditTemplate.create(name="test", version=5)
        template.bump_version()
        template.bump_version()
        assert template.version == 7

    def test_bump_version_updates_timestamp(self):
        template = EditTemplate.create(name="test")
        old_updated = template.updated_at
        template.bump_version()
        assert template.updated_at > old_updated or template.updated_at == old_updated


class TestEditTemplateExtended:
    """EditTemplate 深度补充测试"""

    def test_id_is_hex(self):
        t = EditTemplate.create(name="test")
        int(t.id, 16)

    def test_ids_are_unique(self):
        t1 = EditTemplate.create(name="test1")
        t2 = EditTemplate.create(name="test2")
        assert t1.id != t2.id

    def test_empty_description(self):
        t = EditTemplate.create(name="test", description="")
        assert t.description == ""

    def test_long_description(self):
        desc = "描述" * 200
        t = EditTemplate.create(name="test", description=desc)
        assert t.description == desc
        assert len(t.description) == 400

    def test_unicode_name(self):
        t = EditTemplate.create(name="🎬 口播 Vlog 模板")
        assert "🎬" in t.name
        assert "口播" in t.name

    def test_special_characters_name(self):
        special = "模!@#$%板"
        t = EditTemplate.create(name=special)
        assert t.name == special

    def test_long_name(self):
        long_name = "模板名称" * 50
        t = EditTemplate.create(name=long_name)
        assert t.name == long_name
        assert len(t.name) == 200

    def test_config_independence(self):
        t1 = EditTemplate.create(name="test1")
        t2 = EditTemplate.create(name="test2")
        t1.config["key"] = "val"
        assert "key" not in t2.config

    def test_sort_weight_negative(self):
        t = EditTemplate.create(name="test", sort_weight=-100)
        assert t.sort_weight == -100

    def test_sort_weight_large(self):
        t = EditTemplate.create(name="test", sort_weight=99999)
        assert t.sort_weight == 99999

    def test_sort_weight_zero(self):
        t = EditTemplate.create(name="test", sort_weight=0)
        assert t.sort_weight == 0

    def test_preview_url_empty(self):
        t = EditTemplate.create(name="test", preview_url="")
        assert t.preview_url == ""

    def test_version_zero(self):
        t = EditTemplate.create(name="test", version=0)
        assert t.version == 0

    def test_version_large(self):
        t = EditTemplate.create(name="test", version=999)
        assert t.version == 999

    def test_status_is_active_property(self):
        t = EditTemplate.create(name="test", status=EditTemplateStatus.ACTIVE)
        assert t.is_active is True
        t.deactivate()
        assert t.is_active is False
        t.activate()
        assert t.is_active is True

    def test_bump_version_from_zero(self):
        t = EditTemplate.create(name="test", version=0)
        t.bump_version()
        assert t.version == 1

    def test_template_type_custom(self):
        t = EditTemplate.create(name="test", template_type="custom_type")
        assert t.template_type == "custom_type"

    def test_template_type_strips_and_default(self):
        """空格的 template_type 回退到 default"""
        t = EditTemplate.create(name="test", template_type="   ")
        assert t.template_type == "default"

    def test_create_with_empty_editing_mode_defaults(self):
        """空字符串 editing_mode 回退到 one_take"""
        t = EditTemplate.create(name="test", editing_mode="")
        assert t.editing_mode == "one_take"

    def test_preview_url_strips_whitespace(self):
        t = EditTemplate.create(name="test", preview_url="  https://example.com/v.mp4  ")
        assert t.preview_url == "https://example.com/v.mp4"
