"""
DY-YG400A Smoke Sensor, TS0601 from _TZE204_ntcy3xu1
https://www.aliexpress.com/item/1005005863519099.html
https://www.aliexpress.com/item/1005005854203557.html
"""

import logging

import zigpy.profiles.zha
from zigpy.quirks import CustomDevice
import zigpy.types as t
from zigpy.zcl.clusters.general import (
    Basic,
    Groups,
    Ota,
    Scenes,
    Time,
    BinaryInput,
    BatterySize,
)
from zigpy.zcl.clusters.security import IasZone
from zhaquirks import Bus
from zhaquirks.const import (
    DEVICE_TYPE,
    ENDPOINTS,
    INPUT_CLUSTERS,
    MODELS_INFO,
    OUTPUT_CLUSTERS,
    PROFILE_ID,
    ZONE_TYPE,
)
from zhaquirks.tuya import (
    TuyaLocalCluster,
    TuyaManufCluster,
    TuyaManufClusterAttributes,
    TuyaPowerConfigurationCluster,
)

_LOGGER = logging.getLogger(__name__)

TUYA_SMOKE_DETECTED_ATTR = 0x0401  # [0]/[1] [Detected]/[Clear]!
TUYA_SMOKE_TAMPERED_ATTR = 0x0104  # [0]/[1] [Clear]/[Tampered]!
TUYA_SMOKE_BATTERY_ATTR = 0x040e  # [0]/[1]/[2] [Low]/[Med]]/[Full]!


class TuyaSmokeDetectorCluster(TuyaManufClusterAttributes):
    """Manufacturer Specific Cluster of the TS0601 smoke detector."""

    attributes = {
        TUYA_SMOKE_DETECTED_ATTR: ("smoke_detected", t.uint8_t, True),
        TUYA_SMOKE_TAMPERED_ATTR: ("tampered_device", t.uint8_t, True),
        TUYA_SMOKE_BATTERY_ATTR: ("battery_status", t.uint8_t, True),
    }

    def _update_attribute(self, attrid, value):
        super()._update_attribute(attrid, value)
        if attrid == TUYA_SMOKE_DETECTED_ATTR:
            status = IasZone.ZoneStatus.Alarm_1 if value == 0 else 0
            self.endpoint.device.ias_bus.listener_event("update_attribute", "zone_status", status)
        elif attrid == TUYA_SMOKE_TAMPERED_ATTR:
            self.endpoint.device.tamper_detection_bus.listener_event(
                "update_attribute", "present_value", bool(value)
            )
        elif attrid == TUYA_SMOKE_BATTERY_ATTR:
            batt = 5 if value == 0 else 40 if value == 1 else 100
            self.endpoint.device.battery_bus.listener_event("battery_change", batt)
        else:
            _LOGGER.warning(
                "[0x%04x:%s:0x%04x] unhandled attribute: 0x%04x",
                self.endpoint.device.nwk,
                self.endpoint.endpoint_id,
                self.cluster_id,
                attrid,
            )


class TuyaIasZone(TuyaLocalCluster, IasZone):
    """
    IAS Zone: this generates the "Smoke" entity for HA.
    Receives updates from TuyaSmokeDetectorCluster.
    """

    _CONSTANT_ATTRIBUTES = {ZONE_TYPE: IasZone.ZoneType.Fire_Sensor}

    def __init__(self, *args, **kwargs):
        """Init."""
        super().__init__(*args, **kwargs)
        self.endpoint.device.ias_bus.add_listener(self)


class TuyaPowerConfigCluster(TuyaPowerConfigurationCluster):
    """
    Power Config Cluster: this generates the "Battery" entity for HA.
    Receives updates from TuyaSmokeDetectorCluster.
    """

    _CONSTANT_ATTRIBUTES = {
        TuyaPowerConfigurationCluster.attributes_by_name["battery_size"].id: BatterySize.AAA,
        TuyaPowerConfigurationCluster.attributes_by_name["battery_quantity"].id: 2,
        TuyaPowerConfigurationCluster.attributes_by_name["battery_rated_voltage"].id: 15,
    }


class TuyaTamperDetection(TuyaLocalCluster, BinaryInput):
    """
    Tamper Detection Cluster: this generates the "Binary input" entity for HA, which is updated
    with the Tampered state. Receives updates from TuyaSmokeDetectorCluster.
    """

    _CONSTANT_ATTRIBUTES = {
        BinaryInput.attributes_by_name["description"].id: "Tamper Detected",
        BinaryInput.attributes_by_name["active_text"].id: "Tampered",
        BinaryInput.attributes_by_name["inactive_text"].id: "Clear",
    }

    def __init__(self, *args, **kwargs):
        """Init."""
        super().__init__(*args, **kwargs)
        self.endpoint.device.tamper_detection_bus.add_listener(self)


class TuyaSmokeDetector0601(CustomDevice):
    """TS0601 Smoke detector quirk."""

    def __init__(self, *args, **kwargs):
        """Init."""
        self.ias_bus = Bus()
        self.battery_bus = Bus()
        self.tamper_detection_bus = Bus()
        super().__init__(*args, **kwargs)

    signature = {
        MODELS_INFO: [
            """("_TZE200_uebojraa", "TS0601"),"""
            ("_TZE200_uebojraa"),
        ],
        ENDPOINTS: {
            1: {
                PROFILE_ID: zigpy.profiles.zha.PROFILE_ID,
                DEVICE_TYPE: zigpy.profiles.zha.DeviceType.SMART_PLUG,
                INPUT_CLUSTERS: [
                    Basic.cluster_id,
                    Groups.cluster_id,
                    Scenes.cluster_id,
                    TuyaManufCluster.cluster_id,
                ],
                OUTPUT_CLUSTERS: [
                    Time.cluster_id,
                    Ota.cluster_id,
                ],
            },
        },
    }

    replacement = {
        ENDPOINTS: {
            1: {
                PROFILE_ID: zigpy.profiles.zha.PROFILE_ID,
                DEVICE_TYPE: zigpy.profiles.zha.DeviceType.IAS_ZONE,
                INPUT_CLUSTERS: [
                    Basic.cluster_id,
                    Groups.cluster_id,
                    Scenes.cluster_id,
                    TuyaIasZone,
                    TuyaSmokeDetectorCluster,
                    TuyaPowerConfigCluster,
                    TuyaTamperDetection,
                ],
                OUTPUT_CLUSTERS: [
                    Time.cluster_id,
                    Ota.cluster_id,
                ],
            },
        },
    }