import paho.mqtt.client as mqtt
import re
import datetime

from .payload.relay import (
    PowerPayload,
)
from .esp import MqttEspBase


class MqttRelay(MqttEspBase):
    TOPIC_LEAF = 'relay'

    def set_power(self, device_id, enable: bool, secret=None):
        device = next(d for d in self._devices if d.id == device_id)
        secret = secret if secret else device.secret

        assert secret is not None, 'device secret not specified'

        payload = PowerPayload(secret=secret,
                               state=enable)
        self._client.publish(f'hk/{device.id}/{self.TOPIC_LEAF}/power',
                             payload=payload.pack(),
                             qos=1)
        self._client.loop_write()

    def on_message(self, client: mqtt.Client, userdata, msg):
        if super().on_message(client, userdata, msg):
            return

        try:
            match = re.match(self.get_mqtt_topics(['power']), msg.topic)
            if not match:
                return

            device_id = match.group(1)
            subtopic = match.group(2)

            message = None
            if subtopic == 'power':
                message = PowerPayload.unpack(msg.payload)

            if message and self._message_callback:
                self._message_callback(device_id, message)

        except Exception as e:
            self._logger.exception(str(e))


class MqttRelayState:
    enabled: bool
    update_time: datetime.datetime
    rssi: int
    fw_version: int
    ever_updated: bool

    def __init__(self):
        self.ever_updated = False
        self.enabled = False
        self.rssi = 0

    def update(self,
               enabled: bool,
               rssi: int,
               fw_version=None):
        self.ever_updated = True
        self.enabled = enabled
        self.rssi = rssi
        self.update_time = datetime.datetime.now()
        if fw_version:
            self.fw_version = fw_version
