"""BGM配置合并逻辑单元测试。"""

import pytest

from packages.domain.bgm_utils import merge_bgm_config


class TestMergeBgmConfig:
    """merge_bgm_config 单元测试。"""

    def test_template_empty_user_has_config(self):
        """模板为空，用户有配置 → 返回用户配置副本。"""
        template = {}
        user = {"audio_url": "http://example.com/bgm.mp3", "volume": 0.8}

        result = merge_bgm_config(template, user)

        assert result == {"audio_url": "http://example.com/bgm.mp3", "volume": 0.8}
        # 确保返回的是新对象，不是同一引用
        assert result is not user

    def test_user_empty_template_has_config(self):
        """用户为空，模板有配置 → 返回模板配置副本。"""
        template = {"audio_url": "http://example.com/default.mp3", "enabled": True}
        user = {}

        result = merge_bgm_config(template, user)

        assert result == {"audio_url": "http://example.com/default.mp3", "enabled": True}
        assert result is not template

    def test_both_empty(self):
        """都为空 → 返回空dict。"""
        result = merge_bgm_config({}, {})
        assert result == {}

    def test_user_overrides_single_field(self):
        """用户覆盖单个普通字段。"""
        template = {"audio_url": "http://template.com/default.mp3", "volume": 0.5}
        user = {"audio_url": "http://user.com/custom.mp3"}

        result = merge_bgm_config(template, user)

        assert result["audio_url"] == "http://user.com/custom.mp3"
        assert result["volume"] == 0.5  # 模板值保留

    def test_user_overrides_multiple_fields(self):
        """用户覆盖多个字段。"""
        template = {
            "audio_url": "http://template.com/default.mp3",
            "volume": 0.5,
            "fade_in": 1.0,
            "fade_out": 1.0,
        }
        user = {
            "audio_url": "http://user.com/custom.mp3",
            "volume": 0.9,
        }

        result = merge_bgm_config(template, user)

        assert result["audio_url"] == "http://user.com/custom.mp3"
        assert result["volume"] == 0.9
        assert result["fade_in"] == 1.0
        assert result["fade_out"] == 1.0

    def test_enabled_not_in_user_keep_template_true(self):
        """enabled特殊处理：用户没传，模板enabled=True → 保留True。"""
        template = {"audio_url": "http://template.com/default.mp3", "enabled": True}
        user = {"audio_url": "http://user.com/custom.mp3"}

        result = merge_bgm_config(template, user)

        assert result["enabled"] is True
        assert result["audio_url"] == "http://user.com/custom.mp3"

    def test_enabled_not_in_user_keep_template_false(self):
        """enabled特殊处理：用户没传，模板enabled=False → 保留False。"""
        template = {"audio_url": "http://template.com/default.mp3", "enabled": False}
        user = {"audio_url": "http://user.com/custom.mp3"}

        result = merge_bgm_config(template, user)

        assert result["enabled"] is False

    def test_enabled_explicit_true_overrides_template_false(self):
        """enabled特殊处理：用户显式传True，覆盖模板False。"""
        template = {"audio_url": "http://template.com/default.mp3", "enabled": False}
        user = {"enabled": True}

        result = merge_bgm_config(template, user)

        assert result["enabled"] is True

    def test_enabled_explicit_false_overrides_template_true(self):
        """enabled特殊处理：用户显式传False，覆盖模板True。"""
        template = {"audio_url": "http://template.com/default.mp3", "enabled": True}
        user = {"enabled": False}

        result = merge_bgm_config(template, user)

        assert result["enabled"] is False

    def test_nested_fields_shallow_merge(self):
        """普通字段（包括嵌套dict）按浅层合并处理。"""
        template = {
            "audio_url": "http://template.com/default.mp3",
            "effects": {"fade_in": 1.0, "fade_out": 1.0},
        }
        user = {
            "effects": {"fade_in": 3.0},  # 整个覆盖，不是深合并
        }

        result = merge_bgm_config(template, user)

        # 浅层合并：用户的effects完全替换模板的effects
        assert result["effects"] == {"fade_in": 3.0}

    def test_user_none_value_fields(self):
        """用户传None值的字段，会覆盖模板值为None。"""
        template = {"audio_url": "http://template.com/default.mp3", "volume": 0.5}
        user = {"audio_url": None}

        result = merge_bgm_config(template, user)

        assert result["audio_url"] is None
        assert result["volume"] == 0.5

    def test_does_not_mutate_inputs(self):
        """合并操作不修改原始输入对象。"""
        template = {"audio_url": "http://template.com/default.mp3", "enabled": True, "volume": 0.5}
        user = {"volume": 0.9}
        template_copy = dict(template)
        user_copy = dict(user)

        merge_bgm_config(template, user)

        assert template == template_copy
        assert user == user_copy

    def test_user_adds_new_field(self):
        """用户新增模板中没有的字段。"""
        template = {"audio_url": "http://template.com/default.mp3"}
        user = {"loop": True, "start_time": 5.0}

        result = merge_bgm_config(template, user)

        assert result["audio_url"] == "http://template.com/default.mp3"
        assert result["loop"] is True
        assert result["start_time"] == 5.0

    def test_asset_id_and_preset_id_fields(self):
        """asset_id和preset_id字段正常合并。"""
        template = {"preset_id": "preset_default", "volume": 0.5}
        user = {"asset_id": "asset_user_123"}

        result = merge_bgm_config(template, user)

        assert result["preset_id"] == "preset_default"
        assert result["asset_id"] == "asset_user_123"
        assert result["volume"] == 0.5
