#!/usr/bin/env python
# -*- coding: utf-8 -*-
#
import config
from devdi import rooms as devdi_rooms
from devdi.topic import STOP_EXECUTION_TOPIC
from function.garden import garden
from function.stairway import stairway
from function.ground_floor_west import ground_floor_west
from function.first_floor_west import first_floor_west
from function.first_floor_east import first_floor_east
from function.rooms import room_collection
import json
import logging
import mqtt

try:
    from config import APP_NAME as ROOT_LOGGER_NAME
except ImportError:
    ROOT_LOGGER_NAME = 'root'
logger = logging.getLogger(ROOT_LOGGER_NAME).getChild(__name__)


class all_functions(room_collection, devdi_rooms.collection):
    def __init__(self, mqtt_client: mqtt.mqtt_client):
        super().__init__(mqtt_client)
        devdi_rooms.collection.__init__(self, mqtt_client)
        #
        self.run = True
        if config.DEBUG:
            mqtt_client.add_callback(STOP_EXECUTION_TOPIC, self.__stop_execution__)
        #
        # Rooms
        #
        # garden
        self.gar = garden(self.mqtt_client)
        # stairway
        self.stw = stairway(self.mqtt_client)
        # ground floor west
        self.gfw = ground_floor_west(self.mqtt_client)
        # first floor west
        self.ffw = first_floor_west(self.mqtt_client)
        # first floor east
        self.ffe = first_floor_east(self.mqtt_client)
        #
        # Interactions
        #
        # cross_room_interactions
        self.init_cross_room_interactions()
        # Off Buttons
        self.init_off_functionality()
        # Summer / Winter mode
        self.init_sumer_winter_mode()

    def __stop_execution__(self, client, userdata, message):
        if config.DEBUG:
            try:
                data = json.loads(message.payload)
            except:
                logger.error("Error while receiving mqtt message: topic=%s - payload=%s", repr(message.topic), repr(message.payload))
            else:
                if data is True:
                    self.run = False

    def init_cross_room_interactions(self):
        # shelly dirk input 1
        self.last_gfw_dirk_input_1 = None
        self.gfw.dirk.switch_main_light.add_callback(self.gfw.dirk.switch_main_light.KEY_INPUT_1, None, self.gfw_dirk_input_1)
        # tradfri button ffe_sleep right click
        self.ffe.sleep.input_device.add_callback(self.ffe.sleep.input_device.KEY_ACTION,
                                                 self.ffe.sleep.input_device.ACTION_RIGHT, self.ffe.floor.switch_main_light.toggle_output_0_mcb)

    def init_off_functionality(self):
        # ALL OFF - Virtual device
        self.videv_all_off.connect_room_collection(self)

        # ALL OFF - Long push stairway
        self.stw.stairway.switch_main_light.add_callback(self.stw.stairway.switch_main_light.KEY_LONGPUSH_0,
                                                         True, self.stw.stairway.switch_main_light.flash_0_mcb)
        self.stw.stairway.switch_main_light.add_callback(self.stw.stairway.switch_main_light.KEY_LONGPUSH_0, True, self.all_off)

        # FFE ALL OFF - Long push ffe_floor
        self.ffe.floor.switch_main_light.add_callback(self.ffe.floor.switch_main_light.KEY_LONGPUSH_0,
                                                      True, self.ffe.floor.switch_main_light.flash_0_mcb)
        self.ffe.floor.switch_main_light.add_callback(self.ffe.floor.switch_main_light.KEY_LONGPUSH_0, True, self.ffe.all_off)

        # FFE ALL OFF - Long push input device
        self.ffe.sleep.input_device.add_callback(self.ffe.sleep.input_device.KEY_ACTION,
                                                 self.ffe.sleep.input_device.ACTION_RIGHT_LONG, self.ffe.all_off)

        # FFW ALL OFF - Long push ffw_floor
        self.ffw.floor.switch_main_light.add_callback(self.ffw.floor.switch_main_light.KEY_LONGPUSH_0,
                                                      True, self.ffw.floor.switch_main_light.flash_0_mcb)
        self.ffw.floor.switch_main_light.add_callback(self.ffw.floor.switch_main_light.KEY_LONGPUSH_0, True, self.ffw.all_off)

    def init_sumer_winter_mode(self):
        self.videv_summer_mode.add_callback(self.videv_summer_mode.KEY_STATE, None, self.gfw.summer_mode)
        self.videv_summer_mode.add_callback(self.videv_summer_mode.KEY_STATE, None, self.ffw.summer_mode)
        self.videv_summer_mode.add_callback(self.videv_summer_mode.KEY_STATE, None, self.ffe.summer_mode)

    def gfw_dirk_input_1(self, device, key, data):
        if self.last_gfw_dirk_input_1 is not None:
            if self.last_gfw_dirk_input_1 != data:
                self.gfw.floor.switch_main_light.toggle_output_0_mcb(device, key, data)
        self.last_gfw_dirk_input_1 = data
