"""The tests for the  Template light platform."""

from typing import Any

import pytest

from homeassistant.components import light, template
from homeassistant.components.light import (
    ATTR_BRIGHTNESS,
    ATTR_COLOR_TEMP_KELVIN,
    ATTR_EFFECT,
    ATTR_HS_COLOR,
    ATTR_RGB_COLOR,
    ATTR_RGBW_COLOR,
    ATTR_RGBWW_COLOR,
    ATTR_TRANSITION,
    ColorMode,
    LightEntityFeature,
)
from homeassistant.components.template.light import rewrite_legacy_to_modern_conf
from homeassistant.const import (
    ATTR_ENTITY_ID,
    SERVICE_TURN_OFF,
    SERVICE_TURN_ON,
    STATE_OFF,
    STATE_ON,
    STATE_UNAVAILABLE,
    STATE_UNKNOWN,
)
from homeassistant.core import HomeAssistant, ServiceCall
from homeassistant.helpers import entity_registry as er
from homeassistant.helpers.template import Template
from homeassistant.setup import async_setup_component

from .conftest import ConfigurationStyle

from tests.common import assert_setup_component

# Represent for light's availability
_STATE_AVAILABILITY_BOOLEAN = "availability_boolean.state"


OPTIMISTIC_ON_OFF_LIGHT_CONFIG = {
    "turn_on": {
        "service": "test.automation",
        "data_template": {
            "action": "turn_on",
            "caller": "{{ this.entity_id }}",
        },
    },
    "turn_off": {
        "service": "test.automation",
        "data_template": {
            "action": "turn_off",
            "caller": "{{ this.entity_id }}",
        },
    },
}


OPTIMISTIC_BRIGHTNESS_LIGHT_CONFIG = {
    **OPTIMISTIC_ON_OFF_LIGHT_CONFIG,
    "set_level": {
        "service": "test.automation",
        "data_template": {
            "action": "set_level",
            "brightness": "{{brightness}}",
            "caller": "{{ this.entity_id }}",
        },
    },
}


OPTIMISTIC_COLOR_TEMP_LIGHT_CONFIG = {
    **OPTIMISTIC_ON_OFF_LIGHT_CONFIG,
    "set_temperature": {
        "service": "test.automation",
        "data_template": {
            "action": "set_temperature",
            "caller": "{{ this.entity_id }}",
            "color_temp": "{{color_temp}}",
        },
    },
}


OPTIMISTIC_LEGACY_COLOR_LIGHT_CONFIG = {
    **OPTIMISTIC_ON_OFF_LIGHT_CONFIG,
    "set_color": {
        "service": "test.automation",
        "data_template": {
            "action": "set_color",
            "caller": "{{ this.entity_id }}",
            "s": "{{s}}",
            "h": "{{h}}",
        },
    },
}


OPTIMISTIC_HS_COLOR_LIGHT_CONFIG = {
    **OPTIMISTIC_ON_OFF_LIGHT_CONFIG,
    "set_hs": {
        "service": "test.automation",
        "data_template": {
            "action": "set_hs",
            "caller": "{{ this.entity_id }}",
            "s": "{{s}}",
            "h": "{{h}}",
        },
    },
}


OPTIMISTIC_RGB_COLOR_LIGHT_CONFIG = {
    **OPTIMISTIC_ON_OFF_LIGHT_CONFIG,
    "set_rgb": {
        "service": "test.automation",
        "data_template": {
            "action": "set_rgb",
            "caller": "{{ this.entity_id }}",
            "r": "{{r}}",
            "g": "{{g}}",
            "b": "{{b}}",
        },
    },
}


OPTIMISTIC_RGBW_COLOR_LIGHT_CONFIG = {
    **OPTIMISTIC_ON_OFF_LIGHT_CONFIG,
    "set_rgbw": {
        "service": "test.automation",
        "data_template": {
            "action": "set_rgbw",
            "caller": "{{ this.entity_id }}",
            "r": "{{r}}",
            "g": "{{g}}",
            "b": "{{b}}",
            "w": "{{w}}",
        },
    },
}


OPTIMISTIC_RGBWW_COLOR_LIGHT_CONFIG = {
    **OPTIMISTIC_ON_OFF_LIGHT_CONFIG,
    "set_rgbww": {
        "service": "test.automation",
        "data_template": {
            "action": "set_rgbww",
            "caller": "{{ this.entity_id }}",
            "r": "{{r}}",
            "g": "{{g}}",
            "b": "{{b}}",
            "cw": "{{cw}}",
            "ww": "{{ww}}",
        },
    },
}


TEST_STATE_TRIGGER = {
    "trigger": {"trigger": "state", "entity_id": "light.test_state"},
    "variables": {"triggering_entity": "{{ trigger.entity_id }}"},
    "action": [{"event": "action_event", "event_data": {"what": "triggering_entity"}}],
}


TEST_EVENT_TRIGGER = {
    "trigger": {"platform": "event", "event_type": "test_event"},
    "variables": {"type": "{{ trigger.event.data.type }}"},
    "action": [{"event": "action_event", "event_data": {"type": "{{ type }}"}}],
}


TEST_MISSING_KEY_CONFIG = {
    "turn_on": {
        "service": "light.turn_on",
        "entity_id": "light.test_state",
    },
    "set_level": {
        "service": "light.turn_on",
        "data_template": {
            "entity_id": "light.test_state",
            "brightness": "{{brightness}}",
        },
    },
}


TEST_ON_ACTION_WITH_TRANSITION_CONFIG = {
    "turn_on": {
        "service": "test.automation",
        "data_template": {
            "transition": "{{transition}}",
        },
    },
    "turn_off": {
        "service": "light.turn_off",
        "entity_id": "light.test_state",
    },
    "set_level": {
        "service": "light.turn_on",
        "data_template": {
            "entity_id": "light.test_state",
            "brightness": "{{brightness}}",
            "transition": "{{transition}}",
        },
    },
}


TEST_OFF_ACTION_WITH_TRANSITION_CONFIG = {
    "turn_on": {
        "service": "light.turn_on",
        "entity_id": "light.test_state",
    },
    "turn_off": {
        "service": "test.automation",
        "data_template": {
            "transition": "{{transition}}",
        },
    },
    "set_level": {
        "service": "light.turn_on",
        "data_template": {
            "entity_id": "light.test_state",
            "brightness": "{{brightness}}",
            "transition": "{{transition}}",
        },
    },
}


TEST_ALL_COLORS_NO_TEMPLATE_CONFIG = {
    "set_hs": {
        "service": "test.automation",
        "data_template": {
            "entity_id": "test.test_state",
            "h": "{{h}}",
            "s": "{{s}}",
        },
    },
    "set_temperature": {
        "service": "test.automation",
        "data_template": {
            "entity_id": "test.test_state",
            "color_temp": "{{color_temp}}",
        },
    },
    "set_rgb": {
        "service": "test.automation",
        "data_template": {
            "entity_id": "test.test_state",
            "r": "{{r}}",
            "g": "{{g}}",
            "b": "{{b}}",
        },
    },
    "set_rgbw": {
        "service": "test.automation",
        "data_template": {
            "entity_id": "test.test_state",
            "r": "{{r}}",
            "g": "{{g}}",
            "b": "{{b}}",
            "w": "{{w}}",
        },
    },
    "set_rgbww": {
        "service": "test.automation",
        "data_template": {
            "entity_id": "test.test_state",
            "r": "{{r}}",
            "g": "{{g}}",
            "b": "{{b}}",
            "cw": "{{cw}}",
            "ww": "{{ww}}",
        },
    },
}


TEST_UNIQUE_ID_CONFIG = {
    **OPTIMISTIC_ON_OFF_LIGHT_CONFIG,
    "unique_id": "not-so-unique-anymore",
}


@pytest.mark.parametrize(
    ("old_attr", "new_attr", "attr_template"),
    [
        (
            "value_template",
            "state",
            "{{ 1 == 1 }}",
        ),
        (
            "rgb_template",
            "rgb",
            "{{ (255,255,255) }}",
        ),
        (
            "rgbw_template",
            "rgbw",
            "{{ (255,255,255,255) }}",
        ),
        (
            "rgbww_template",
            "rgbww",
            "{{ (255,255,255,255,255) }}",
        ),
        (
            "effect_list_template",
            "effect_list",
            "{{ ['a', 'b'] }}",
        ),
        (
            "effect_template",
            "effect",
            "{{ 'a' }}",
        ),
        (
            "level_template",
            "level",
            "{{ 255 }}",
        ),
        (
            "max_mireds_template",
            "max_mireds",
            "{{ 255 }}",
        ),
        (
            "min_mireds_template",
            "min_mireds",
            "{{ 255 }}",
        ),
        (
            "supports_transition_template",
            "supports_transition",
            "{{ True }}",
        ),
        (
            "temperature_template",
            "temperature",
            "{{ 255 }}",
        ),
        (
            "white_value_template",
            "white_value",
            "{{ 255 }}",
        ),
        (
            "hs_template",
            "hs",
            "{{ (255, 255) }}",
        ),
        (
            "color_template",
            "hs",
            "{{ (255, 255) }}",
        ),
    ],
)
async def test_legacy_to_modern_config(
    hass: HomeAssistant, old_attr: str, new_attr: str, attr_template: str
) -> None:
    """Test the conversion of legacy template to modern template."""
    config = {
        "foo": {
            "friendly_name": "foo bar",
            "unique_id": "foo-bar-light",
            "icon_template": "{{ 'mdi.abc' }}",
            "entity_picture_template": "{{ 'mypicture.jpg' }}",
            "availability_template": "{{ 1 == 1 }}",
            old_attr: attr_template,
            **OPTIMISTIC_ON_OFF_LIGHT_CONFIG,
        }
    }
    altered_configs = rewrite_legacy_to_modern_conf(hass, config)

    assert len(altered_configs) == 1

    assert [
        {
            "availability": Template("{{ 1 == 1 }}", hass),
            "icon": Template("{{ 'mdi.abc' }}", hass),
            "name": Template("foo bar", hass),
            "object_id": "foo",
            "picture": Template("{{ 'mypicture.jpg' }}", hass),
            "turn_off": {
                "data_template": {
                    "action": "turn_off",
                    "caller": "{{ this.entity_id }}",
                },
                "service": "test.automation",
            },
            "turn_on": {
                "data_template": {
                    "action": "turn_on",
                    "caller": "{{ this.entity_id }}",
                },
                "service": "test.automation",
            },
            "unique_id": "foo-bar-light",
            new_attr: Template(attr_template, hass),
        }
    ] == altered_configs


async def async_setup_legacy_format(
    hass: HomeAssistant, count: int, light_config: dict[str, Any]
) -> None:
    """Do setup of light integration via legacy format."""
    config = {"light": {"platform": "template", "lights": light_config}}

    with assert_setup_component(count, light.DOMAIN):
        assert await async_setup_component(
            hass,
            light.DOMAIN,
            config,
        )

    await hass.async_block_till_done()
    await hass.async_start()
    await hass.async_block_till_done()


async def async_setup_legacy_format_with_attribute(
    hass: HomeAssistant,
    count: int,
    attribute: str,
    attribute_template: str,
    extra_config: dict,
) -> None:
    """Do setup of a legacy light that has a single templated attribute."""
    extra = {attribute: attribute_template} if attribute and attribute_template else {}
    await async_setup_legacy_format(
        hass,
        count,
        {
            "test_template_light": {
                **extra_config,
                "value_template": "{{ 1 == 1 }}",
                **extra,
            }
        },
    )


async def async_setup_modern_format(
    hass: HomeAssistant, count: int, light_config: dict[str, Any]
) -> None:
    """Do setup of light integration via new format."""
    config = {"template": {"light": light_config}}

    with assert_setup_component(count, template.DOMAIN):
        assert await async_setup_component(
            hass,
            template.DOMAIN,
            config,
        )

    await hass.async_block_till_done()
    await hass.async_start()
    await hass.async_block_till_done()


async def async_setup_modern_format_with_attribute(
    hass: HomeAssistant,
    count: int,
    attribute: str,
    attribute_template: str,
    extra_config: dict,
) -> None:
    """Do setup of a legacy light that has a single templated attribute."""
    extra = {attribute: attribute_template} if attribute and attribute_template else {}
    await async_setup_modern_format(
        hass,
        count,
        {
            "name": "test_template_light",
            **extra_config,
            "state": "{{ 1 == 1 }}",
            **extra,
        },
    )


async def async_setup_trigger_format(
    hass: HomeAssistant, count: int, light_config: dict[str, Any]
) -> None:
    """Do setup of light integration via new format."""
    config = {
        "template": {
            **TEST_STATE_TRIGGER,
            "light": light_config,
        }
    }

    with assert_setup_component(count, template.DOMAIN):
        assert await async_setup_component(
            hass,
            template.DOMAIN,
            config,
        )

    await hass.async_block_till_done()
    await hass.async_start()
    await hass.async_block_till_done()


async def async_setup_trigger_format_with_attribute(
    hass: HomeAssistant,
    count: int,
    attribute: str,
    attribute_template: str,
    extra_config: dict,
) -> None:
    """Do setup of a legacy light that has a single templated attribute."""
    extra = {attribute: attribute_template} if attribute and attribute_template else {}
    await async_setup_trigger_format(
        hass,
        count,
        {
            "name": "test_template_light",
            **extra_config,
            "state": "{{ 1 == 1 }}",
            **extra,
        },
    )


@pytest.fixture
async def setup_light(
    hass: HomeAssistant,
    count: int,
    style: ConfigurationStyle,
    light_config: dict[str, Any],
) -> None:
    """Do setup of light integration."""
    if style == ConfigurationStyle.LEGACY:
        await async_setup_legacy_format(hass, count, light_config)
    elif style == ConfigurationStyle.MODERN:
        await async_setup_modern_format(hass, count, light_config)
    elif style == ConfigurationStyle.TRIGGER:
        await async_setup_trigger_format(hass, count, light_config)


@pytest.fixture
async def setup_state_light(
    hass: HomeAssistant,
    count: int,
    style: ConfigurationStyle,
    state_template: str,
):
    """Do setup of light integration."""
    if style == ConfigurationStyle.LEGACY:
        await async_setup_legacy_format(
            hass,
            count,
            {
                "test_template_light": {
                    **OPTIMISTIC_BRIGHTNESS_LIGHT_CONFIG,
                    "value_template": state_template,
                }
            },
        )
    elif style == ConfigurationStyle.MODERN:
        await async_setup_modern_format(
            hass,
            count,
            {
                **OPTIMISTIC_BRIGHTNESS_LIGHT_CONFIG,
                "name": "test_template_light",
                "state": state_template,
            },
        )
    elif style == ConfigurationStyle.TRIGGER:
        await async_setup_trigger_format(
            hass,
            count,
            {
                **OPTIMISTIC_BRIGHTNESS_LIGHT_CONFIG,
                "name": "test_template_light",
                "state": state_template,
            },
        )


@pytest.fixture
async def setup_single_attribute_light(
    hass: HomeAssistant,
    count: int,
    style: ConfigurationStyle,
    attribute: str,
    attribute_template: str,
    extra_config: dict,
) -> None:
    """Do setup of light integration."""
    if style == ConfigurationStyle.LEGACY:
        await async_setup_legacy_format_with_attribute(
            hass, count, attribute, attribute_template, extra_config
        )
    elif style == ConfigurationStyle.MODERN:
        await async_setup_modern_format_with_attribute(
            hass, count, attribute, attribute_template, extra_config
        )
    elif style == ConfigurationStyle.TRIGGER:
        await async_setup_trigger_format_with_attribute(
            hass, count, attribute, attribute_template, extra_config
        )


@pytest.fixture
async def setup_single_action_light(
    hass: HomeAssistant,
    count: int,
    style: ConfigurationStyle,
    extra_config: dict,
) -> None:
    """Do setup of light integration."""
    if style == ConfigurationStyle.LEGACY:
        await async_setup_legacy_format_with_attribute(
            hass, count, "", "", extra_config
        )
    elif style == ConfigurationStyle.MODERN:
        await async_setup_modern_format_with_attribute(
            hass, count, "", "", extra_config
        )
    elif style == ConfigurationStyle.TRIGGER:
        await async_setup_trigger_format_with_attribute(
            hass, count, "", "", extra_config
        )


@pytest.fixture
async def setup_empty_action_light(
    hass: HomeAssistant,
    count: int,
    style: ConfigurationStyle,
    action: str,
    extra_config: dict,
) -> None:
    """Do setup of light integration."""
    if style == ConfigurationStyle.LEGACY:
        await async_setup_legacy_format(
            hass,
            count,
            {
                "test_template_light": {
                    "turn_on": [],
                    "turn_off": [],
                    action: [],
                    **extra_config,
                }
            },
        )
    elif style == ConfigurationStyle.MODERN:
        await async_setup_modern_format(
            hass,
            count,
            {
                "name": "test_template_light",
                "turn_on": [],
                "turn_off": [],
                action: [],
                **extra_config,
            },
        )


@pytest.fixture
async def setup_light_with_effects(
    hass: HomeAssistant,
    count: int,
    style: ConfigurationStyle,
    effect_list_template: str,
    effect_template: str,
) -> None:
    """Do setup of light with effects."""
    common = {
        "set_effect": {
            "service": "test.automation",
            "data_template": {
                "action": "set_effect",
                "caller": "{{ this.entity_id }}",
                "entity_id": "test.test_state",
                "effect": "{{effect}}",
            },
        },
    }
    if style == ConfigurationStyle.LEGACY:
        await async_setup_legacy_format(
            hass,
            count,
            {
                "test_template_light": {
                    **OPTIMISTIC_BRIGHTNESS_LIGHT_CONFIG,
                    "value_template": "{{true}}",
                    **common,
                    "effect_list_template": effect_list_template,
                    "effect_template": effect_template,
                }
            },
        )
    elif style == ConfigurationStyle.MODERN:
        await async_setup_modern_format(
            hass,
            count,
            {
                "name": "test_template_light",
                **OPTIMISTIC_BRIGHTNESS_LIGHT_CONFIG,
                "state": "{{true}}",
                **common,
                "effect_list": effect_list_template,
                "effect": effect_template,
            },
        )
    elif style == ConfigurationStyle.TRIGGER:
        await async_setup_trigger_format(
            hass,
            count,
            {
                "name": "test_template_light",
                **OPTIMISTIC_BRIGHTNESS_LIGHT_CONFIG,
                "state": "{{true}}",
                **common,
                "effect_list": effect_list_template,
                "effect": effect_template,
            },
        )


@pytest.fixture
async def setup_light_with_mireds(
    hass: HomeAssistant,
    count: int,
    style: ConfigurationStyle,
    attribute: str,
    attribute_template: str,
) -> None:
    """Do setup of light that uses mireds."""
    common = {
        "set_temperature": {
            "service": "light.turn_on",
            "data_template": {
                "entity_id": "light.test_state",
                "color_temp": "{{color_temp}}",
            },
        },
        attribute: attribute_template,
    }
    if style == ConfigurationStyle.LEGACY:
        await async_setup_legacy_format(
            hass,
            count,
            {
                "test_template_light": {
                    **OPTIMISTIC_ON_OFF_LIGHT_CONFIG,
                    "value_template": "{{ 1 == 1 }}",
                    **common,
                    "temperature_template": "{{200}}",
                }
            },
        )
    elif style == ConfigurationStyle.MODERN:
        await async_setup_modern_format(
            hass,
            count,
            {
                "name": "test_template_light",
                **OPTIMISTIC_ON_OFF_LIGHT_CONFIG,
                "state": "{{ 1 == 1 }}",
                **common,
                "temperature": "{{200}}",
            },
        )
    elif style == ConfigurationStyle.TRIGGER:
        await async_setup_trigger_format(
            hass,
            count,
            {
                "name": "test_template_light",
                **OPTIMISTIC_ON_OFF_LIGHT_CONFIG,
                "state": "{{ 1 == 1 }}",
                **common,
                "temperature": "{{200}}",
            },
        )


@pytest.fixture
async def setup_light_with_transition_template(
    hass: HomeAssistant,
    count: int,
    style: ConfigurationStyle,
    transition_template: str,
) -> None:
    """Do setup of light that uses mireds."""
    common = {
        "set_effect": {
            "service": "test.automation",
            "data_template": {
                "entity_id": "test.test_state",
                "effect": "{{effect}}",
            },
        },
    }
    if style == ConfigurationStyle.LEGACY:
        await async_setup_legacy_format(
            hass,
            count,
            {
                "test_template_light": {
                    **OPTIMISTIC_COLOR_TEMP_LIGHT_CONFIG,
                    "value_template": "{{ 1 == 1 }}",
                    **common,
                    "effect_list_template": "{{ ['Disco', 'Police'] }}",
                    "effect_template": "{{ None }}",
                    "supports_transition_template": transition_template,
                }
            },
        )
    elif style == ConfigurationStyle.MODERN:
        await async_setup_modern_format(
            hass,
            count,
            {
                "name": "test_template_light",
                **OPTIMISTIC_COLOR_TEMP_LIGHT_CONFIG,
                "state": "{{ 1 == 1 }}",
                **common,
                "effect_list": "{{ ['Disco', 'Police'] }}",
                "effect": "{{ None }}",
                "supports_transition": transition_template,
            },
        )
    elif style == ConfigurationStyle.TRIGGER:
        await async_setup_trigger_format(
            hass,
            count,
            {
                "name": "test_template_light",
                **OPTIMISTIC_COLOR_TEMP_LIGHT_CONFIG,
                "state": "{{ 1 == 1 }}",
                **common,
                "effect_list": "{{ ['Disco', 'Police'] }}",
                "effect": "{{ None }}",
                "supports_transition": transition_template,
            },
        )


@pytest.mark.parametrize("count", [1])
@pytest.mark.parametrize(
    ("supported_features", "supported_color_modes"),
    [(0, [ColorMode.BRIGHTNESS])],
)
@pytest.mark.parametrize(
    ("style", "expected_state"),
    [
        (ConfigurationStyle.LEGACY, STATE_OFF),
        (ConfigurationStyle.MODERN, STATE_OFF),
        (ConfigurationStyle.TRIGGER, STATE_UNKNOWN),
    ],
)
@pytest.mark.parametrize("state_template", ["{{states.test['big.fat...']}}"])
async def test_template_state_invalid(
    hass: HomeAssistant,
    supported_features,
    supported_color_modes,
    expected_state,
    setup_state_light,
) -> None:
    """Test template state with render error."""
    state = hass.states.get("light.test_template_light")
    assert state.state == expected_state
    assert state.attributes["color_mode"] is None
    assert state.attributes["supported_color_modes"] == supported_color_modes
    assert state.attributes["supported_features"] == supported_features


@pytest.mark.parametrize("count", [1])
@pytest.mark.parametrize(
    "style",
    [
        ConfigurationStyle.LEGACY,
        ConfigurationStyle.MODERN,
        ConfigurationStyle.TRIGGER,
    ],
)
@pytest.mark.parametrize("state_template", ["{{ states.light.test_state.state }}"])
async def test_template_state_text(hass: HomeAssistant, setup_state_light) -> None:
    """Test the state text of a template."""
    set_state = STATE_ON
    hass.states.async_set("light.test_state", set_state)
    await hass.async_block_till_done()
    state = hass.states.get("light.test_template_light")
    assert state.state == set_state
    assert state.attributes["color_mode"] == ColorMode.BRIGHTNESS
    assert state.attributes["supported_color_modes"] == [ColorMode.BRIGHTNESS]
    assert state.attributes["supported_features"] == 0

    set_state = STATE_OFF
    hass.states.async_set("light.test_state", set_state)
    await hass.async_block_till_done()
    state = hass.states.get("light.test_template_light")
    assert state.state == set_state
    assert state.attributes["color_mode"] is None
    assert state.attributes["supported_color_modes"] == [ColorMode.BRIGHTNESS]
    assert state.attributes["supported_features"] == 0


@pytest.mark.parametrize("count", [1])
@pytest.mark.parametrize(
    "style",
    [
        ConfigurationStyle.LEGACY,
        ConfigurationStyle.MODERN,
        ConfigurationStyle.TRIGGER,
    ],
)
@pytest.mark.parametrize(
    ("state_template", "expected_state", "expected_color_mode"),
    [
        (
            "{{ 1 == 1 }}",
            STATE_ON,
            ColorMode.BRIGHTNESS,
        ),
        (
            "{{ 1 == 2 }}",
            STATE_OFF,
            None,
        ),
    ],
)
async def test_template_state_boolean(
    hass: HomeAssistant,
    expected_color_mode,
    expected_state,
    style,
    setup_state_light,
) -> None:
    """Test the setting of the state with boolean on."""
    if style == ConfigurationStyle.TRIGGER:
        hass.states.async_set("light.test_state", expected_state)
        await hass.async_block_till_done()

    state = hass.states.get("light.test_template_light")
    assert state.state == expected_state
    assert state.attributes.get("color_mode") == expected_color_mode
    assert state.attributes["supported_color_modes"] == [ColorMode.BRIGHTNESS]
    assert state.attributes["supported_features"] == 0


@pytest.mark.parametrize("count", [0])
@pytest.mark.parametrize(
    ("light_config", "style"),
    [
        (
            {
                "test_template_light": {
                    **OPTIMISTIC_BRIGHTNESS_LIGHT_CONFIG,
                    "value_template": "{%- if false -%}",
                }
            },
            ConfigurationStyle.LEGACY,
        ),
        (
            {
                "bad name here": {
                    **OPTIMISTIC_BRIGHTNESS_LIGHT_CONFIG,
                    "value_template": "{{ 1== 1}}",
                }
            },
            ConfigurationStyle.LEGACY,
        ),
        (
            {"test_template_light": "Invalid"},
            ConfigurationStyle.LEGACY,
        ),
        (
            {
                **OPTIMISTIC_BRIGHTNESS_LIGHT_CONFIG,
                "name": "test_template_light",
                "state": "{%- if false -%}",
            },
            ConfigurationStyle.MODERN,
        ),
        (
            {
                **OPTIMISTIC_BRIGHTNESS_LIGHT_CONFIG,
                "name": "test_template_light",
                "state": "{%- if false -%}",
            },
            ConfigurationStyle.TRIGGER,
        ),
    ],
)
async def test_template_config_errors(hass: HomeAssistant, setup_light) -> None:
    """Test template light configuration errors."""
    assert hass.states.async_all("light") == []


@pytest.mark.parametrize(
    ("light_config", "style", "count"),
    [
        (
            {"light_one": {"value_template": "{{ 1== 1}}", **TEST_MISSING_KEY_CONFIG}},
            ConfigurationStyle.LEGACY,
            0,
        ),
        (
            {"name": "light_one", "state": "{{ 1== 1}}", **TEST_MISSING_KEY_CONFIG},
            ConfigurationStyle.MODERN,
            0,
        ),
        (
            {"name": "light_one", "state": "{{ 1== 1}}", **TEST_MISSING_KEY_CONFIG},
            ConfigurationStyle.TRIGGER,
            0,
        ),
    ],
)
async def test_missing_key(hass: HomeAssistant, count, setup_light) -> None:
    """Test missing template."""
    if count:
        assert hass.states.async_all("light") != []
    else:
        assert hass.states.async_all("light") == []


@pytest.mark.parametrize("count", [1])
@pytest.mark.parametrize(
    "style",
    [
        ConfigurationStyle.LEGACY,
        ConfigurationStyle.MODERN,
        ConfigurationStyle.TRIGGER,
    ],
)
@pytest.mark.parametrize("state_template", ["{{ states.light.test_state.state }}"])
async def test_on_action(
    hass: HomeAssistant, setup_state_light, calls: list[ServiceCall]
) -> None:
    """Test on action."""
    hass.states.async_set("light.test_state", STATE_OFF)
    await hass.async_block_till_done()

    state = hass.states.get("light.test_template_light")
    assert state.state == STATE_OFF
    assert state.attributes["color_mode"] is None
    assert state.attributes["supported_color_modes"] == [ColorMode.BRIGHTNESS]
    assert state.attributes["supported_features"] == 0

    await hass.services.async_call(
        light.DOMAIN,
        SERVICE_TURN_ON,
        {ATTR_ENTITY_ID: "light.test_template_light"},
        blocking=True,
    )

    assert len(calls) == 1
    assert calls[-1].data["action"] == "turn_on"
    assert calls[-1].data["caller"] == "light.test_template_light"

    assert state.state == STATE_OFF
    assert state.attributes["color_mode"] is None
    assert state.attributes["supported_color_modes"] == [ColorMode.BRIGHTNESS]
    assert state.attributes["supported_features"] == 0


@pytest.mark.parametrize("count", [1])
@pytest.mark.parametrize(
    ("light_config", "style"),
    [
        (
            {
                "test_template_light": {
                    "value_template": "{{states.light.test_state.state}}",
                    **TEST_ON_ACTION_WITH_TRANSITION_CONFIG,
                    "supports_transition_template": "{{true}}",
                }
            },
            ConfigurationStyle.LEGACY,
        ),
        (
            {
                "name": "test_template_light",
                "state": "{{states.light.test_state.state}}",
                **TEST_ON_ACTION_WITH_TRANSITION_CONFIG,
                "supports_transition": "{{true}}",
            },
            ConfigurationStyle.MODERN,
        ),
        (
            {
                "name": "test_template_light",
                "state": "{{states.light.test_state.state}}",
                **TEST_ON_ACTION_WITH_TRANSITION_CONFIG,
                "supports_transition": "{{true}}",
            },
            ConfigurationStyle.TRIGGER,
        ),
    ],
)
async def test_on_action_with_transition(
    hass: HomeAssistant, setup_light, calls: list[ServiceCall]
) -> None:
    """Test on action with transition."""
    hass.states.async_set("light.test_state", STATE_OFF)
    await hass.async_block_till_done()

    state = hass.states.get("light.test_template_light")
    assert state.state == STATE_OFF
    assert state.attributes["color_mode"] is None
    assert state.attributes["supported_color_modes"] == [ColorMode.BRIGHTNESS]
    assert state.attributes["supported_features"] == LightEntityFeature.TRANSITION

    await hass.services.async_call(
        light.DOMAIN,
        SERVICE_TURN_ON,
        {ATTR_ENTITY_ID: "light.test_template_light", ATTR_TRANSITION: 5},
        blocking=True,
    )

    assert len(calls) == 1
    assert calls[0].data["transition"] == 5

    assert state.state == STATE_OFF
    assert state.attributes["color_mode"] is None
    assert state.attributes["supported_color_modes"] == [ColorMode.BRIGHTNESS]
    assert state.attributes["supported_features"] == LightEntityFeature.TRANSITION


@pytest.mark.parametrize("count", [1])
@pytest.mark.parametrize(
    ("light_config", "style", "initial_state"),
    [
        (
            {
                "test_template_light": {
                    **OPTIMISTIC_BRIGHTNESS_LIGHT_CONFIG,
                }
            },
            ConfigurationStyle.LEGACY,
            STATE_OFF,
        ),
        (
            {
                "name": "test_template_light",
                **OPTIMISTIC_BRIGHTNESS_LIGHT_CONFIG,
            },
            ConfigurationStyle.MODERN,
            STATE_OFF,
        ),
        (
            {
                "name": "test_template_light",
                **OPTIMISTIC_BRIGHTNESS_LIGHT_CONFIG,
            },
            ConfigurationStyle.TRIGGER,
            STATE_UNKNOWN,
        ),
    ],
)
async def test_on_action_optimistic(
    hass: HomeAssistant,
    initial_state: str,
    setup_light,
    calls: list[ServiceCall],
) -> None:
    """Test on action with optimistic state."""
    hass.states.async_set("light.test_state", STATE_OFF)
    await hass.async_block_till_done()

    state = hass.states.get("light.test_template_light")
    assert state.state == initial_state
    assert state.attributes["color_mode"] is None
    assert state.attributes["supported_color_modes"] == [ColorMode.BRIGHTNESS]
    assert state.attributes["supported_features"] == 0

    await hass.services.async_call(
        light.DOMAIN,
        SERVICE_TURN_ON,
        {ATTR_ENTITY_ID: "light.test_template_light"},
        blocking=True,
    )

    state = hass.states.get("light.test_template_light")
    assert len(calls) == 1
    assert calls[-1].data["action"] == "turn_on"
    assert calls[-1].data["caller"] == "light.test_template_light"
    assert state.state == STATE_ON
    assert state.attributes["color_mode"] == ColorMode.BRIGHTNESS
    assert state.attributes["supported_color_modes"] == [ColorMode.BRIGHTNESS]
    assert state.attributes["supported_features"] == 0

    await hass.services.async_call(
        light.DOMAIN,
        SERVICE_TURN_ON,
        {ATTR_ENTITY_ID: "light.test_template_light", ATTR_BRIGHTNESS: 100},
        blocking=True,
    )

    state = hass.states.get("light.test_template_light")
    assert len(calls) == 2
    assert calls[-1].data["action"] == "set_level"
    assert calls[-1].data["brightness"] == 100
    assert calls[-1].data["caller"] == "light.test_template_light"
    assert state.state == STATE_ON
    assert state.attributes["color_mode"] == ColorMode.BRIGHTNESS
    assert state.attributes["supported_color_modes"] == [ColorMode.BRIGHTNESS]
    assert state.attributes["supported_features"] == 0


@pytest.mark.parametrize("count", [1])
@pytest.mark.parametrize(
    "style",
    [
        ConfigurationStyle.LEGACY,
        ConfigurationStyle.MODERN,
        ConfigurationStyle.TRIGGER,
    ],
)
@pytest.mark.parametrize("state_template", ["{{ states.light.test_state.state }}"])
async def test_off_action(
    hass: HomeAssistant, setup_state_light, calls: list[ServiceCall]
) -> None:
    """Test off action."""
    hass.states.async_set("light.test_state", STATE_ON)
    await hass.async_block_till_done()

    state = hass.states.get("light.test_template_light")
    assert state.state == STATE_ON
    assert state.attributes["color_mode"] == ColorMode.BRIGHTNESS
    assert state.attributes["supported_color_modes"] == [ColorMode.BRIGHTNESS]
    assert state.attributes["supported_features"] == 0

    await hass.services.async_call(
        light.DOMAIN,
        SERVICE_TURN_OFF,
        {ATTR_ENTITY_ID: "light.test_template_light"},
        blocking=True,
    )

    assert len(calls) == 1
    assert calls[-1].data["action"] == "turn_off"
    assert calls[-1].data["caller"] == "light.test_template_light"
    assert state.state == STATE_ON
    assert state.attributes["color_mode"] == ColorMode.BRIGHTNESS
    assert state.attributes["supported_color_modes"] == [ColorMode.BRIGHTNESS]
    assert state.attributes["supported_features"] == 0


@pytest.mark.parametrize("count", [(1)])
@pytest.mark.parametrize(
    ("light_config", "style"),
    [
        (
            {
                "test_template_light": {
                    "value_template": "{{states.light.test_state.state}}",
                    **TEST_OFF_ACTION_WITH_TRANSITION_CONFIG,
                    "supports_transition_template": "{{true}}",
                }
            },
            ConfigurationStyle.LEGACY,
        ),
        (
            {
                "name": "test_template_light",
                "state": "{{states.light.test_state.state}}",
                **TEST_OFF_ACTION_WITH_TRANSITION_CONFIG,
                "supports_transition": "{{true}}",
            },
            ConfigurationStyle.MODERN,
        ),
        (
            {
                "name": "test_template_light",
                "state": "{{states.light.test_state.state}}",
                **TEST_OFF_ACTION_WITH_TRANSITION_CONFIG,
                "supports_transition": "{{true}}",
            },
            ConfigurationStyle.TRIGGER,
        ),
    ],
)
async def test_off_action_with_transition(
    hass: HomeAssistant, setup_light, calls: list[ServiceCall]
) -> None:
    """Test off action with transition."""
    hass.states.async_set("light.test_state", STATE_ON)
    await hass.async_block_till_done()

    state = hass.states.get("light.test_template_light")
    assert state.state == STATE_ON
    assert state.attributes["color_mode"] == ColorMode.BRIGHTNESS
    assert state.attributes["supported_color_modes"] == [ColorMode.BRIGHTNESS]
    assert state.attributes["supported_features"] == LightEntityFeature.TRANSITION

    await hass.services.async_call(
        light.DOMAIN,
        SERVICE_TURN_OFF,
        {ATTR_ENTITY_ID: "light.test_template_light", ATTR_TRANSITION: 2},
        blocking=True,
    )

    assert len(calls) == 1
    assert calls[0].data["transition"] == 2
    assert state.state == STATE_ON
    assert state.attributes["color_mode"] == ColorMode.BRIGHTNESS
    assert state.attributes["supported_color_modes"] == [ColorMode.BRIGHTNESS]
    assert state.attributes["supported_features"] == LightEntityFeature.TRANSITION


@pytest.mark.parametrize("count", [1])
@pytest.mark.parametrize(
    ("light_config", "style", "initial_state"),
    [
        (
            {
                "test_template_light": {
                    **OPTIMISTIC_BRIGHTNESS_LIGHT_CONFIG,
                }
            },
            ConfigurationStyle.LEGACY,
            STATE_OFF,
        ),
        (
            {
                "name": "test_template_light",
                **OPTIMISTIC_BRIGHTNESS_LIGHT_CONFIG,
            },
            ConfigurationStyle.MODERN,
            STATE_OFF,
        ),
        (
            {
                "name": "test_template_light",
                **OPTIMISTIC_BRIGHTNESS_LIGHT_CONFIG,
            },
            ConfigurationStyle.TRIGGER,
            STATE_UNKNOWN,
        ),
    ],
)
async def test_off_action_optimistic(
    hass: HomeAssistant, initial_state, setup_light, calls: list[ServiceCall]
) -> None:
    """Test off action with optimistic state."""
    state = hass.states.get("light.test_template_light")
    assert state.state == initial_state
    assert state.attributes["color_mode"] is None
    assert state.attributes["supported_color_modes"] == [ColorMode.BRIGHTNESS]
    assert state.attributes["supported_features"] == 0

    await hass.services.async_call(
        light.DOMAIN,
        SERVICE_TURN_OFF,
        {ATTR_ENTITY_ID: "light.test_template_light"},
        blocking=True,
    )

    assert len(calls) == 1
    state = hass.states.get("light.test_template_light")
    assert state.state == STATE_OFF
    assert state.attributes["color_mode"] is None
    assert state.attributes["supported_color_modes"] == [ColorMode.BRIGHTNESS]
    assert state.attributes["supported_features"] == 0


@pytest.mark.parametrize("count", [1])
@pytest.mark.parametrize(
    "style",
    [
        ConfigurationStyle.LEGACY,
        ConfigurationStyle.MODERN,
        ConfigurationStyle.TRIGGER,
    ],
)
@pytest.mark.parametrize("state_template", ["{{1 == 1}}"])
async def test_level_action_no_template(
    hass: HomeAssistant,
    setup_state_light,
    calls: list[ServiceCall],
) -> None:
    """Test setting brightness with optimistic template."""
    state = hass.states.get("light.test_template_light")
    assert state.attributes.get("brightness") is None

    await hass.services.async_call(
        light.DOMAIN,
        SERVICE_TURN_ON,
        {ATTR_ENTITY_ID: "light.test_template_light", ATTR_BRIGHTNESS: 124},
        blocking=True,
    )

    assert len(calls) == 1
    assert calls[-1].data["action"] == "set_level"
    assert calls[-1].data["brightness"] == 124
    assert calls[-1].data["caller"] == "light.test_template_light"

    state = hass.states.get("light.test_template_light")
    assert state.state == STATE_ON
    assert state.attributes["brightness"] == 124
    assert state.attributes["color_mode"] == ColorMode.BRIGHTNESS
    assert state.attributes["supported_color_modes"] == [ColorMode.BRIGHTNESS]
    assert state.attributes["supported_features"] == 0


@pytest.mark.parametrize(
    ("count", "extra_config"), [(1, OPTIMISTIC_BRIGHTNESS_LIGHT_CONFIG)]
)
@pytest.mark.parametrize(
    ("style", "attribute"),
    [
        (ConfigurationStyle.LEGACY, "level_template"),
        (ConfigurationStyle.MODERN, "level"),
        (ConfigurationStyle.TRIGGER, "level"),
    ],
)
@pytest.mark.parametrize(
    ("expected_level", "attribute_template", "expected_color_mode"),
    [
        (255, "{{255}}", ColorMode.BRIGHTNESS),
        (None, "{{256}}", ColorMode.BRIGHTNESS),
        (None, "{{x - 12}}", ColorMode.BRIGHTNESS),
        (None, "{{ none }}", ColorMode.BRIGHTNESS),
        (None, "", ColorMode.BRIGHTNESS),
        (
            None,
            "{{ state_attr('light.nolight', 'brightness') }}",
            ColorMode.BRIGHTNESS,
        ),
        (None, "{{'one'}}", ColorMode.BRIGHTNESS),
    ],
)
async def test_level_template(
    hass: HomeAssistant,
    style: ConfigurationStyle,
    expected_level: Any,
    expected_color_mode: ColorMode,
    setup_single_attribute_light,
) -> None:
    """Test the template for the level."""
    if style == ConfigurationStyle.TRIGGER:
        hass.states.async_set("light.test_state", STATE_ON)
        await hass.async_block_till_done()

    state = hass.states.get("light.test_template_light")
    assert state.attributes.get("brightness") == expected_level
    assert state.state == STATE_ON

    assert state.attributes["color_mode"] == expected_color_mode
    assert state.attributes["supported_color_modes"] == [ColorMode.BRIGHTNESS]
    assert state.attributes["supported_features"] == 0


@pytest.mark.parametrize(
    ("count", "extra_config"), [(1, OPTIMISTIC_COLOR_TEMP_LIGHT_CONFIG)]
)
@pytest.mark.parametrize(
    ("style", "attribute"),
    [
        (ConfigurationStyle.LEGACY, "temperature_template"),
        (ConfigurationStyle.MODERN, "temperature"),
        (ConfigurationStyle.TRIGGER, "temperature"),
    ],
)
@pytest.mark.parametrize(
    ("expected_temp", "attribute_template", "expected_color_mode"),
    [
        (500, "{{500}}", ColorMode.COLOR_TEMP),
        (None, "{{501}}", ColorMode.COLOR_TEMP),
        (None, "{{x - 12}}", ColorMode.COLOR_TEMP),
        (None, "None", ColorMode.COLOR_TEMP),
        (None, "{{ none }}", ColorMode.COLOR_TEMP),
        (None, "", ColorMode.COLOR_TEMP),
        (None, "{{ 'one' }}", ColorMode.COLOR_TEMP),
    ],
)
async def test_temperature_template(
    hass: HomeAssistant,
    style: ConfigurationStyle,
    expected_temp: Any,
    expected_color_mode: ColorMode,
    setup_single_attribute_light,
) -> None:
    """Test the template for the temperature."""
    if style == ConfigurationStyle.TRIGGER:
        hass.states.async_set("light.test_state", STATE_ON)
        await hass.async_block_till_done()

    state = hass.states.get("light.test_template_light")
    assert state.attributes.get("color_temp") == expected_temp
    assert state.state == STATE_ON
    assert state.attributes.get("color_mode") == expected_color_mode
    assert state.attributes["supported_color_modes"] == [ColorMode.COLOR_TEMP]
    assert state.attributes["supported_features"] == 0


@pytest.mark.parametrize(
    ("count", "extra_config"), [(1, OPTIMISTIC_COLOR_TEMP_LIGHT_CONFIG)]
)
@pytest.mark.parametrize(
    "style",
    [
        ConfigurationStyle.LEGACY,
        ConfigurationStyle.MODERN,
        ConfigurationStyle.TRIGGER,
    ],
)
async def test_temperature_action_no_template(
    hass: HomeAssistant,
    setup_single_action_light,
    calls: list[ServiceCall],
) -> None:
    """Test setting temperature with optimistic template."""
    state = hass.states.get("light.test_template_light")
    assert state.attributes.get("color_template") is None

    await hass.services.async_call(
        light.DOMAIN,
        SERVICE_TURN_ON,
        {ATTR_ENTITY_ID: "light.test_template_light", ATTR_COLOR_TEMP_KELVIN: 2898},
        blocking=True,
    )

    assert len(calls) == 1
    assert calls[-1].data["action"] == "set_temperature"
    assert calls[-1].data["caller"] == "light.test_template_light"
    assert calls[-1].data["color_temp"] == 345

    state = hass.states.get("light.test_template_light")
    assert state is not None
    assert state.attributes.get("color_temp") == 345
    assert state.state == STATE_ON
    assert state.attributes["color_mode"] == ColorMode.COLOR_TEMP
    assert state.attributes["supported_color_modes"] == [ColorMode.COLOR_TEMP]
    assert state.attributes["supported_features"] == 0


@pytest.mark.parametrize("count", [1])
@pytest.mark.parametrize(
    ("light_config", "style", "entity_id"),
    [
        (
            {
                "test_template_light": {
                    **OPTIMISTIC_BRIGHTNESS_LIGHT_CONFIG,
                    "friendly_name": "Template light",
                    "value_template": "{{ 1 == 1 }}",
                }
            },
            ConfigurationStyle.LEGACY,
            "light.test_template_light",
        ),
        (
            {
                **OPTIMISTIC_BRIGHTNESS_LIGHT_CONFIG,
                "name": "Template light",
                "state": "{{ 1 == 1 }}",
            },
            ConfigurationStyle.MODERN,
            "light.template_light",
        ),
        (
            {
                **OPTIMISTIC_BRIGHTNESS_LIGHT_CONFIG,
                "name": "Template light",
                "state": "{{ 1 == 1 }}",
            },
            ConfigurationStyle.TRIGGER,
            "light.template_light",
        ),
    ],
)
async def test_friendly_name(hass: HomeAssistant, entity_id: str, setup_light) -> None:
    """Test the accessibility of the friendly_name attribute."""

    state = hass.states.get(entity_id)
    assert state is not None

    assert state.attributes.get("friendly_name") == "Template light"


@pytest.mark.parametrize(
    ("count", "extra_config"), [(1, OPTIMISTIC_BRIGHTNESS_LIGHT_CONFIG)]
)
@pytest.mark.parametrize(
    ("style", "attribute"),
    [
        (ConfigurationStyle.LEGACY, "icon_template"),
        (ConfigurationStyle.MODERN, "icon"),
        (ConfigurationStyle.TRIGGER, "icon"),
    ],
)
@pytest.mark.parametrize(
    "attribute_template", ["{% if states.light.test_state.state %}mdi:check{% endif %}"]
)
async def test_icon_template(hass: HomeAssistant, setup_single_attribute_light) -> None:
    """Test icon template."""
    state = hass.states.get("light.test_template_light")
    assert state.attributes.get("icon") in ("", None)

    state = hass.states.async_set("light.test_state", STATE_ON)
    await hass.async_block_till_done()

    state = hass.states.get("light.test_template_light")

    assert state.attributes["icon"] == "mdi:check"


@pytest.mark.parametrize(
    ("count", "extra_config"), [(1, OPTIMISTIC_BRIGHTNESS_LIGHT_CONFIG)]
)
@pytest.mark.parametrize(
    ("style", "attribute"),
    [
        (ConfigurationStyle.LEGACY, "entity_picture_template"),
        (ConfigurationStyle.MODERN, "picture"),
        (ConfigurationStyle.TRIGGER, "picture"),
    ],
)
@pytest.mark.parametrize(
    "attribute_template",
    ["{% if states.light.test_state.state %}/local/light.png{% endif %}"],
)
async def test_entity_picture_template(
    hass: HomeAssistant, setup_single_attribute_light
) -> None:
    """Test entity_picture template."""
    state = hass.states.get("light.test_template_light")
    assert state.attributes.get("entity_picture") in ("", None)

    state = hass.states.async_set("light.test_state", STATE_ON)
    await hass.async_block_till_done()

    state = hass.states.get("light.test_template_light")

    assert state.attributes["entity_picture"] == "/local/light.png"


@pytest.mark.parametrize(
    ("count", "extra_config"),
    [
        (1, OPTIMISTIC_LEGACY_COLOR_LIGHT_CONFIG),
    ],
)
@pytest.mark.parametrize(
    "style",
    [
        ConfigurationStyle.LEGACY,
    ],
)
async def test_legacy_color_action_no_template(
    hass: HomeAssistant,
    setup_single_action_light,
    calls: list[ServiceCall],
) -> None:
    """Test setting color with optimistic template."""
    state = hass.states.get("light.test_template_light")
    assert state.attributes.get("hs_color") is None

    await hass.services.async_call(
        light.DOMAIN,
        SERVICE_TURN_ON,
        {ATTR_ENTITY_ID: "light.test_template_light", ATTR_HS_COLOR: (40, 50)},
        blocking=True,
    )

    assert len(calls) == 1
    assert calls[-1].data["action"] == "set_color"
    assert calls[-1].data["caller"] == "light.test_template_light"
    assert calls[-1].data["h"] == 40
    assert calls[-1].data["s"] == 50

    state = hass.states.get("light.test_template_light")
    assert state.state == STATE_ON
    assert state.attributes["color_mode"] == ColorMode.HS
    assert state.attributes.get("hs_color") == (40, 50)
    assert state.attributes["supported_color_modes"] == [ColorMode.HS]
    assert state.attributes["supported_features"] == 0


@pytest.mark.parametrize(
    ("count", "extra_config"),
    [
        (1, OPTIMISTIC_HS_COLOR_LIGHT_CONFIG),
    ],
)
@pytest.mark.parametrize(
    "style",
    [
        ConfigurationStyle.LEGACY,
        ConfigurationStyle.MODERN,
        ConfigurationStyle.TRIGGER,
    ],
)
async def test_hs_color_action_no_template(
    hass: HomeAssistant,
    setup_single_action_light,
    calls: list[ServiceCall],
) -> None:
    """Test setting color with optimistic template."""
    state = hass.states.get("light.test_template_light")
    assert state.attributes.get("hs_color") is None

    await hass.services.async_call(
        light.DOMAIN,
        SERVICE_TURN_ON,
        {ATTR_ENTITY_ID: "light.test_template_light", ATTR_HS_COLOR: (40, 50)},
        blocking=True,
    )

    assert len(calls) == 1
    assert calls[-1].data["action"] == "set_hs"
    assert calls[-1].data["caller"] == "light.test_template_light"
    assert calls[-1].data["h"] == 40
    assert calls[-1].data["s"] == 50

    state = hass.states.get("light.test_template_light")
    assert state.state == STATE_ON
    assert state.attributes["color_mode"] == ColorMode.HS
    assert state.attributes.get("hs_color") == (40, 50)
    assert state.attributes["supported_color_modes"] == [ColorMode.HS]
    assert state.attributes["supported_features"] == 0


@pytest.mark.parametrize(
    ("count", "extra_config"),
    [(1, OPTIMISTIC_RGB_COLOR_LIGHT_CONFIG)],
)
@pytest.mark.parametrize(
    "style",
    [
        ConfigurationStyle.LEGACY,
        ConfigurationStyle.MODERN,
        ConfigurationStyle.TRIGGER,
    ],
)
async def test_rgb_color_action_no_template(
    hass: HomeAssistant,
    setup_single_action_light,
    calls: list[ServiceCall],
) -> None:
    """Test setting rgb color with optimistic template."""
    state = hass.states.get("light.test_template_light")
    assert state.attributes.get("rgb_color") is None

    await hass.services.async_call(
        light.DOMAIN,
        SERVICE_TURN_ON,
        {ATTR_ENTITY_ID: "light.test_template_light", ATTR_RGB_COLOR: (160, 78, 192)},
        blocking=True,
    )

    assert len(calls) == 1
    assert calls[-1].data["action"] == "set_rgb"
    assert calls[-1].data["caller"] == "light.test_template_light"
    assert calls[-1].data["r"] == 160
    assert calls[-1].data["g"] == 78
    assert calls[-1].data["b"] == 192

    state = hass.states.get("light.test_template_light")
    assert state.state == STATE_ON
    assert state.attributes["color_mode"] == ColorMode.RGB
    assert state.attributes.get("rgb_color") == (160, 78, 192)
    assert state.attributes["supported_color_modes"] == [ColorMode.RGB]
    assert state.attributes["supported_features"] == 0


@pytest.mark.parametrize(
    ("count", "extra_config"),
    [(1, OPTIMISTIC_RGBW_COLOR_LIGHT_CONFIG)],
)
@pytest.mark.parametrize(
    "style",
    [
        ConfigurationStyle.LEGACY,
        ConfigurationStyle.MODERN,
        ConfigurationStyle.TRIGGER,
    ],
)
async def test_rgbw_color_action_no_template(
    hass: HomeAssistant,
    setup_single_action_light,
    calls: list[ServiceCall],
) -> None:
    """Test setting rgbw color with optimistic template."""
    state = hass.states.get("light.test_template_light")
    assert state.attributes.get("rgbw_color") is None

    await hass.services.async_call(
        light.DOMAIN,
        SERVICE_TURN_ON,
        {
            ATTR_ENTITY_ID: "light.test_template_light",
            ATTR_RGBW_COLOR: (160, 78, 192, 25),
        },
        blocking=True,
    )

    assert len(calls) == 1
    assert calls[-1].data["action"] == "set_rgbw"
    assert calls[-1].data["caller"] == "light.test_template_light"
    assert calls[-1].data["r"] == 160
    assert calls[-1].data["g"] == 78
    assert calls[-1].data["b"] == 192
    assert calls[-1].data["w"] == 25

    state = hass.states.get("light.test_template_light")
    assert state.state == STATE_ON
    assert state.attributes["color_mode"] == ColorMode.RGBW
    assert state.attributes.get("rgbw_color") == (160, 78, 192, 25)
    assert state.attributes["supported_color_modes"] == [ColorMode.RGBW]
    assert state.attributes["supported_features"] == 0


@pytest.mark.parametrize(
    ("count", "extra_config"),
    [(1, OPTIMISTIC_RGBWW_COLOR_LIGHT_CONFIG)],
)
@pytest.mark.parametrize(
    "style",
    [
        ConfigurationStyle.LEGACY,
        ConfigurationStyle.MODERN,
        ConfigurationStyle.TRIGGER,
    ],
)
async def test_rgbww_color_action_no_template(
    hass: HomeAssistant,
    setup_single_action_light,
    calls: list[ServiceCall],
) -> None:
    """Test setting rgbww color with optimistic template."""
    state = hass.states.get("light.test_template_light")
    assert state.attributes.get("rgbww_color") is None

    await hass.services.async_call(
        light.DOMAIN,
        SERVICE_TURN_ON,
        {
            ATTR_ENTITY_ID: "light.test_template_light",
            ATTR_RGBWW_COLOR: (160, 78, 192, 25, 55),
        },
        blocking=True,
    )

    assert len(calls) == 1
    assert calls[-1].data["action"] == "set_rgbww"
    assert calls[-1].data["caller"] == "light.test_template_light"
    assert calls[-1].data["r"] == 160
    assert calls[-1].data["g"] == 78
    assert calls[-1].data["b"] == 192
    assert calls[-1].data["cw"] == 25
    assert calls[-1].data["ww"] == 55

    state = hass.states.get("light.test_template_light")
    assert state.state == STATE_ON
    assert state.attributes["color_mode"] == ColorMode.RGBWW
    assert state.attributes.get("rgbww_color") == (160, 78, 192, 25, 55)
    assert state.attributes["supported_color_modes"] == [ColorMode.RGBWW]
    assert state.attributes["supported_features"] == 0


@pytest.mark.parametrize("count", [1])
@pytest.mark.parametrize(
    ("expected_hs", "color_template", "expected_color_mode"),
    [
        ((360, 100), "{{(360, 100)}}", ColorMode.HS),
        ((359.9, 99.9), "{{(359.9, 99.9)}}", ColorMode.HS),
        (None, "{{(361, 100)}}", ColorMode.HS),
        (None, "{{(360, 101)}}", ColorMode.HS),
        (None, "[{{(360)}},{{null}}]", ColorMode.HS),
        (None, "{{x - 12}}", ColorMode.HS),
        (None, "", ColorMode.HS),
        (None, "{{ none }}", ColorMode.HS),
        (None, "{{('one','two')}}", ColorMode.HS),
    ],
)
async def test_legacy_color_template(
    hass: HomeAssistant,
    expected_hs: tuple[float, float] | None,
    expected_color_mode: ColorMode,
    count: int,
    color_template: str,
) -> None:
    """Test the template for the color."""
    light_config = {
        "test_template_light": {
            **OPTIMISTIC_LEGACY_COLOR_LIGHT_CONFIG,
            "value_template": "{{ 1 == 1 }}",
            "color_template": color_template,
        }
    }
    await async_setup_legacy_format(hass, count, light_config)
    state = hass.states.get("light.test_template_light")
    assert state.attributes.get("hs_color") == expected_hs
    assert state.state == STATE_ON
    assert state.attributes["color_mode"] == expected_color_mode
    assert state.attributes["supported_color_modes"] == [ColorMode.HS]
    assert state.attributes["supported_features"] == 0


@pytest.mark.parametrize(
    ("count", "extra_config"), [(1, OPTIMISTIC_HS_COLOR_LIGHT_CONFIG)]
)
@pytest.mark.parametrize(
    ("style", "attribute"),
    [
        (ConfigurationStyle.LEGACY, "hs_template"),
        (ConfigurationStyle.MODERN, "hs"),
        (ConfigurationStyle.TRIGGER, "hs"),
    ],
)
@pytest.mark.parametrize(
    ("expected_hs", "attribute_template", "expected_color_mode"),
    [
        ((360, 100), "{{(360, 100)}}", ColorMode.HS),
        ((360, 100), "(360, 100)", ColorMode.HS),
        ((359.9, 99.9), "{{(359.9, 99.9)}}", ColorMode.HS),
        (None, "{{(361, 100)}}", ColorMode.HS),
        (None, "{{(360, 101)}}", ColorMode.HS),
        (None, "[{{(360)}},{{null}}]", ColorMode.HS),
        (None, "{{x - 12}}", ColorMode.HS),
        (None, "", ColorMode.HS),
        (None, "{{ none }}", ColorMode.HS),
        (None, "{{('one','two')}}", ColorMode.HS),
    ],
)
async def test_hs_template(
    hass: HomeAssistant,
    expected_hs,
    expected_color_mode,
    style: ConfigurationStyle,
    setup_single_attribute_light,
) -> None:
    """Test the template for the color."""
    if style == ConfigurationStyle.TRIGGER:
        hass.states.async_set("light.test_state", STATE_ON)
        await hass.async_block_till_done()

    state = hass.states.get("light.test_template_light")
    assert state.attributes.get("hs_color") == expected_hs
    assert state.state == STATE_ON
    assert state.attributes["color_mode"] == expected_color_mode
    assert state.attributes["supported_color_modes"] == [ColorMode.HS]
    assert state.attributes["supported_features"] == 0


@pytest.mark.parametrize(
    ("count", "extra_config"), [(1, OPTIMISTIC_RGB_COLOR_LIGHT_CONFIG)]
)
@pytest.mark.parametrize(
    ("style", "attribute"),
    [
        (ConfigurationStyle.LEGACY, "rgb_template"),
        (ConfigurationStyle.MODERN, "rgb"),
        (ConfigurationStyle.TRIGGER, "rgb"),
    ],
)
@pytest.mark.parametrize(
    ("expected_rgb", "attribute_template", "expected_color_mode"),
    [
        ((160, 78, 192), "{{(160, 78, 192)}}", ColorMode.RGB),
        ((160, 78, 192), "{{[160, 78, 192]}}", ColorMode.RGB),
        ((160, 78, 192), "(160, 78, 192)", ColorMode.RGB),
        ((159, 77, 191), "{{(159.9, 77.9, 191.9)}}", ColorMode.RGB),
        (None, "{{(256, 100, 100)}}", ColorMode.RGB),
        (None, "{{(100, 256, 100)}}", ColorMode.RGB),
        (None, "{{(100, 100, 256)}}", ColorMode.RGB),
        (None, "{{x - 12}}", ColorMode.RGB),
        (None, "", ColorMode.RGB),
        (None, "{{ none }}", ColorMode.RGB),
        (None, "{{('one','two','tree')}}", ColorMode.RGB),
    ],
)
async def test_rgb_template(
    hass: HomeAssistant,
    expected_rgb,
    expected_color_mode,
    style: ConfigurationStyle,
    setup_single_attribute_light,
) -> None:
    """Test the template for the color."""
    if style == ConfigurationStyle.TRIGGER:
        hass.states.async_set("light.test_state", STATE_ON)
        await hass.async_block_till_done()

    state = hass.states.get("light.test_template_light")
    assert state.attributes.get("rgb_color") == expected_rgb
    assert state.state == STATE_ON
    assert state.attributes["color_mode"] == expected_color_mode
    assert state.attributes["supported_color_modes"] == [ColorMode.RGB]
    assert state.attributes["supported_features"] == 0


@pytest.mark.parametrize(
    ("count", "extra_config"), [(1, OPTIMISTIC_RGBW_COLOR_LIGHT_CONFIG)]
)
@pytest.mark.parametrize(
    ("style", "attribute"),
    [
        (ConfigurationStyle.LEGACY, "rgbw_template"),
        (ConfigurationStyle.MODERN, "rgbw"),
        (ConfigurationStyle.TRIGGER, "rgbw"),
    ],
)
@pytest.mark.parametrize(
    ("expected_rgbw", "attribute_template", "expected_color_mode"),
    [
        ((160, 78, 192, 25), "{{(160, 78, 192, 25)}}", ColorMode.RGBW),
        ((160, 78, 192, 25), "{{[160, 78, 192, 25]}}", ColorMode.RGBW),
        ((160, 78, 192, 25), "(160, 78, 192, 25)", ColorMode.RGBW),
        ((159, 77, 191, 24), "{{(159.9, 77.9, 191.9, 24.9)}}", ColorMode.RGBW),
        (None, "{{(256, 100, 100, 100)}}", ColorMode.RGBW),
        (None, "{{(100, 256, 100, 100)}}", ColorMode.RGBW),
        (None, "{{(100, 100, 256, 100)}}", ColorMode.RGBW),
        (None, "{{(100, 100, 100, 256)}}", ColorMode.RGBW),
        (None, "{{x - 12}}", ColorMode.RGBW),
        (None, "", ColorMode.RGBW),
        (None, "{{ none }}", ColorMode.RGBW),
        (None, "{{('one','two','tree','four')}}", ColorMode.RGBW),
    ],
)
async def test_rgbw_template(
    hass: HomeAssistant,
    expected_rgbw,
    expected_color_mode,
    style: ConfigurationStyle,
    setup_single_attribute_light,
) -> None:
    """Test the template for the color."""
    if style == ConfigurationStyle.TRIGGER:
        hass.states.async_set("light.test_state", STATE_ON)
        await hass.async_block_till_done()

    state = hass.states.get("light.test_template_light")
    assert state.attributes.get("rgbw_color") == expected_rgbw
    assert state.state == STATE_ON
    assert state.attributes["color_mode"] == expected_color_mode
    assert state.attributes["supported_color_modes"] == [ColorMode.RGBW]
    assert state.attributes["supported_features"] == 0


@pytest.mark.parametrize(
    ("count", "extra_config"), [(1, OPTIMISTIC_RGBWW_COLOR_LIGHT_CONFIG)]
)
@pytest.mark.parametrize(
    ("style", "attribute"),
    [
        (ConfigurationStyle.LEGACY, "rgbww_template"),
        (ConfigurationStyle.MODERN, "rgbww"),
        (ConfigurationStyle.TRIGGER, "rgbww"),
    ],
)
@pytest.mark.parametrize(
    ("expected_rgbww", "attribute_template", "expected_color_mode"),
    [
        ((160, 78, 192, 25, 55), "{{(160, 78, 192, 25, 55)}}", ColorMode.RGBWW),
        ((160, 78, 192, 25, 55), "(160, 78, 192, 25, 55)", ColorMode.RGBWW),
        ((160, 78, 192, 25, 55), "{{[160, 78, 192, 25, 55]}}", ColorMode.RGBWW),
        (
            (159, 77, 191, 24, 54),
            "{{(159.9, 77.9, 191.9, 24.9, 54.9)}}",
            ColorMode.RGBWW,
        ),
        (None, "{{(256, 100, 100, 100, 100)}}", ColorMode.RGBWW),
        (None, "{{(100, 256, 100, 100, 100)}}", ColorMode.RGBWW),
        (None, "{{(100, 100, 256, 100, 100)}}", ColorMode.RGBWW),
        (None, "{{(100, 100, 100, 256, 100)}}", ColorMode.RGBWW),
        (None, "{{(100, 100, 100, 100, 256)}}", ColorMode.RGBWW),
        (None, "{{x - 12}}", ColorMode.RGBWW),
        (None, "", ColorMode.RGBWW),
        (None, "{{ none }}", ColorMode.RGBWW),
        (None, "{{('one','two','tree','four','five')}}", ColorMode.RGBWW),
    ],
)
async def test_rgbww_template(
    hass: HomeAssistant,
    expected_rgbww,
    expected_color_mode,
    style: ConfigurationStyle,
    setup_single_attribute_light,
) -> None:
    """Test the template for the color."""
    if style == ConfigurationStyle.TRIGGER:
        hass.states.async_set("light.test_state", STATE_ON)
        await hass.async_block_till_done()

    state = hass.states.get("light.test_template_light")
    assert state.attributes.get("rgbww_color") == expected_rgbww
    assert state.state == STATE_ON
    assert state.attributes["color_mode"] == expected_color_mode
    assert state.attributes["supported_color_modes"] == [ColorMode.RGBWW]
    assert state.attributes["supported_features"] == 0


@pytest.mark.parametrize("count", [1])
@pytest.mark.parametrize(
    ("light_config", "style"),
    [
        (
            {
                "test_template_light": {
                    **OPTIMISTIC_ON_OFF_LIGHT_CONFIG,
                    "value_template": "{{1 == 1}}",
                    **TEST_ALL_COLORS_NO_TEMPLATE_CONFIG,
                }
            },
            ConfigurationStyle.LEGACY,
        ),
        (
            {
                "name": "test_template_light",
                **OPTIMISTIC_ON_OFF_LIGHT_CONFIG,
                "state": "{{1 == 1}}",
                **TEST_ALL_COLORS_NO_TEMPLATE_CONFIG,
            },
            ConfigurationStyle.MODERN,
        ),
        (
            {
                "name": "test_template_light",
                **OPTIMISTIC_ON_OFF_LIGHT_CONFIG,
                "state": "{{1 == 1}}",
                **TEST_ALL_COLORS_NO_TEMPLATE_CONFIG,
            },
            ConfigurationStyle.TRIGGER,
        ),
    ],
)
async def test_all_colors_mode_no_template(
    hass: HomeAssistant, setup_light, calls: list[ServiceCall]
) -> None:
    """Test setting color and color temperature with optimistic template."""
    state = hass.states.get("light.test_template_light")
    assert state.attributes.get("hs_color") is None

    # Optimistically set hs color, light should be in hs_color mode
    await hass.services.async_call(
        light.DOMAIN,
        SERVICE_TURN_ON,
        {ATTR_ENTITY_ID: "light.test_template_light", ATTR_HS_COLOR: (40, 50)},
        blocking=True,
    )

    assert len(calls) == 1
    assert calls[-1].data["h"] == 40
    assert calls[-1].data["s"] == 50

    state = hass.states.get("light.test_template_light")
    assert state.attributes["color_mode"] == ColorMode.HS
    assert state.attributes["color_temp"] is None
    assert state.attributes["hs_color"] == (40, 50)
    assert state.attributes["supported_color_modes"] == [
        ColorMode.COLOR_TEMP,
        ColorMode.HS,
        ColorMode.RGB,
        ColorMode.RGBW,
        ColorMode.RGBWW,
    ]
    assert state.attributes["supported_features"] == 0

    # Optimistically set color temp, light should be in color temp mode
    await hass.services.async_call(
        light.DOMAIN,
        SERVICE_TURN_ON,
        {ATTR_ENTITY_ID: "light.test_template_light", ATTR_COLOR_TEMP_KELVIN: 8130},
        blocking=True,
    )

    assert len(calls) == 2
    assert calls[-1].data["color_temp"] == 123

    state = hass.states.get("light.test_template_light")
    assert state.attributes["color_mode"] == ColorMode.COLOR_TEMP
    assert state.attributes["color_temp"] == 123
    assert "hs_color" in state.attributes  # Color temp represented as hs_color
    assert state.attributes["supported_color_modes"] == [
        ColorMode.COLOR_TEMP,
        ColorMode.HS,
        ColorMode.RGB,
        ColorMode.RGBW,
        ColorMode.RGBWW,
    ]
    assert state.attributes["supported_features"] == 0

    # Optimistically set rgb color, light should be in rgb_color mode
    await hass.services.async_call(
        light.DOMAIN,
        SERVICE_TURN_ON,
        {ATTR_ENTITY_ID: "light.test_template_light", ATTR_RGB_COLOR: (160, 78, 192)},
        blocking=True,
    )

    assert len(calls) == 3
    assert calls[-1].data["r"] == 160
    assert calls[-1].data["g"] == 78
    assert calls[-1].data["b"] == 192

    state = hass.states.get("light.test_template_light")
    assert state.attributes["color_mode"] == ColorMode.RGB
    assert state.attributes["color_temp"] is None
    assert state.attributes["rgb_color"] == (160, 78, 192)
    assert state.attributes["supported_color_modes"] == [
        ColorMode.COLOR_TEMP,
        ColorMode.HS,
        ColorMode.RGB,
        ColorMode.RGBW,
        ColorMode.RGBWW,
    ]
    assert state.attributes["supported_features"] == 0

    # Optimistically set rgbw color, light should be in rgb_color mode
    await hass.services.async_call(
        light.DOMAIN,
        SERVICE_TURN_ON,
        {
            ATTR_ENTITY_ID: "light.test_template_light",
            ATTR_RGBW_COLOR: (160, 78, 192, 25),
        },
        blocking=True,
    )

    assert len(calls) == 4
    assert calls[-1].data["r"] == 160
    assert calls[-1].data["g"] == 78
    assert calls[-1].data["b"] == 192
    assert calls[-1].data["w"] == 25

    state = hass.states.get("light.test_template_light")
    assert state.attributes["color_mode"] == ColorMode.RGBW
    assert state.attributes["color_temp"] is None
    assert state.attributes["rgbw_color"] == (160, 78, 192, 25)
    assert state.attributes["supported_color_modes"] == [
        ColorMode.COLOR_TEMP,
        ColorMode.HS,
        ColorMode.RGB,
        ColorMode.RGBW,
        ColorMode.RGBWW,
    ]
    assert state.attributes["supported_features"] == 0

    # Optimistically set rgbww color, light should be in rgb_color mode
    await hass.services.async_call(
        light.DOMAIN,
        SERVICE_TURN_ON,
        {
            ATTR_ENTITY_ID: "light.test_template_light",
            ATTR_RGBWW_COLOR: (160, 78, 192, 25, 55),
        },
        blocking=True,
    )

    assert len(calls) == 5
    assert calls[-1].data["r"] == 160
    assert calls[-1].data["g"] == 78
    assert calls[-1].data["b"] == 192
    assert calls[-1].data["cw"] == 25
    assert calls[-1].data["ww"] == 55

    state = hass.states.get("light.test_template_light")
    assert state.attributes["color_mode"] == ColorMode.RGBWW
    assert state.attributes["color_temp"] is None
    assert state.attributes["rgbww_color"] == (160, 78, 192, 25, 55)
    assert state.attributes["supported_color_modes"] == [
        ColorMode.COLOR_TEMP,
        ColorMode.HS,
        ColorMode.RGB,
        ColorMode.RGBW,
        ColorMode.RGBWW,
    ]
    assert state.attributes["supported_features"] == 0

    # Optimistically set hs color, light should again be in hs_color mode
    await hass.services.async_call(
        light.DOMAIN,
        SERVICE_TURN_ON,
        {ATTR_ENTITY_ID: "light.test_template_light", ATTR_HS_COLOR: (10, 20)},
        blocking=True,
    )

    assert len(calls) == 6
    assert calls[-1].data["h"] == 10
    assert calls[-1].data["s"] == 20

    state = hass.states.get("light.test_template_light")
    assert state.attributes["color_mode"] == ColorMode.HS
    assert state.attributes["color_temp"] is None
    assert state.attributes["hs_color"] == (10, 20)
    assert state.attributes["supported_color_modes"] == [
        ColorMode.COLOR_TEMP,
        ColorMode.HS,
        ColorMode.RGB,
        ColorMode.RGBW,
        ColorMode.RGBWW,
    ]
    assert state.attributes["supported_features"] == 0

    # Optimistically set color temp, light should again be in color temp mode
    await hass.services.async_call(
        light.DOMAIN,
        SERVICE_TURN_ON,
        {ATTR_ENTITY_ID: "light.test_template_light", ATTR_COLOR_TEMP_KELVIN: 4273},
        blocking=True,
    )

    assert len(calls) == 7
    assert calls[-1].data["color_temp"] == 234

    state = hass.states.get("light.test_template_light")
    assert state.attributes["color_mode"] == ColorMode.COLOR_TEMP
    assert state.attributes["color_temp"] == 234
    assert "hs_color" in state.attributes  # Color temp represented as hs_color
    assert state.attributes["supported_color_modes"] == [
        ColorMode.COLOR_TEMP,
        ColorMode.HS,
        ColorMode.RGB,
        ColorMode.RGBW,
        ColorMode.RGBWW,
    ]
    assert state.attributes["supported_features"] == 0


@pytest.mark.parametrize("count", [1])
@pytest.mark.parametrize(
    "style",
    [ConfigurationStyle.LEGACY, ConfigurationStyle.MODERN, ConfigurationStyle.TRIGGER],
)
@pytest.mark.parametrize(
    ("effect_list_template", "effect_template", "effect", "expected"),
    [
        ("{{ ['Disco', 'Police'] }}", "{{ 'Disco' }}", "Disco", "Disco"),
        ("{{ ['Disco', 'Police'] }}", "{{ 'None' }}", "RGB", None),
    ],
)
async def test_effect_action(
    hass: HomeAssistant,
    effect: str,
    expected: Any,
    style: ConfigurationStyle,
    setup_light_with_effects,
    calls: list[ServiceCall],
) -> None:
    """Test setting valid effect with template."""

    if style == ConfigurationStyle.TRIGGER:
        # Ensures the trigger template entity updates
        hass.states.async_set("light.test_state", STATE_ON)
        await hass.async_block_till_done()

    state = hass.states.get("light.test_template_light")
    assert state is not None

    await hass.services.async_call(
        light.DOMAIN,
        SERVICE_TURN_ON,
        {ATTR_ENTITY_ID: "light.test_template_light", ATTR_EFFECT: effect},
        blocking=True,
    )

    assert len(calls) == 1
    assert calls[-1].data["action"] == "set_effect"
    assert calls[-1].data["caller"] == "light.test_template_light"
    assert calls[-1].data["effect"] == effect

    state = hass.states.get("light.test_template_light")
    assert state is not None
    assert state.attributes.get("effect") == expected


@pytest.mark.parametrize(("count", "effect_template"), [(1, "{{ None }}")])
@pytest.mark.parametrize(
    "style",
    [ConfigurationStyle.LEGACY, ConfigurationStyle.MODERN, ConfigurationStyle.TRIGGER],
)
@pytest.mark.parametrize(
    ("expected_effect_list", "effect_list_template"),
    [
        (
            ["Strobe color", "Police", "Christmas", "RGB", "Random Loop"],
            "{{ ['Strobe color', 'Police', 'Christmas', 'RGB', 'Random Loop'] }}",
        ),
        (
            ["Police", "RGB", "Random Loop"],
            "{{ ['Police', 'RGB', 'Random Loop'] }}",
        ),
        (None, "{{ [] }}"),
        (None, "{{ '[]' }}"),
        (None, "{{ 124 }}"),
        (None, "{{ '124' }}"),
        (None, "{{ none }}"),
        (None, ""),
    ],
)
async def test_effect_list_template(
    hass: HomeAssistant,
    expected_effect_list,
    style: ConfigurationStyle,
    setup_light_with_effects,
) -> None:
    """Test the template for the effect list."""
    if style == ConfigurationStyle.TRIGGER:
        hass.states.async_set("light.test_state", STATE_ON)
        await hass.async_block_till_done()

    state = hass.states.get("light.test_template_light")
    assert state is not None
    assert state.attributes.get("effect_list") == expected_effect_list


@pytest.mark.parametrize(
    ("count", "effect_list_template"),
    [(1, "{{ ['Strobe color', 'Police', 'Christmas', 'RGB', 'Random Loop'] }}")],
)
@pytest.mark.parametrize(
    "style",
    [ConfigurationStyle.LEGACY, ConfigurationStyle.MODERN, ConfigurationStyle.TRIGGER],
)
@pytest.mark.parametrize(
    ("expected_effect", "effect_template"),
    [
        (None, "Disco"),
        (None, "None"),
        (None, "{{ None }}"),
        ("Police", "Police"),
        ("Strobe color", "{{ 'Strobe color' }}"),
    ],
)
async def test_effect_template(
    hass: HomeAssistant,
    expected_effect,
    style: ConfigurationStyle,
    setup_light_with_effects,
) -> None:
    """Test the template for the effect."""
    if style == ConfigurationStyle.TRIGGER:
        hass.states.async_set("light.test_state", STATE_ON)
        await hass.async_block_till_done()

    state = hass.states.get("light.test_template_light")
    assert state is not None
    assert state.attributes.get("effect") == expected_effect


@pytest.mark.parametrize("count", [1])
@pytest.mark.parametrize(
    ("style", "attribute"),
    [
        (ConfigurationStyle.LEGACY, "min_mireds_template"),
        (ConfigurationStyle.MODERN, "min_mireds"),
        (ConfigurationStyle.TRIGGER, "min_mireds"),
    ],
)
@pytest.mark.parametrize(
    ("expected_min_mireds", "attribute_template"),
    [
        (118, "{{118}}"),
        (153, "{{x - 12}}"),
        (153, "None"),
        (153, "{{ none }}"),
        (153, ""),
        (153, "{{ 'a' }}"),
    ],
)
async def test_min_mireds_template(
    hass: HomeAssistant,
    expected_min_mireds,
    style: ConfigurationStyle,
    setup_light_with_mireds,
) -> None:
    """Test the template for the min mireds."""
    if style == ConfigurationStyle.TRIGGER:
        hass.states.async_set("light.test_state", STATE_ON)
        await hass.async_block_till_done()

    state = hass.states.get("light.test_template_light")
    assert state is not None
    assert state.attributes.get("min_mireds") == expected_min_mireds


@pytest.mark.parametrize("count", [1])
@pytest.mark.parametrize(
    ("style", "attribute"),
    [
        (ConfigurationStyle.LEGACY, "max_mireds_template"),
        (ConfigurationStyle.MODERN, "max_mireds"),
        (ConfigurationStyle.TRIGGER, "max_mireds"),
    ],
)
@pytest.mark.parametrize(
    ("expected_max_mireds", "attribute_template"),
    [
        (488, "{{488}}"),
        (500, "{{x - 12}}"),
        (500, "None"),
        (500, "{{ none }}"),
        (500, ""),
        (500, "{{ 'a' }}"),
    ],
)
async def test_max_mireds_template(
    hass: HomeAssistant,
    expected_max_mireds,
    style: ConfigurationStyle,
    setup_light_with_mireds,
) -> None:
    """Test the template for the max mireds."""
    if style == ConfigurationStyle.TRIGGER:
        hass.states.async_set("light.test_state", STATE_ON)
        await hass.async_block_till_done()

    state = hass.states.get("light.test_template_light")
    assert state is not None
    assert state.attributes.get("max_mireds") == expected_max_mireds


@pytest.mark.parametrize(
    ("count", "extra_config"), [(1, OPTIMISTIC_COLOR_TEMP_LIGHT_CONFIG)]
)
@pytest.mark.parametrize(
    ("style", "attribute"),
    [
        (ConfigurationStyle.LEGACY, "supports_transition_template"),
        (ConfigurationStyle.MODERN, "supports_transition"),
        (ConfigurationStyle.TRIGGER, "supports_transition"),
    ],
)
@pytest.mark.parametrize(
    ("expected_supports_transition", "attribute_template"),
    [
        (True, "{{true}}"),
        (True, "{{1 == 1}}"),
        (False, "{{false}}"),
        (False, "{{ none }}"),
        (False, ""),
        (False, "None"),
    ],
)
async def test_supports_transition_template(
    hass: HomeAssistant,
    style: ConfigurationStyle,
    expected_supports_transition,
    setup_single_attribute_light,
) -> None:
    """Test the template for the supports transition."""
    if style == ConfigurationStyle.TRIGGER:
        # Ensures the trigger template entity updates
        hass.states.async_set("light.test_state", STATE_ON)
        await hass.async_block_till_done()

    state = hass.states.get("light.test_template_light")

    expected_value = 1

    if expected_supports_transition is True:
        expected_value = 0

    assert state is not None
    assert (
        int(state.attributes.get("supported_features")) & LightEntityFeature.TRANSITION
    ) != expected_value


@pytest.mark.parametrize(
    ("count", "transition_template"), [(1, "{{ states('sensor.test') }}")]
)
@pytest.mark.parametrize(
    "style",
    [ConfigurationStyle.LEGACY, ConfigurationStyle.MODERN, ConfigurationStyle.TRIGGER],
)
async def test_supports_transition_template_updates(
    hass: HomeAssistant, style: ConfigurationStyle, setup_light_with_transition_template
) -> None:
    """Test the template for the supports transition dynamically."""
    state = hass.states.get("light.test_template_light")
    assert state is not None

    hass.states.async_set("sensor.test", 0)
    await hass.async_block_till_done()

    if style == ConfigurationStyle.TRIGGER:
        # Ensures the trigger template entity updates
        hass.states.async_set("light.test_state", STATE_ON)
        await hass.async_block_till_done()

    state = hass.states.get("light.test_template_light")
    supported_features = state.attributes.get("supported_features")
    assert supported_features == LightEntityFeature.EFFECT

    hass.states.async_set("sensor.test", 1)
    await hass.async_block_till_done()

    if style == ConfigurationStyle.TRIGGER:
        # Ensures the trigger template entity updates
        hass.states.async_set("light.test_state", STATE_OFF)
        await hass.async_block_till_done()

    state = hass.states.get("light.test_template_light")
    supported_features = state.attributes.get("supported_features")
    assert (
        supported_features == LightEntityFeature.TRANSITION | LightEntityFeature.EFFECT
    )

    hass.states.async_set("sensor.test", 0)
    await hass.async_block_till_done()

    if style == ConfigurationStyle.TRIGGER:
        # Ensures the trigger template entity updates
        hass.states.async_set("light.test_state", STATE_ON)
        await hass.async_block_till_done()

    state = hass.states.get("light.test_template_light")
    supported_features = state.attributes.get("supported_features")
    assert supported_features == LightEntityFeature.EFFECT


@pytest.mark.parametrize(
    ("count", "extra_config", "attribute_template"),
    [
        (
            1,
            OPTIMISTIC_BRIGHTNESS_LIGHT_CONFIG,
            "{{ is_state('availability_boolean.state', 'on') }}",
        )
    ],
)
@pytest.mark.parametrize(
    ("style", "attribute"),
    [
        (ConfigurationStyle.LEGACY, "availability_template"),
        (ConfigurationStyle.MODERN, "availability"),
        (ConfigurationStyle.TRIGGER, "availability"),
    ],
)
async def test_available_template_with_entities(
    hass: HomeAssistant, style: ConfigurationStyle, setup_single_attribute_light
) -> None:
    """Test availability templates with values from other entities."""
    # When template returns true..
    hass.states.async_set(_STATE_AVAILABILITY_BOOLEAN, STATE_ON)
    await hass.async_block_till_done()

    if style == ConfigurationStyle.TRIGGER:
        # Ensures the trigger template entity updates
        hass.states.async_set("light.test_state", STATE_ON)
        await hass.async_block_till_done()

    # Device State should not be unavailable
    assert hass.states.get("light.test_template_light").state != STATE_UNAVAILABLE

    # When Availability template returns false
    hass.states.async_set(_STATE_AVAILABILITY_BOOLEAN, STATE_OFF)
    await hass.async_block_till_done()

    if style == ConfigurationStyle.TRIGGER:
        # Ensures the trigger template entity updates
        hass.states.async_set("light.test_state", STATE_OFF)
        await hass.async_block_till_done()

    # device state should be unavailable
    assert hass.states.get("light.test_template_light").state == STATE_UNAVAILABLE


@pytest.mark.parametrize(
    ("count", "extra_config", "attribute_template"),
    [
        (
            1,
            OPTIMISTIC_BRIGHTNESS_LIGHT_CONFIG,
            "{{ x - 12 }}",
        )
    ],
)
@pytest.mark.parametrize(
    ("style", "attribute"),
    [
        (ConfigurationStyle.LEGACY, "availability_template"),
        (ConfigurationStyle.MODERN, "availability"),
    ],
)
async def test_invalid_availability_template_keeps_component_available(
    hass: HomeAssistant,
    setup_single_attribute_light,
    caplog_setup_text,
) -> None:
    """Test that an invalid availability keeps the device available."""
    assert hass.states.get("light.test_template_light").state != STATE_UNAVAILABLE
    assert "UndefinedError: 'x' is undefined" in caplog_setup_text


@pytest.mark.parametrize("count", [1])
@pytest.mark.parametrize(
    ("light_config", "style"),
    [
        (
            {
                "test_template_light_01": TEST_UNIQUE_ID_CONFIG,
                "test_template_light_02": TEST_UNIQUE_ID_CONFIG,
            },
            ConfigurationStyle.LEGACY,
        ),
        (
            [
                {
                    "name": "test_template_light_01",
                    **TEST_UNIQUE_ID_CONFIG,
                },
                {
                    "name": "test_template_light_02",
                    **TEST_UNIQUE_ID_CONFIG,
                },
            ],
            ConfigurationStyle.MODERN,
        ),
        (
            [
                {
                    "name": "test_template_light_01",
                    **TEST_UNIQUE_ID_CONFIG,
                },
                {
                    "name": "test_template_light_02",
                    **TEST_UNIQUE_ID_CONFIG,
                },
            ],
            ConfigurationStyle.TRIGGER,
        ),
    ],
)
async def test_unique_id(hass: HomeAssistant, setup_light) -> None:
    """Test unique_id option only creates one light per id."""
    assert len(hass.states.async_all("light")) == 1


async def test_nested_unique_id(
    hass: HomeAssistant, entity_registry: er.EntityRegistry
) -> None:
    """Test unique_id option creates one light per nested id."""

    with assert_setup_component(1, template.DOMAIN):
        assert await async_setup_component(
            hass,
            template.DOMAIN,
            {
                "template": {
                    "unique_id": "x",
                    "light": [
                        {
                            "name": "test_a",
                            **OPTIMISTIC_ON_OFF_LIGHT_CONFIG,
                            "unique_id": "a",
                        },
                        {
                            "name": "test_b",
                            **OPTIMISTIC_ON_OFF_LIGHT_CONFIG,
                            "unique_id": "b",
                        },
                    ],
                }
            },
        )

    await hass.async_block_till_done()
    await hass.async_start()
    await hass.async_block_till_done()

    assert len(hass.states.async_all("light")) == 2

    entry = entity_registry.async_get("light.test_a")
    assert entry
    assert entry.unique_id == "x-a"

    entry = entity_registry.async_get("light.test_b")
    assert entry
    assert entry.unique_id == "x-b"


@pytest.mark.parametrize(("count", "extra_config"), [(1, {})])
@pytest.mark.parametrize(
    "style",
    [
        ConfigurationStyle.LEGACY,
        ConfigurationStyle.MODERN,
    ],
)
@pytest.mark.parametrize(
    ("action", "color_mode"),
    [
        ("set_level", ColorMode.BRIGHTNESS),
        ("set_temperature", ColorMode.COLOR_TEMP),
        ("set_hs", ColorMode.HS),
        ("set_rgb", ColorMode.RGB),
        ("set_rgbw", ColorMode.RGBW),
        ("set_rgbww", ColorMode.RGBWW),
    ],
)
async def test_empty_color_mode_action_config(
    hass: HomeAssistant,
    color_mode: ColorMode,
    setup_empty_action_light,
) -> None:
    """Test empty actions for color mode actions."""
    state = hass.states.get("light.test_template_light")
    assert state.attributes["supported_color_modes"] == [color_mode]

    await hass.services.async_call(
        light.DOMAIN,
        SERVICE_TURN_ON,
        {ATTR_ENTITY_ID: "light.test_template_light"},
        blocking=True,
    )

    state = hass.states.get("light.test_template_light")
    assert state.state == STATE_ON

    await hass.services.async_call(
        light.DOMAIN,
        SERVICE_TURN_OFF,
        {ATTR_ENTITY_ID: "light.test_template_light"},
        blocking=True,
    )

    state = hass.states.get("light.test_template_light")
    assert state.state == STATE_OFF


@pytest.mark.parametrize(("count"), [1])
@pytest.mark.parametrize(
    ("style", "extra_config"),
    [
        (
            ConfigurationStyle.LEGACY,
            {
                "effect_list_template": "{{ ['a'] }}",
                "effect_template": "{{ 'a' }}",
            },
        ),
        (
            ConfigurationStyle.MODERN,
            {
                "effect_list": "{{ ['a'] }}",
                "effect": "{{ 'a' }}",
            },
        ),
    ],
)
@pytest.mark.parametrize("action", ["set_effect"])
async def test_effect_with_empty_action(
    hass: HomeAssistant,
    setup_empty_action_light,
) -> None:
    """Test empty set_effect action."""
    state = hass.states.get("light.test_template_light")
    assert state.attributes["supported_features"] == LightEntityFeature.EFFECT