#!/usr/bin/env python
# -*- coding: utf-8 -*-
#
from devices.base import base
from devices.base import BATTERY_WARN_LEVEL
from devices.base import warning
import logging


class tradfri_light(base):
    """ Communication (MQTT)

        tradfri_light {
                    |      "state": ["ON" / "OFF" / "TOGGLE"]
                    |      "linkquality": [0...255] lqi
                    |      "brightness": [0...254]
                    |      "color_mode": ["color_temp"]
                    |      "color_temp": ["coolest", "cool", "neutral", "warm", "warmest", 250...454]
                    |      "color_temp_startup": ["coolest", "cool", "neutral", "warm", "warmest", "previous", 250...454]
                    |      "update": []
                    | }
                    +- get {
                    |           "state": ""
                    |      }
                    +- set {
                                "state": ["ON" / "OFF"]
                                "brightness": [0...256]
                                "color_temp": [250...454]
                                "transition": [0...] seconds
                                "brightness_move": [-X...0...X] X/s
                                "brightness_step": [-X...0...X]
                                "color_temp_move": [-X...0...X] X/s
                                "color_temp_step": [-X...0...X]
                            }
    """
    KEY_LINKQUALITY = "linkquality"
    KEY_OUTPUT_0 = "state"
    KEY_BRIGHTNESS = "brightness"
    KEY_COLOR_TEMP = "color_temp"
    KEY_BRIGHTNESS_FADE = "brightness_move"
    #
    TX_TYPE = base.TX_DICT
    TX_FILTER_DATA_KEYS = [KEY_OUTPUT_0, KEY_BRIGHTNESS, KEY_COLOR_TEMP, KEY_BRIGHTNESS_FADE]
    #
    RX_KEYS = [KEY_LINKQUALITY, KEY_OUTPUT_0, KEY_BRIGHTNESS, KEY_COLOR_TEMP]
    RX_IGNORE_KEYS = ['update', 'color_mode', 'color_temp_startup']
    RX_FILTER_DATA_KEYS = [KEY_OUTPUT_0, KEY_BRIGHTNESS, KEY_COLOR_TEMP]

    def __state_logging__(self, inst, key, data):
        if key in [self.KEY_OUTPUT_0, self.KEY_BRIGHTNESS, self.KEY_COLOR_TEMP, self.KEY_BRIGHTNESS_FADE]:
            self.logger.info("State change of '%s' to '%s'", key, repr(data))

    def __device_to_instance_filter__(self, key, data):
        if key == self.KEY_BRIGHTNESS:
            return int(round((data - 1) * 100 / 253, 0))
        elif key == self.KEY_COLOR_TEMP:
            return int(round((data - 250) * 10 / 204, 0))
        return super().__device_to_instance_filter__(key, data)

    def __instance_to_device_filter__(self, key, data):
        if key == self.KEY_BRIGHTNESS:
            return int(round(data * 253 / 100 + 1, 0))
        elif key == self.KEY_COLOR_TEMP:
            return int(round(data * 204 / 10 + 250, 0))
        return super().__instance_to_device_filter__(key, data)

    #
    # RX
    #
    @property
    def output_0(self):
        """rv: [True, False]"""
        return self.get(self.KEY_OUTPUT_0, False)

    @property
    def linkquality(self):
        """rv: numeric value"""
        return self.get(self.KEY_LINKQUALITY, 0)

    @property
    def brightness(self):
        """rv: numeric value [0%, ..., 100%]"""
        return self.get(self.KEY_BRIGHTNESS, 0)

    @property
    def color_temp(self):
        """rv: numeric value [0, ..., 10]"""
        return self.get(self.KEY_COLOR_TEMP, 0)

    #
    # TX
    #
    def request_data(self, device=None, key=None, data=None):
        self.mqtt_client.send(self.topic + "/get", '{"%s": ""}' % self.KEY_OUTPUT_0)

    def set_output_0(self, state):
        """state: [True, False]"""
        self.send_command(self.KEY_OUTPUT_0, state)

    def set_output_0_mcb(self, device, key, data):
        self.set_output_0(data)

    def toggle_output_0_mcb(self, device, key, data):
        self.set_output_0(not self.output_0)

    def set_brightness(self, brightness):
        """brightness: [0, ..., 100]"""
        self.send_command(self.KEY_BRIGHTNESS, brightness)

    def set_brightness_mcb(self, device, key, data):
        self.set_brightness(data)

    def default_inc(self, speed=40):
        self.send_command(self.KEY_BRIGHTNESS_FADE, speed)

    def default_dec(self, speed=-40):
        self.default_inc(speed)

    def default_stop(self):
        self.default_inc(0)

    def set_color_temp(self, color_temp):
        """color_temp: [0, ..., 10]"""
        self.send_command(self.KEY_COLOR_TEMP, color_temp)

    def set_color_temp_mcb(self, device, key, data):
        self.set_color_temp(data)

    def all_off(self):
        if self.output_0:
            self.set_output_0(False)


class tradfri_button(base):
    """ Communication (MQTT)

        tradfri_button {
                            "action": [
                                           "arrow_left_click",
                                           "arrow_left_hold",
                                           "arrow_left_release",
                                           "arrow_right_click",
                                           "arrow_right_hold",
                                           "arrow_right_release",
                                           "brightness_down_click",
                                           "brightness_down_hold",
                                           "brightness_down_release",
                                           "brightness_up_click",
                                           "brightness_up_hold",
                                           "brightness_up_release",
                                           "toggle"
                                      ]
                            "action_duration": [0...] s
                            "battery": [0...100] %
                            "linkquality": [0...255] lqi
                            "update": []
                       }
    """
    ACTION_TOGGLE = "toggle"
    ACTION_BRIGHTNESS_UP = "brightness_up_click"
    ACTION_BRIGHTNESS_DOWN = "brightness_down_click"
    ACTION_RIGHT = "arrow_right_click"
    ACTION_LEFT = "arrow_left_click"
    ACTION_BRIGHTNESS_UP_LONG = "brightness_up_hold"
    ACTION_BRIGHTNESS_UP_RELEASE = "brightness_up_release"
    ACTION_BRIGHTNESS_DOWN_LONG = "brightness_down_hold"
    ACTION_BRIGHTNESS_DOWN_RELEASE = "brightness_down_release"
    ACTION_RIGHT_LONG = "arrow_right_hold"
    ACTION_RIGHT_RELEASE = "arrow_right_release"
    ACTION_LEFT_LONG = "arrow_left_hold"
    ACTION_LEFT_RELEASE = "arrow_left_release"
    #
    KEY_LINKQUALITY = "linkquality"
    KEY_BATTERY = "battery"
    KEY_ACTION = "action"
    KEY_ACTION_DURATION = "action_duration"
    #
    RX_KEYS = [KEY_LINKQUALITY, KEY_BATTERY, KEY_ACTION]
    RX_IGNORE_KEYS = ['update', KEY_ACTION_DURATION]

    def __init__(self, mqtt_client, topic):
        super().__init__(mqtt_client, topic)
        #
        self.add_callback(self.KEY_BATTERY, None, self.__warning__, True)
        self.__battery_warning__ = False

    def __state_logging__(self, inst, key, data):
        if key in [self.KEY_ACTION]:
            self.logger.info("Input '%s' with '%s'", key, repr(data))

    #
    # WARNING CALL
    #
    def __warning__(self, client, key, data):
        if data <= BATTERY_WARN_LEVEL:
            if not self.__battery_warning__:
                w = warning(self.topic, warning.TYPE_BATTERY_LOW, "Battery low (%.1f%%)", data)
                self.logger.warning(w)
                self.set(self.KEY_WARNING, w)
        else:
            self.__battery_warning__ = False

    #
    # RX
    #
    @property
    def action(self):
        """rv: action_txt"""
        return self.get(self.KEY_ACTION)