"""Support for sensors through the SmartThings cloud API."""

from __future__ import annotations

from collections.abc import Callable, Mapping
from dataclasses import dataclass
from datetime import datetime
from typing import Any, cast

from pysmartthings import Attribute, Capability, ComponentStatus, SmartThings, Status

from homeassistant.components.sensor import (
    DOMAIN as SENSOR_DOMAIN,
    SensorDeviceClass,
    SensorEntity,
    SensorEntityDescription,
    SensorStateClass,
)
from homeassistant.const import (
    CONCENTRATION_MICROGRAMS_PER_CUBIC_METER,
    CONCENTRATION_PARTS_PER_MILLION,
    LIGHT_LUX,
    PERCENTAGE,
    EntityCategory,
    UnitOfArea,
    UnitOfEnergy,
    UnitOfMass,
    UnitOfPower,
    UnitOfPressure,
    UnitOfTemperature,
    UnitOfVolume,
)
from homeassistant.core import HomeAssistant
from homeassistant.helpers import entity_registry as er
from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback
from homeassistant.util import dt as dt_util

from . import FullDevice, SmartThingsConfigEntry
from .const import MAIN
from .entity import SmartThingsEntity
from .util import deprecate_entity

THERMOSTAT_CAPABILITIES = {
    Capability.TEMPERATURE_MEASUREMENT,
    Capability.THERMOSTAT_HEATING_SETPOINT,
    Capability.THERMOSTAT_MODE,
}

COOKTOP_HEATING_MODES = {
    "off": "off",
    "manual": "manual",
    "boost": "boost",
    "keepWarm": "keep_warm",
    "quickPreheat": "quick_preheat",
    "defrost": "defrost",
    "melt": "melt",
    "simmer": "simmer",
}

JOB_STATE_MAP = {
    "airWash": "air_wash",
    "airwash": "air_wash",
    "aIRinse": "ai_rinse",
    "aISpin": "ai_spin",
    "aIWash": "ai_wash",
    "aIDrying": "ai_drying",
    "internalCare": "internal_care",
    "continuousDehumidifying": "continuous_dehumidifying",
    "thawingFrozenInside": "thawing_frozen_inside",
    "delayWash": "delay_wash",
    "weightSensing": "weight_sensing",
    "freezeProtection": "freeze_protection",
    "preDrain": "pre_drain",
    "preWash": "pre_wash",
    "prewash": "pre_wash",
    "wrinklePrevent": "wrinkle_prevent",
    "unknown": None,
}

OVEN_JOB_STATE_MAP = {
    "scheduledStart": "scheduled_start",
    "fastPreheat": "fast_preheat",
    "scheduledEnd": "scheduled_end",
    "stone_heating": "stone_heating",
    "timeHoldPreheat": "time_hold_preheat",
}

MEDIA_PLAYBACK_STATE_MAP = {
    "fast forwarding": "fast_forwarding",
}

ROBOT_CLEANER_TURBO_MODE_STATE_MAP = {
    "extraSilence": "extra_silence",
}

ROBOT_CLEANER_MOVEMENT_MAP = {
    "powerOff": "off",
}

OVEN_MODE = {
    "Conventional": "conventional",
    "Bake": "bake",
    "BottomHeat": "bottom_heat",
    "ConvectionBake": "convection_bake",
    "ConvectionRoast": "convection_roast",
    "Broil": "broil",
    "ConvectionBroil": "convection_broil",
    "SteamCook": "steam_cook",
    "SteamBake": "steam_bake",
    "SteamRoast": "steam_roast",
    "SteamBottomHeatplusConvection": "steam_bottom_heat_plus_convection",
    "Microwave": "microwave",
    "MWplusGrill": "microwave_plus_grill",
    "MWplusConvection": "microwave_plus_convection",
    "MWplusHotBlast": "microwave_plus_hot_blast",
    "MWplusHotBlast2": "microwave_plus_hot_blast_2",
    "SlimMiddle": "slim_middle",
    "SlimStrong": "slim_strong",
    "SlowCook": "slow_cook",
    "Proof": "proof",
    "Dehydrate": "dehydrate",
    "Others": "others",
    "StrongSteam": "strong_steam",
    "Descale": "descale",
    "Rinse": "rinse",
}

HEALTH_CONCERN = {
    "good": "good",
    "moderate": "moderate",
    "slightlyUnhealthy": "slightly_unhealthy",
    "unhealthy": "unhealthy",
    "veryUnhealthy": "very_unhealthy",
    "hazardous": "hazardous",
}

WASHER_OPTIONS = ["pause", "run", "stop"]


def power_attributes(status: dict[str, Any]) -> dict[str, Any]:
    """Return the power attributes."""
    state = {}
    for attribute in ("start", "end"):
        if (value := status.get(attribute)) is not None:
            state[f"power_consumption_{attribute}"] = value
    return state


@dataclass(frozen=True, kw_only=True)
class SmartThingsSensorEntityDescription(SensorEntityDescription):
    """Describe a SmartThings sensor entity."""

    value_fn: Callable[[Any], str | float | int | datetime | None] = lambda value: value
    extra_state_attributes_fn: Callable[[Any], dict[str, Any]] | None = None
    capability_ignore_list: list[set[Capability]] | None = None
    options_attribute: Attribute | None = None
    options_map: dict[str, str] | None = None
    translation_placeholders_fn: Callable[[str], dict[str, str]] | None = None
    component_fn: Callable[[str], bool] | None = None
    exists_fn: Callable[[Status], bool] | None = None
    use_temperature_unit: bool = False
    deprecated: Callable[[ComponentStatus], tuple[str, str] | None] | None = None
    component_translation_key: dict[str, str] | None = None


CAPABILITY_TO_SENSORS: dict[
    Capability, dict[Attribute, list[SmartThingsSensorEntityDescription]]
] = {
    # Haven't seen at devices yet
    Capability.ACTIVITY_LIGHTING_MODE: {
        Attribute.LIGHTING_MODE: [
            SmartThingsSensorEntityDescription(
                key=Attribute.LIGHTING_MODE,
                translation_key="lighting_mode",
                entity_category=EntityCategory.DIAGNOSTIC,
            )
        ]
    },
    Capability.AIR_CONDITIONER_MODE: {
        Attribute.AIR_CONDITIONER_MODE: [
            SmartThingsSensorEntityDescription(
                key=Attribute.AIR_CONDITIONER_MODE,
                translation_key="air_conditioner_mode",
                entity_category=EntityCategory.DIAGNOSTIC,
                capability_ignore_list=[
                    {
                        Capability.TEMPERATURE_MEASUREMENT,
                        Capability.THERMOSTAT_COOLING_SETPOINT,
                    }
                ],
            )
        ]
    },
    Capability.AIR_QUALITY_SENSOR: {
        Attribute.AIR_QUALITY: [
            SmartThingsSensorEntityDescription(
                key=Attribute.AIR_QUALITY,
                translation_key="air_quality",
                native_unit_of_measurement="CAQI",
                state_class=SensorStateClass.MEASUREMENT,
            )
        ]
    },
    Capability.ALARM: {
        Attribute.ALARM: [
            SmartThingsSensorEntityDescription(
                key=Attribute.ALARM,
                translation_key="alarm",
                options=["both", "strobe", "siren", "off"],
                device_class=SensorDeviceClass.ENUM,
            )
        ]
    },
    Capability.ATMOSPHERIC_PRESSURE_MEASUREMENT: {
        Attribute.ATMOSPHERIC_PRESSURE: [
            SmartThingsSensorEntityDescription(
                key=Attribute.ATMOSPHERIC_PRESSURE,
                device_class=SensorDeviceClass.ATMOSPHERIC_PRESSURE,
                state_class=SensorStateClass.MEASUREMENT,
            )
        ]
    },
    Capability.AUDIO_VOLUME: {
        Attribute.VOLUME: [
            SmartThingsSensorEntityDescription(
                key=Attribute.VOLUME,
                translation_key="audio_volume",
                native_unit_of_measurement=PERCENTAGE,
                deprecated=(
                    lambda status: (
                        ("2025.10.0", "media_player")
                        if Capability.AUDIO_MUTE in status
                        else None
                    )
                ),
            )
        ]
    },
    Capability.BATTERY: {
        Attribute.BATTERY: [
            SmartThingsSensorEntityDescription(
                key=Attribute.BATTERY,
                native_unit_of_measurement=PERCENTAGE,
                device_class=SensorDeviceClass.BATTERY,
                entity_category=EntityCategory.DIAGNOSTIC,
            )
        ]
    },
    # Haven't seen at devices yet
    Capability.BODY_MASS_INDEX_MEASUREMENT: {
        Attribute.BMI_MEASUREMENT: [
            SmartThingsSensorEntityDescription(
                key=Attribute.BMI_MEASUREMENT,
                translation_key="body_mass_index",
                native_unit_of_measurement=f"{UnitOfMass.KILOGRAMS}/{UnitOfArea.SQUARE_METERS}",
                state_class=SensorStateClass.MEASUREMENT,
            )
        ]
    },
    # Haven't seen at devices yet
    Capability.BODY_WEIGHT_MEASUREMENT: {
        Attribute.BODY_WEIGHT_MEASUREMENT: [
            SmartThingsSensorEntityDescription(
                key=Attribute.BODY_WEIGHT_MEASUREMENT,
                translation_key="body_weight",
                native_unit_of_measurement=UnitOfMass.KILOGRAMS,
                device_class=SensorDeviceClass.WEIGHT,
                state_class=SensorStateClass.MEASUREMENT,
            )
        ]
    },
    Capability.CARBON_DIOXIDE_MEASUREMENT: {
        Attribute.CARBON_DIOXIDE: [
            SmartThingsSensorEntityDescription(
                key=Attribute.CARBON_DIOXIDE,
                native_unit_of_measurement=CONCENTRATION_PARTS_PER_MILLION,
                device_class=SensorDeviceClass.CO2,
                state_class=SensorStateClass.MEASUREMENT,
            )
        ]
    },
    # Haven't seen at devices yet
    Capability.CARBON_MONOXIDE_DETECTOR: {
        Attribute.CARBON_MONOXIDE: [
            SmartThingsSensorEntityDescription(
                key=Attribute.CARBON_MONOXIDE,
                translation_key="carbon_monoxide_detector",
                options=["detected", "clear", "tested"],
                device_class=SensorDeviceClass.ENUM,
            )
        ]
    },
    # Haven't seen at devices yet
    Capability.CARBON_MONOXIDE_MEASUREMENT: {
        Attribute.CARBON_MONOXIDE_LEVEL: [
            SmartThingsSensorEntityDescription(
                key=Attribute.CARBON_MONOXIDE_LEVEL,
                native_unit_of_measurement=CONCENTRATION_PARTS_PER_MILLION,
                device_class=SensorDeviceClass.CO,
                state_class=SensorStateClass.MEASUREMENT,
            )
        ]
    },
    Capability.SAMSUNG_CE_COOKTOP_HEATING_POWER: {
        Attribute.MANUAL_LEVEL: [
            SmartThingsSensorEntityDescription(
                key=Attribute.MANUAL_LEVEL,
                translation_key="manual_level",
                translation_placeholders_fn=lambda component: {
                    "burner_id": component.split("-0")[-1]
                },
                component_fn=lambda component: component.startswith("burner-0"),
            )
        ],
        Attribute.HEATING_MODE: [
            SmartThingsSensorEntityDescription(
                key=Attribute.HEATING_MODE,
                translation_key="heating_mode",
                options_attribute=Attribute.SUPPORTED_HEATING_MODES,
                options_map=COOKTOP_HEATING_MODES,
                device_class=SensorDeviceClass.ENUM,
                translation_placeholders_fn=lambda component: {
                    "burner_id": component.split("-0")[-1]
                },
                component_fn=lambda component: component.startswith("burner-0"),
            )
        ],
    },
    Capability.CUSTOM_COOKTOP_OPERATING_STATE: {
        Attribute.COOKTOP_OPERATING_STATE: [
            SmartThingsSensorEntityDescription(
                key=Attribute.COOKTOP_OPERATING_STATE,
                translation_key="cooktop_operating_state",
                device_class=SensorDeviceClass.ENUM,
                options_attribute=Attribute.SUPPORTED_COOKTOP_OPERATING_STATE,
            )
        ]
    },
    Capability.CUSTOM_WATER_FILTER: {
        Attribute.WATER_FILTER_USAGE: [
            SmartThingsSensorEntityDescription(
                key=Attribute.WATER_FILTER_USAGE,
                translation_key="water_filter_usage",
                native_unit_of_measurement=PERCENTAGE,
                state_class=SensorStateClass.MEASUREMENT,
            )
        ]
    },
    Capability.DISHWASHER_OPERATING_STATE: {
        Attribute.MACHINE_STATE: [
            SmartThingsSensorEntityDescription(
                key=Attribute.MACHINE_STATE,
                translation_key="dishwasher_machine_state",
                options=WASHER_OPTIONS,
                device_class=SensorDeviceClass.ENUM,
            )
        ],
        Attribute.DISHWASHER_JOB_STATE: [
            SmartThingsSensorEntityDescription(
                key=Attribute.DISHWASHER_JOB_STATE,
                translation_key="dishwasher_job_state",
                options=[
                    "air_wash",
                    "cooling",
                    "drying",
                    "finish",
                    "pre_drain",
                    "pre_wash",
                    "rinse",
                    "spin",
                    "wash",
                    "wrinkle_prevent",
                ],
                device_class=SensorDeviceClass.ENUM,
                value_fn=lambda value: JOB_STATE_MAP.get(value, value),
            )
        ],
        Attribute.COMPLETION_TIME: [
            SmartThingsSensorEntityDescription(
                key=Attribute.COMPLETION_TIME,
                translation_key="completion_time",
                device_class=SensorDeviceClass.TIMESTAMP,
                value_fn=dt_util.parse_datetime,
            )
        ],
    },
    # part of the proposed spec, Haven't seen at devices yet
    Capability.DRYER_MODE: {
        Attribute.DRYER_MODE: [
            SmartThingsSensorEntityDescription(
                key=Attribute.DRYER_MODE,
                translation_key="dryer_mode",
                entity_category=EntityCategory.DIAGNOSTIC,
            )
        ]
    },
    Capability.DRYER_OPERATING_STATE: {
        Attribute.MACHINE_STATE: [
            SmartThingsSensorEntityDescription(
                key=Attribute.MACHINE_STATE,
                translation_key="dryer_machine_state",
                options=WASHER_OPTIONS,
                device_class=SensorDeviceClass.ENUM,
            )
        ],
        Attribute.DRYER_JOB_STATE: [
            SmartThingsSensorEntityDescription(
                key=Attribute.DRYER_JOB_STATE,
                translation_key="dryer_job_state",
                options=[
                    "cooling",
                    "delay_wash",
                    "drying",
                    "finished",
                    "none",
                    "refreshing",
                    "weight_sensing",
                    "wrinkle_prevent",
                    "dehumidifying",
                    "ai_drying",
                    "sanitizing",
                    "internal_care",
                    "freeze_protection",
                    "continuous_dehumidifying",
                    "thawing_frozen_inside",
                ],
                device_class=SensorDeviceClass.ENUM,
                value_fn=lambda value: JOB_STATE_MAP.get(value, value),
            )
        ],
        Attribute.COMPLETION_TIME: [
            SmartThingsSensorEntityDescription(
                key=Attribute.COMPLETION_TIME,
                translation_key="completion_time",
                device_class=SensorDeviceClass.TIMESTAMP,
                value_fn=dt_util.parse_datetime,
            )
        ],
    },
    Capability.DUST_HEALTH_CONCERN: {
        Attribute.DUST_HEALTH_CONCERN: [
            SmartThingsSensorEntityDescription(
                key=Attribute.DUST_HEALTH_CONCERN,
                translation_key="pm10_health_concern",
                device_class=SensorDeviceClass.ENUM,
                options=list(HEALTH_CONCERN.values()),
                value_fn=HEALTH_CONCERN.get,
            )
        ]
    },
    Capability.DUST_SENSOR: {
        Attribute.DUST_LEVEL: [
            SmartThingsSensorEntityDescription(
                key=Attribute.DUST_LEVEL,
                device_class=SensorDeviceClass.PM10,
                native_unit_of_measurement=CONCENTRATION_MICROGRAMS_PER_CUBIC_METER,
                state_class=SensorStateClass.MEASUREMENT,
            )
        ],
        Attribute.FINE_DUST_LEVEL: [
            SmartThingsSensorEntityDescription(
                key=Attribute.FINE_DUST_LEVEL,
                device_class=SensorDeviceClass.PM25,
                native_unit_of_measurement=CONCENTRATION_MICROGRAMS_PER_CUBIC_METER,
                state_class=SensorStateClass.MEASUREMENT,
            )
        ],
    },
    Capability.SAMSUNG_CE_EHS_DIVERTER_VALVE: {
        Attribute.POSITION: [
            SmartThingsSensorEntityDescription(
                key=Attribute.POSITION,
                translation_key="diverter_valve_position",
                device_class=SensorDeviceClass.ENUM,
                options=["room", "tank"],
            )
        ]
    },
    Capability.ENERGY_METER: {
        Attribute.ENERGY: [
            SmartThingsSensorEntityDescription(
                key=Attribute.ENERGY,
                native_unit_of_measurement=UnitOfEnergy.KILO_WATT_HOUR,
                device_class=SensorDeviceClass.ENERGY,
                state_class=SensorStateClass.TOTAL_INCREASING,
            )
        ]
    },
    # Haven't seen at devices yet
    Capability.EQUIVALENT_CARBON_DIOXIDE_MEASUREMENT: {
        Attribute.EQUIVALENT_CARBON_DIOXIDE_MEASUREMENT: [
            SmartThingsSensorEntityDescription(
                key=Attribute.EQUIVALENT_CARBON_DIOXIDE_MEASUREMENT,
                translation_key="equivalent_carbon_dioxide",
                native_unit_of_measurement=CONCENTRATION_PARTS_PER_MILLION,
                device_class=SensorDeviceClass.CO2,
                state_class=SensorStateClass.MEASUREMENT,
            )
        ]
    },
    Capability.FINE_DUST_HEALTH_CONCERN: {
        Attribute.FINE_DUST_HEALTH_CONCERN: [
            SmartThingsSensorEntityDescription(
                key=Attribute.FINE_DUST_HEALTH_CONCERN,
                translation_key="pm25_health_concern",
                device_class=SensorDeviceClass.ENUM,
                options=list(HEALTH_CONCERN.values()),
                value_fn=HEALTH_CONCERN.get,
            )
        ]
    },
    Capability.FINE_DUST_SENSOR: {
        Attribute.FINE_DUST_LEVEL: [
            SmartThingsSensorEntityDescription(
                key=Attribute.FINE_DUST_LEVEL,
                native_unit_of_measurement=CONCENTRATION_MICROGRAMS_PER_CUBIC_METER,
                state_class=SensorStateClass.MEASUREMENT,
                device_class=SensorDeviceClass.PM25,
            )
        ]
    },
    # Haven't seen at devices yet
    Capability.FORMALDEHYDE_MEASUREMENT: {
        Attribute.FORMALDEHYDE_LEVEL: [
            SmartThingsSensorEntityDescription(
                key=Attribute.FORMALDEHYDE_LEVEL,
                translation_key="formaldehyde",
                native_unit_of_measurement=CONCENTRATION_PARTS_PER_MILLION,
                state_class=SensorStateClass.MEASUREMENT,
            )
        ]
    },
    Capability.GAS_METER: {
        Attribute.GAS_METER: [
            SmartThingsSensorEntityDescription(
                key=Attribute.GAS_METER,
                translation_key="gas_meter",
                native_unit_of_measurement=UnitOfEnergy.KILO_WATT_HOUR,
                device_class=SensorDeviceClass.ENERGY,
                state_class=SensorStateClass.TOTAL,
            )
        ],
        Attribute.GAS_METER_CALORIFIC: [
            SmartThingsSensorEntityDescription(
                key=Attribute.GAS_METER_CALORIFIC,
                translation_key="gas_meter_calorific",
            )
        ],
        Attribute.GAS_METER_TIME: [
            SmartThingsSensorEntityDescription(
                key=Attribute.GAS_METER_TIME,
                translation_key="gas_meter_time",
                device_class=SensorDeviceClass.TIMESTAMP,
                value_fn=dt_util.parse_datetime,
            )
        ],
        Attribute.GAS_METER_VOLUME: [
            SmartThingsSensorEntityDescription(
                key=Attribute.GAS_METER_VOLUME,
                native_unit_of_measurement=UnitOfVolume.CUBIC_METERS,
                device_class=SensorDeviceClass.GAS,
                state_class=SensorStateClass.TOTAL,
            )
        ],
    },
    Capability.ILLUMINANCE_MEASUREMENT: {
        Attribute.ILLUMINANCE: [
            SmartThingsSensorEntityDescription(
                key=Attribute.ILLUMINANCE,
                native_unit_of_measurement=LIGHT_LUX,
                device_class=SensorDeviceClass.ILLUMINANCE,
                state_class=SensorStateClass.MEASUREMENT,
            )
        ]
    },
    # Haven't seen at devices yet
    Capability.INFRARED_LEVEL: {
        Attribute.INFRARED_LEVEL: [
            SmartThingsSensorEntityDescription(
                key=Attribute.INFRARED_LEVEL,
                translation_key="infrared_level",
                native_unit_of_measurement=PERCENTAGE,
                state_class=SensorStateClass.MEASUREMENT,
            )
        ]
    },
    Capability.MEDIA_INPUT_SOURCE: {
        Attribute.INPUT_SOURCE: [
            SmartThingsSensorEntityDescription(
                key=Attribute.INPUT_SOURCE,
                translation_key="media_input_source",
                device_class=SensorDeviceClass.ENUM,
                options_attribute=Attribute.SUPPORTED_INPUT_SOURCES,
                value_fn=lambda value: value.lower() if value else None,
                deprecated=lambda _: ("2025.10.0", "media_player"),
            )
        ]
    },
    Capability.MEDIA_PLAYBACK_REPEAT: {
        Attribute.PLAYBACK_REPEAT_MODE: [
            SmartThingsSensorEntityDescription(
                key=Attribute.PLAYBACK_REPEAT_MODE,
                translation_key="media_playback_repeat",
                deprecated=lambda _: ("2025.10.0", "media_player"),
            )
        ]
    },
    Capability.MEDIA_PLAYBACK_SHUFFLE: {
        Attribute.PLAYBACK_SHUFFLE: [
            SmartThingsSensorEntityDescription(
                key=Attribute.PLAYBACK_SHUFFLE,
                translation_key="media_playback_shuffle",
                deprecated=lambda _: ("2025.10.0", "media_player"),
            )
        ]
    },
    Capability.MEDIA_PLAYBACK: {
        Attribute.PLAYBACK_STATUS: [
            SmartThingsSensorEntityDescription(
                key=Attribute.PLAYBACK_STATUS,
                translation_key="media_playback_status",
                options=[
                    "paused",
                    "playing",
                    "stopped",
                    "fast_forwarding",
                    "rewinding",
                    "buffering",
                ],
                device_class=SensorDeviceClass.ENUM,
                value_fn=lambda value: MEDIA_PLAYBACK_STATE_MAP.get(value, value),
                deprecated=lambda _: ("2025.10.0", "media_player"),
            )
        ]
    },
    Capability.ODOR_SENSOR: {
        Attribute.ODOR_LEVEL: [
            SmartThingsSensorEntityDescription(
                key=Attribute.ODOR_LEVEL,
                translation_key="odor_sensor",
            )
        ]
    },
    Capability.OVEN_MODE: {
        Attribute.OVEN_MODE: [
            SmartThingsSensorEntityDescription(
                key=Attribute.OVEN_MODE,
                translation_key="oven_mode",
                entity_category=EntityCategory.DIAGNOSTIC,
                options=[
                    *OVEN_MODE.values(),
                    "heating",
                    "grill",
                    "defrosting",
                    "warming",
                ],
                device_class=SensorDeviceClass.ENUM,
                value_fn=lambda value: OVEN_MODE.get(value, value),
                component_fn=lambda component: component == "cavity-01",
                component_translation_key={
                    "cavity-01": "oven_mode_cavity_01",
                },
            )
        ]
    },
    Capability.OVEN_OPERATING_STATE: {
        Attribute.MACHINE_STATE: [
            SmartThingsSensorEntityDescription(
                key=Attribute.MACHINE_STATE,
                translation_key="oven_machine_state",
                options=["ready", "running", "paused"],
                device_class=SensorDeviceClass.ENUM,
                component_fn=lambda component: component == "cavity-01",
                component_translation_key={
                    "cavity-01": "oven_machine_state_cavity_01",
                },
            )
        ],
        Attribute.OVEN_JOB_STATE: [
            SmartThingsSensorEntityDescription(
                key=Attribute.OVEN_JOB_STATE,
                translation_key="oven_job_state",
                options=[
                    "cleaning",
                    "cooking",
                    "cooling",
                    "draining",
                    "preheat",
                    "ready",
                    "rinsing",
                    "finished",
                    "scheduled_start",
                    "warming",
                    "defrosting",
                    "sensing",
                    "searing",
                    "fast_preheat",
                    "scheduled_end",
                    "stone_heating",
                    "time_hold_preheat",
                ],
                device_class=SensorDeviceClass.ENUM,
                value_fn=lambda value: OVEN_JOB_STATE_MAP.get(value, value),
                component_fn=lambda component: component == "cavity-01",
                component_translation_key={
                    "cavity-01": "oven_job_state_cavity_01",
                },
            )
        ],
        Attribute.COMPLETION_TIME: [
            SmartThingsSensorEntityDescription(
                key=Attribute.COMPLETION_TIME,
                translation_key="completion_time",
                device_class=SensorDeviceClass.TIMESTAMP,
                value_fn=dt_util.parse_datetime,
                component_fn=lambda component: component == "cavity-01",
                component_translation_key={
                    "cavity-01": "oven_completion_time_cavity_01",
                },
            )
        ],
    },
    Capability.OVEN_SETPOINT: {
        Attribute.OVEN_SETPOINT: [
            SmartThingsSensorEntityDescription(
                key=Attribute.OVEN_SETPOINT,
                translation_key="oven_setpoint",
                device_class=SensorDeviceClass.TEMPERATURE,
                use_temperature_unit=True,
                # Set the value to None if it is 0 F (-17 C)
                value_fn=lambda value: None if value in {-17, 0, 1} else value,
                component_fn=lambda component: component == "cavity-01",
                component_translation_key={
                    "cavity-01": "oven_setpoint_cavity_01",
                },
            )
        ]
    },
    Capability.POWER_CONSUMPTION_REPORT: {
        Attribute.POWER_CONSUMPTION: [
            SmartThingsSensorEntityDescription(
                key="energy_meter",
                state_class=SensorStateClass.TOTAL_INCREASING,
                device_class=SensorDeviceClass.ENERGY,
                native_unit_of_measurement=UnitOfEnergy.KILO_WATT_HOUR,
                value_fn=lambda value: value["energy"] / 1000,
                suggested_display_precision=2,
                exists_fn=lambda status: (
                    (value := cast(dict | None, status.value)) is not None
                    and "energy" in value
                ),
            ),
            SmartThingsSensorEntityDescription(
                key="power_meter",
                state_class=SensorStateClass.MEASUREMENT,
                device_class=SensorDeviceClass.POWER,
                native_unit_of_measurement=UnitOfPower.WATT,
                value_fn=lambda value: value["power"],
                extra_state_attributes_fn=power_attributes,
                suggested_display_precision=2,
                exists_fn=lambda status: (
                    (value := cast(dict | None, status.value)) is not None
                    and "power" in value
                ),
            ),
            SmartThingsSensorEntityDescription(
                key="deltaEnergy_meter",
                translation_key="energy_difference",
                state_class=SensorStateClass.TOTAL,
                device_class=SensorDeviceClass.ENERGY,
                native_unit_of_measurement=UnitOfEnergy.KILO_WATT_HOUR,
                value_fn=lambda value: value["deltaEnergy"] / 1000,
                suggested_display_precision=2,
                exists_fn=lambda status: (
                    (value := cast(dict | None, status.value)) is not None
                    and "deltaEnergy" in value
                ),
            ),
            SmartThingsSensorEntityDescription(
                key="powerEnergy_meter",
                translation_key="power_energy",
                state_class=SensorStateClass.TOTAL,
                device_class=SensorDeviceClass.ENERGY,
                native_unit_of_measurement=UnitOfEnergy.KILO_WATT_HOUR,
                value_fn=lambda value: value["powerEnergy"] / 1000,
                suggested_display_precision=2,
                exists_fn=lambda status: (
                    (value := cast(dict | None, status.value)) is not None
                    and "powerEnergy" in value
                ),
            ),
            SmartThingsSensorEntityDescription(
                key="energySaved_meter",
                translation_key="energy_saved",
                state_class=SensorStateClass.TOTAL_INCREASING,
                device_class=SensorDeviceClass.ENERGY,
                native_unit_of_measurement=UnitOfEnergy.KILO_WATT_HOUR,
                value_fn=lambda value: value["energySaved"] / 1000,
                suggested_display_precision=2,
                exists_fn=lambda status: (
                    (value := cast(dict | None, status.value)) is not None
                    and "energySaved" in value
                ),
            ),
        ]
    },
    Capability.POWER_METER: {
        Attribute.POWER: [
            SmartThingsSensorEntityDescription(
                key=Attribute.POWER,
                native_unit_of_measurement=UnitOfPower.WATT,
                device_class=SensorDeviceClass.POWER,
                state_class=SensorStateClass.MEASUREMENT,
            )
        ]
    },
    # Haven't seen at devices yet
    Capability.POWER_SOURCE: {
        Attribute.POWER_SOURCE: [
            SmartThingsSensorEntityDescription(
                key=Attribute.POWER_SOURCE,
                translation_key="power_source",
                entity_category=EntityCategory.DIAGNOSTIC,
            )
        ]
    },
    # part of the proposed spec
    Capability.REFRIGERATION_SETPOINT: {
        Attribute.REFRIGERATION_SETPOINT: [
            SmartThingsSensorEntityDescription(
                key=Attribute.REFRIGERATION_SETPOINT,
                translation_key="refrigeration_setpoint",
                device_class=SensorDeviceClass.TEMPERATURE,
            )
        ]
    },
    Capability.RELATIVE_BRIGHTNESS: {
        Attribute.BRIGHTNESS_INTENSITY: [
            SmartThingsSensorEntityDescription(
                key=Attribute.BRIGHTNESS_INTENSITY,
                translation_key="brightness_intensity",
                state_class=SensorStateClass.MEASUREMENT,
            )
        ]
    },
    Capability.RELATIVE_HUMIDITY_MEASUREMENT: {
        Attribute.HUMIDITY: [
            SmartThingsSensorEntityDescription(
                key=Attribute.HUMIDITY,
                native_unit_of_measurement=PERCENTAGE,
                device_class=SensorDeviceClass.HUMIDITY,
                state_class=SensorStateClass.MEASUREMENT,
            )
        ]
    },
    Capability.ROBOT_CLEANER_CLEANING_MODE: {
        Attribute.ROBOT_CLEANER_CLEANING_MODE: [
            SmartThingsSensorEntityDescription(
                key=Attribute.ROBOT_CLEANER_CLEANING_MODE,
                translation_key="robot_cleaner_cleaning_mode",
                options=["auto", "part", "repeat", "manual", "stop", "map"],
                device_class=SensorDeviceClass.ENUM,
                entity_category=EntityCategory.DIAGNOSTIC,
            )
        ],
    },
    Capability.ROBOT_CLEANER_MOVEMENT: {
        Attribute.ROBOT_CLEANER_MOVEMENT: [
            SmartThingsSensorEntityDescription(
                key=Attribute.ROBOT_CLEANER_MOVEMENT,
                translation_key="robot_cleaner_movement",
                options=[
                    "homing",
                    "idle",
                    "charging",
                    "alarm",
                    "off",
                    "reserve",
                    "point",
                    "after",
                    "cleaning",
                    "pause",
                ],
                device_class=SensorDeviceClass.ENUM,
                value_fn=lambda value: ROBOT_CLEANER_MOVEMENT_MAP.get(value, value),
            )
        ]
    },
    Capability.ROBOT_CLEANER_TURBO_MODE: {
        Attribute.ROBOT_CLEANER_TURBO_MODE: [
            SmartThingsSensorEntityDescription(
                key=Attribute.ROBOT_CLEANER_TURBO_MODE,
                translation_key="robot_cleaner_turbo_mode",
                options=["on", "off", "silence", "extra_silence"],
                device_class=SensorDeviceClass.ENUM,
                value_fn=lambda value: ROBOT_CLEANER_TURBO_MODE_STATE_MAP.get(
                    value, value
                ),
                entity_category=EntityCategory.DIAGNOSTIC,
            )
        ]
    },
    Capability.SIGNAL_STRENGTH: {
        Attribute.LQI: [
            SmartThingsSensorEntityDescription(
                key=Attribute.LQI,
                translation_key="link_quality",
                state_class=SensorStateClass.MEASUREMENT,
                entity_category=EntityCategory.DIAGNOSTIC,
            )
        ],
        Attribute.RSSI: [
            SmartThingsSensorEntityDescription(
                key=Attribute.RSSI,
                device_class=SensorDeviceClass.SIGNAL_STRENGTH,
                state_class=SensorStateClass.MEASUREMENT,
                entity_category=EntityCategory.DIAGNOSTIC,
            )
        ],
    },
    # Haven't seen at devices yet
    Capability.SMOKE_DETECTOR: {
        Attribute.SMOKE: [
            SmartThingsSensorEntityDescription(
                key=Attribute.SMOKE,
                translation_key="smoke_detector",
                options=["detected", "clear", "tested"],
                device_class=SensorDeviceClass.ENUM,
            )
        ]
    },
    Capability.TEMPERATURE_MEASUREMENT: {
        Attribute.TEMPERATURE: [
            SmartThingsSensorEntityDescription(
                key=Attribute.TEMPERATURE,
                device_class=SensorDeviceClass.TEMPERATURE,
                state_class=SensorStateClass.MEASUREMENT,
                deprecated=(
                    lambda status: (
                        ("2025.12.0", "dhw")
                        if Capability.CUSTOM_OUTING_MODE in status
                        else None
                    )
                ),
                component_fn=(
                    lambda component: (
                        component in {"freezer", "cooler", "onedoor", "cavity-01"}
                    )
                ),
                component_translation_key={
                    "freezer": "freezer_temperature",
                    "cooler": "cooler_temperature",
                    "cavity-01": "oven_temperature_cavity_01",
                },
            )
        ]
    },
    Capability.THERMOSTAT_COOLING_SETPOINT: {
        Attribute.COOLING_SETPOINT: [
            SmartThingsSensorEntityDescription(
                key=Attribute.COOLING_SETPOINT,
                translation_key="thermostat_cooling_setpoint",
                device_class=SensorDeviceClass.TEMPERATURE,
                capability_ignore_list=[
                    {
                        Capability.AIR_CONDITIONER_FAN_MODE,
                        Capability.TEMPERATURE_MEASUREMENT,
                        Capability.AIR_CONDITIONER_MODE,
                    },
                    THERMOSTAT_CAPABILITIES,
                ],
                deprecated=(
                    lambda status: (
                        ("2025.12.0", "dhw")
                        if Capability.CUSTOM_OUTING_MODE in status
                        else None
                    )
                ),
            )
        ]
    },
    # Haven't seen at devices yet
    Capability.THERMOSTAT_FAN_MODE: {
        Attribute.THERMOSTAT_FAN_MODE: [
            SmartThingsSensorEntityDescription(
                key=Attribute.THERMOSTAT_FAN_MODE,
                translation_key="thermostat_fan_mode",
                entity_category=EntityCategory.DIAGNOSTIC,
                capability_ignore_list=[THERMOSTAT_CAPABILITIES],
            )
        ]
    },
    # Haven't seen at devices yet
    Capability.THERMOSTAT_HEATING_SETPOINT: {
        Attribute.HEATING_SETPOINT: [
            SmartThingsSensorEntityDescription(
                key=Attribute.HEATING_SETPOINT,
                translation_key="thermostat_heating_setpoint",
                device_class=SensorDeviceClass.TEMPERATURE,
                entity_category=EntityCategory.DIAGNOSTIC,
                capability_ignore_list=[THERMOSTAT_CAPABILITIES],
            )
        ]
    },
    # Haven't seen at devices yet
    Capability.THERMOSTAT_MODE: {
        Attribute.THERMOSTAT_MODE: [
            SmartThingsSensorEntityDescription(
                key=Attribute.THERMOSTAT_MODE,
                translation_key="thermostat_mode",
                entity_category=EntityCategory.DIAGNOSTIC,
                capability_ignore_list=[THERMOSTAT_CAPABILITIES],
            )
        ]
    },
    # Haven't seen at devices yet
    Capability.THERMOSTAT_OPERATING_STATE: {
        Attribute.THERMOSTAT_OPERATING_STATE: [
            SmartThingsSensorEntityDescription(
                key=Attribute.THERMOSTAT_OPERATING_STATE,
                translation_key="thermostat_operating_state",
                capability_ignore_list=[THERMOSTAT_CAPABILITIES],
            )
        ]
    },
    # deprecated capability
    Capability.THERMOSTAT_SETPOINT: {
        Attribute.THERMOSTAT_SETPOINT: [
            SmartThingsSensorEntityDescription(
                key=Attribute.THERMOSTAT_SETPOINT,
                translation_key="thermostat_setpoint",
                device_class=SensorDeviceClass.TEMPERATURE,
                entity_category=EntityCategory.DIAGNOSTIC,
            )
        ]
    },
    Capability.THREE_AXIS: {
        Attribute.THREE_AXIS: [
            SmartThingsSensorEntityDescription(
                key="x_coordinate",
                translation_key="x_coordinate",
                value_fn=lambda value: value[0],
            ),
            SmartThingsSensorEntityDescription(
                key="y_coordinate",
                translation_key="y_coordinate",
                value_fn=lambda value: value[1],
            ),
            SmartThingsSensorEntityDescription(
                key="z_coordinate",
                translation_key="z_coordinate",
                value_fn=lambda value: value[2],
            ),
        ]
    },
    Capability.TV_CHANNEL: {
        Attribute.TV_CHANNEL: [
            SmartThingsSensorEntityDescription(
                key=Attribute.TV_CHANNEL,
                translation_key="tv_channel",
            )
        ],
        Attribute.TV_CHANNEL_NAME: [
            SmartThingsSensorEntityDescription(
                key=Attribute.TV_CHANNEL_NAME,
                translation_key="tv_channel_name",
            )
        ],
    },
    Capability.TVOC_MEASUREMENT: {
        Attribute.TVOC_LEVEL: [
            SmartThingsSensorEntityDescription(
                key=Attribute.TVOC_LEVEL,
                device_class=SensorDeviceClass.VOLATILE_ORGANIC_COMPOUNDS_PARTS,
                native_unit_of_measurement=CONCENTRATION_PARTS_PER_MILLION,
                state_class=SensorStateClass.MEASUREMENT,
            )
        ]
    },
    Capability.ULTRAVIOLET_INDEX: {
        Attribute.ULTRAVIOLET_INDEX: [
            SmartThingsSensorEntityDescription(
                key=Attribute.ULTRAVIOLET_INDEX,
                translation_key="uv_index",
                state_class=SensorStateClass.MEASUREMENT,
            )
        ]
    },
    Capability.VERY_FINE_DUST_HEALTH_CONCERN: {
        Attribute.VERY_FINE_DUST_HEALTH_CONCERN: [
            SmartThingsSensorEntityDescription(
                key=Attribute.VERY_FINE_DUST_HEALTH_CONCERN,
                translation_key="pm1_health_concern",
                device_class=SensorDeviceClass.ENUM,
                options=list(HEALTH_CONCERN.values()),
                value_fn=HEALTH_CONCERN.get,
            )
        ]
    },
    Capability.VERY_FINE_DUST_SENSOR: {
        Attribute.VERY_FINE_DUST_LEVEL: [
            SmartThingsSensorEntityDescription(
                key=Attribute.VERY_FINE_DUST_LEVEL,
                native_unit_of_measurement=CONCENTRATION_MICROGRAMS_PER_CUBIC_METER,
                device_class=SensorDeviceClass.PM1,
                state_class=SensorStateClass.MEASUREMENT,
            )
        ]
    },
    Capability.VOLTAGE_MEASUREMENT: {
        Attribute.VOLTAGE: [
            SmartThingsSensorEntityDescription(
                key=Attribute.VOLTAGE,
                device_class=SensorDeviceClass.VOLTAGE,
                state_class=SensorStateClass.MEASUREMENT,
            )
        ]
    },
    # part of the proposed spec
    Capability.WASHER_MODE: {
        Attribute.WASHER_MODE: [
            SmartThingsSensorEntityDescription(
                key=Attribute.WASHER_MODE,
                translation_key="washer_mode",
                entity_category=EntityCategory.DIAGNOSTIC,
            )
        ]
    },
    Capability.WASHER_OPERATING_STATE: {
        Attribute.MACHINE_STATE: [
            SmartThingsSensorEntityDescription(
                key=Attribute.MACHINE_STATE,
                translation_key="washer_machine_state",
                options=WASHER_OPTIONS,
                device_class=SensorDeviceClass.ENUM,
                component_fn=lambda component: component == "sub",
                component_translation_key={
                    "sub": "washer_sub_machine_state",
                },
            )
        ],
        Attribute.WASHER_JOB_STATE: [
            SmartThingsSensorEntityDescription(
                key=Attribute.WASHER_JOB_STATE,
                translation_key="washer_job_state",
                options=[
                    "air_wash",
                    "ai_rinse",
                    "ai_spin",
                    "ai_wash",
                    "cooling",
                    "delay_wash",
                    "drying",
                    "finish",
                    "none",
                    "pre_wash",
                    "rinse",
                    "spin",
                    "wash",
                    "weight_sensing",
                    "wrinkle_prevent",
                    "freeze_protection",
                ],
                device_class=SensorDeviceClass.ENUM,
                value_fn=lambda value: JOB_STATE_MAP.get(value, value),
                component_fn=lambda component: component == "sub",
                component_translation_key={
                    "sub": "washer_sub_job_state",
                },
            )
        ],
        Attribute.COMPLETION_TIME: [
            SmartThingsSensorEntityDescription(
                key=Attribute.COMPLETION_TIME,
                translation_key="completion_time",
                device_class=SensorDeviceClass.TIMESTAMP,
                value_fn=dt_util.parse_datetime,
                component_fn=lambda component: component == "sub",
                component_translation_key={
                    "sub": "washer_sub_completion_time",
                },
            )
        ],
    },
    Capability.SAMSUNG_CE_WATER_CONSUMPTION_REPORT: {
        Attribute.WATER_CONSUMPTION: [
            SmartThingsSensorEntityDescription(
                key=Attribute.WATER_CONSUMPTION,
                translation_key="water_consumption",
                state_class=SensorStateClass.TOTAL_INCREASING,
                device_class=SensorDeviceClass.WATER,
                native_unit_of_measurement=UnitOfVolume.LITERS,
                value_fn=lambda value: value["cumulativeAmount"] / 1000,
            )
        ]
    },
    Capability.SAMSUNG_CE_HOOD_FILTER: {
        Attribute.HOOD_FILTER_USAGE: [
            SmartThingsSensorEntityDescription(
                key=Attribute.HOOD_FILTER_USAGE,
                translation_key="hood_filter_usage",
                state_class=SensorStateClass.MEASUREMENT,
                native_unit_of_measurement=PERCENTAGE,
                entity_category=EntityCategory.DIAGNOSTIC,
            )
        ]
    },
}


UNITS = {
    "C": UnitOfTemperature.CELSIUS,
    "F": UnitOfTemperature.FAHRENHEIT,
    "ccf": UnitOfVolume.CENTUM_CUBIC_FEET,
    "lux": LIGHT_LUX,
    "mG": None,
    "μg/m^3": CONCENTRATION_MICROGRAMS_PER_CUBIC_METER,
    "kPa": UnitOfPressure.KPA,
}


async def async_setup_entry(
    hass: HomeAssistant,
    entry: SmartThingsConfigEntry,
    async_add_entities: AddConfigEntryEntitiesCallback,
) -> None:
    """Add sensors for a config entry."""
    entry_data = entry.runtime_data
    entities = []

    entity_registry = er.async_get(hass)

    for device in entry_data.devices.values():  # pylint: disable=too-many-nested-blocks
        for capability, attributes in CAPABILITY_TO_SENSORS.items():
            for component, capabilities in device.status.items():
                if capability in capabilities:
                    for attribute, descriptions in attributes.items():
                        for description in descriptions:
                            if (
                                (
                                    not description.capability_ignore_list
                                    or not any(
                                        all(
                                            capability in device.status[MAIN]
                                            for capability in capability_list
                                        )
                                        for capability_list in description.capability_ignore_list
                                    )
                                )
                                and (
                                    not description.exists_fn
                                    or (
                                        component == MAIN
                                        and description.exists_fn(
                                            device.status[MAIN][capability][attribute]
                                        )
                                    )
                                )
                                and (
                                    component == MAIN
                                    or (
                                        description.component_fn is not None
                                        and description.component_fn(component)
                                    )
                                )
                            ):
                                if (
                                    description.deprecated
                                    and (
                                        deprecation_info := description.deprecated(
                                            device.status[MAIN]
                                        )
                                    )
                                    is not None
                                ):
                                    version, reason = deprecation_info
                                    if deprecate_entity(
                                        hass,
                                        entity_registry,
                                        SENSOR_DOMAIN,
                                        f"{device.device.device_id}_{MAIN}_{capability}_{attribute}_{description.key}",
                                        f"deprecated_{reason}",
                                        version,
                                    ):
                                        entities.append(
                                            SmartThingsSensor(
                                                entry_data.client,
                                                device,
                                                description,
                                                MAIN,
                                                capability,
                                                attribute,
                                            )
                                        )
                                    continue
                                entities.append(
                                    SmartThingsSensor(
                                        entry_data.client,
                                        device,
                                        description,
                                        component,
                                        capability,
                                        attribute,
                                    )
                                )

    async_add_entities(entities)


class SmartThingsSensor(SmartThingsEntity, SensorEntity):
    """Define a SmartThings Sensor."""

    entity_description: SmartThingsSensorEntityDescription

    def __init__(
        self,
        client: SmartThings,
        device: FullDevice,
        entity_description: SmartThingsSensorEntityDescription,
        component: str,
        capability: Capability,
        attribute: Attribute,
    ) -> None:
        """Init the class."""
        capabilities_to_subscribe = {capability}
        if entity_description.use_temperature_unit:
            capabilities_to_subscribe.add(Capability.TEMPERATURE_MEASUREMENT)
        super().__init__(client, device, capabilities_to_subscribe, component=component)
        self._attr_unique_id = f"{device.device.device_id}_{component}_{capability}_{attribute}_{entity_description.key}"
        self._attribute = attribute
        self.capability = capability
        self.entity_description = entity_description
        if self.entity_description.translation_placeholders_fn:
            self._attr_translation_placeholders = (
                self.entity_description.translation_placeholders_fn(component)
            )
        if self.entity_description.component_translation_key and component != MAIN:
            self._attr_translation_key = (
                self.entity_description.component_translation_key.get(component)
            )

    @property
    def native_value(self) -> str | float | datetime | int | None:
        """Return the state of the sensor."""
        res = self.get_attribute_value(self.capability, self._attribute)
        if options_map := self.entity_description.options_map:
            return options_map.get(res)
        return self.entity_description.value_fn(res)

    @property
    def native_unit_of_measurement(self) -> str | None:
        """Return the unit this state is expressed in."""
        if self.entity_description.use_temperature_unit:
            unit = self._internal_state[Capability.TEMPERATURE_MEASUREMENT][
                Attribute.TEMPERATURE
            ].unit
        else:
            unit = self._internal_state[self.capability][self._attribute].unit
        return (
            UNITS.get(unit, unit)
            if unit
            else self.entity_description.native_unit_of_measurement
        )

    @property
    def extra_state_attributes(self) -> Mapping[str, Any] | None:
        """Return the state attributes."""
        if self.entity_description.extra_state_attributes_fn:
            return self.entity_description.extra_state_attributes_fn(
                self.get_attribute_value(self.capability, self._attribute)
            )
        return None

    @property
    def options(self) -> list[str] | None:
        """Return the options for this sensor."""
        if self.entity_description.options_attribute:
            if (
                options := self.get_attribute_value(
                    self.capability, self.entity_description.options_attribute
                )
            ) is None:
                return []
            if options_map := self.entity_description.options_map:
                return [options_map[option] for option in options]
            return [option.lower() for option in options]
        return super().options
