import asyncio
import logging
import re

from .. import fhem
from .. import generic

from pyit600.exceptions import IT600AuthenticationError, IT600ConnectionError
from pyit600.gateway_singleton import IT600GatewaySingleton

_LOGGER = logging.getLogger(__name__)

class pyit600(generic.FhemModule):
    def __init__(self, logger):
        super().__init__(logger)

        self.attr_config = {
            "update_interval": {
                "default": 60,
                "format": "int",
                "help": "Readings update intervall in seconds (default 60s).",
            },
            "update_readings": {
                "default": "always",
                "options": "always,onchange",
                "help": "Update readings only on value change or always (default onchange).",
            },
        }
        self.set_attr_config(self.attr_config)

    # FHEM FUNCTION
    async def Define(self, hash, args, argsh):
        await super().Define(hash, args, argsh)
        if len(args) != 5:
            return (
                "Usage: define my_salus_device fhempy pyit600 host euid"
            )
        self.host = args[3]
        self.euid = args[4]
        self.debug = 1
        _LOGGER.debug(f'host: %s, euid: %s',self.host, self.euid)
        self.create_async_task(self.start_login())
        await fhem.readingsSingleUpdate(self.hash, "state", "connecting", 1)

    async def start_login(self):
        async with IT600GatewaySingleton.get_instance(host=self.host, euid=self.euid, debug=self.debug) as self.gateway:
            try:
                await self.gateway.connect()
                await self.gateway.poll_status(send_callback=False)
            except IT600ConnectionError:
                await fhem.readingsSingleUpdate(self.hash, "state", "Connection error", 1)
                _LOGGER.info(f'Connection error: check if you have specified gateway')
            except IT600AuthenticationError:
                await fhem.readingsSingleUpdate(self.hash, "state", "Authentication error", 1)
                _LOGGER.info(f'Authentication error: check if you have specified gateway EUID is correctly.')

            self.prepare_set_commands()
            await self.update_readings()

    def prepare_set_commands(self):
        self.set_config = {
            "target_temperature" : {
                "args": ["climate_device_id", "temperature"],
                "params": {
                    "climate_device_id": {"format": "str"},
                    "temperature": {"default": 23, "format": "float"}},
                "help": (
                    "Parameters: ID Temperature) <br>"
                    "e.g. set target_temperature 001e5e09020770e3 23<br>"
                )
            }
        }
        self.set_set_config(self.set_config)

    async def set_target_temperature(self, hash, params):
        self.create_async_task(
            self.gateway.set_climate_device_temperature(params["climate_device_id"], params["temperature"])
        )

    async def update_readings(self):
        while True:
            await self.update_readings_once()
            await asyncio.sleep(self._attr_update_interval)

    async def update_readings_once(self):
        await self.gateway.poll_status(send_callback=False)
        try:
            climate_devices = self.gateway.get_climate_devices()

            if not climate_devices:
                await fhem.readingsSingleUpdate(self.hash, "state", "No device found", 1)
            else:
                await fhem.readingsSingleUpdateIfChanged(self.hash, "state", "online", 1)

                for climate_device_id in climate_devices:
                    if self._attr_update_readings == "always":
                        await fhem.readingsSingleUpdate(
                            self.hash, climate_device_id, climate_devices.get(climate_device_id), 1)
                        try:
                            name = re.search('name=''(.+?)'',', str(climate_devices.get(climate_device_id))).group(1)
                            name = name.replace(" ", "")
                            name = name.replace("'", "")
                            curtemp = re.search('current_temperature=(.+?),', str(climate_devices.get(climate_device_id))).group(1)
                            if name == 'unknown':
                                await fhem.readingsSingleUpdate(self.hash, climate_device_id + "_curtemp", curtemp, 1)
                            else:
                                await fhem.readingsSingleUpdate(self.hash, name + "_curtemp", curtemp, 1)
                        except AttributeError:
                            _LOGGER.info(f'Error on reading device name or current temperature!')

                        try:
                            name = re.search('name=''(.+?)'',', str(climate_devices.get(climate_device_id))).group(1)
                            name = name.replace(" ", "")
                            name = name.replace("'", "")
                            targtemp = re.search('target_temperature=(.+?),', str(climate_devices.get(climate_device_id))).group(1)
                            if name == 'unknown':
                                await fhem.readingsSingleUpdate(self.hash, climate_device_id + "_targtemp", targtemp, 1)
                            else:
                                await fhem.readingsSingleUpdate(self.hash, name + "_targtemp", targtemp, 1)
                        except AttributeError:
                            _LOGGER.info(f'Error on reading device name or target temperature!')

                    else:
                        await fhem.readingsSingleUpdateIfChanged(
                            self.hash, climate_device_id, climate_devices.get(climate_device_id), 1)
                        try:
                            name = re.search('name=''(.+?)'',', str(climate_devices.get(climate_device_id))).group(1)
                            name = name.replace(" ", "")
                            name = name.replace("'", "")
                            curtemp = re.search('current_temperature=(.+?),', str(climate_devices.get(climate_device_id))).group(1)
                            if name == 'unknown':
                                await fhem.readingsSingleUpdateIfChanged(self.hash, climate_device_id + "_curtemp", curtemp, 1)
                            else:
                                await fhem.readingsSingleUpdateIfChanged(self.hash, name + "_curtemp", curtemp, 1)
                        except AttributeError:
                            _LOGGER.info(f'Error on reading device name or current temperature!')

                        try:
                            name = re.search('name=''(.+?)'',', str(climate_devices.get(climate_device_id))).group(1)
                            name = name.replace(" ", "")
                            name = name.replace("'", "")
                            targtemp = re.search('target_temperature=(.+?),', str(climate_devices.get(climate_device_id))).group(1)
                            if name == 'unknown':
                                await fhem.readingsSingleUpdateIfChanged(self.hash, climate_device_id + "_targtemp", targtemp, 1)
                            else:
                                await fhem.readingsSingleUpdateIfChanged(self.hash, name + "_targtemp", targtemp, 1)
                        except AttributeError:
                            _LOGGER.info(f'Error on reading device name or target temperature!')

        except Exception:
            self.logger.exception("Failed to update readings")