from typing import Dict, Union
from BaseUtility import Definitions
from etl.epc_clean.epc_attributes.attribute_utils import clean_description, find_keyword, handle_mixed_translation


class MainheatControlAttributes(Definitions):
    # These systems allow for the automatic regulation of temperature
    THERMOSTATIC_CONTROL_KEYWORDS = [
        'room thermostats',
        'appliance thermostats',
        'room thermostat',
        'temperature zone control',
        'time and temperature zone control',
        'celect-type control'  # This is a specific type of thermostat controls
        # 'no thermostatic control',
        # 'no room thermostat'
    ]

    # TRVs stands for Thermostatic Radiator Valves which control the heating temperature of individual radiators
    # This is split out distinctly
    TRVS_KEYWORDS = [
        'trvs',
    ]

    # These systems provide a way to store and manage energy usage
    CHARGING_SYSTEM_KEYWORDS = [
        'charging system',
        'automatic charge control',
        'manual charge control',
        'flat rate charging',
        'high heat retention storage heaters'
    ]

    # These systems are mainly focused on on/off operations
    SWITCH_SYSTEM_KEYWORDS = [
        'programmer',
    ]

    # These systems enhance operation, efficiency, or safety. e.g. a boiler energy manager
    # manages the efficiency of boiler operation. There is an argument to separate 'boiler energy manager' and 'bypass'
    AUXILIARY_SYSTEM_KEYWORDS = [
        'boiler energy manager',
        'bypass',
        'flow switch',
    ]

    # These keywords indicate a lack of control system
    NO_CONTROL_SYSTEM_KEYWORDS = [
        'no time or thermostatic control',
        'no thermostatic control',
        'none',
        'no room thermostat'
    ]

    # These systems provide control specifically for Domestic Hot Water
    DHW_CONTROL_KEYWORDS = [
        'dhw only'
    ]

    # This system indicates the use of community heating
    COMMUNITY_HEATING_KEYWORDS = [
        'use of community heating'
    ]

    MULTIPLE_ROOM_THERMOSTATS_PHRASES = [
        'at least two room stats',
        'at least two room thermostats'
    ]

    RATE_CONTROL_KEYWORDS = [
        'single rate heating',
    ]

    # Sufficiently similar descriptions to be remapped
    TO_REMAP = {
        "celect control": 'celect-type control',
        "celect controls": 'celect-type control',
        "celect type controls": 'celect-type control',
        "trv's, program & flow switch": 'trvs, programmer & flow switch',
        'appliance thermostat': 'appliance thermostats',
    }

    WELSH_TEXT = {
        "rhaglennydd, dim thermostat ystafell": "programmer, no room thermostat",
        "rhaglennydd a thermostat ystafell": "programmer and room thermostat",
        "rheoligçör t+ól +ó llaw": "manual charge control",
        "rheoli'r t+ól +ó llaw": "manual charge control",
        "rheolaeth amser a rheolaeth parthau tymheredd": "time and temperature zone control",
        "rhaglennydd a thermostatau ar y cyfarpar": "programmer, room thermostat",
        "rheolyddion i wresogyddion storio sygçön cadw llawer o wres": "controls for high heat retention storage "
                                                                       "heaters",
        "t+ól un gyfradd, rhaglennydd a thermostat ystafell": "single rate heating, programmer and room thermostat",
        "rhaglennydd ac o leiaf ddau thermostat ystafell": "programmer and at least two room thermostats",
        "thermostat ystafell yn unig": "room thermostat only",
        "dim rheolaeth amser na rheolaeth thermostatig ar dymheredd yr ystafell": "no time or thermostatic control of "
                                                                                  "room temperature",
        "rheoli gwefr drydanol yn awtomatig": "automatic charge control",
        'system dalu wedigçöi chysylltu +ó defnyddio gwres cymunedol, thermostat ystafell yn unig': "charging system "
                                                                                                    "linked to use of"
                                                                                                    " community "
                                                                                                    "heating, "
                                                                                                    "room thermostat "
                                                                                                    "only",
        "dim": "none",
        "dim rheolaeth thermostatig ar dymheredd yr ystafell": "no thermostatic control of room temperature",
        "thermostatau ar y cyfarpar": "appliance thermostats",
        "rhaglennydd a thermostatau ystafell": "programmer and room thermostats",
        "system dalu wedigçöi chysylltu +ó defnyddio gwres cymunedol, rhaglennydd a thermostat ystafell":
            "charging system linked to use of community heating, programmer and room thermostat",
        'system dalu wedigçöi chysylltu +ó defnyddio gwres cymunedol, rhaglennydd a trvs':
            "charging system linked to use of community heating, programmer and trvs",
        'system dalu wedigçöi chysylltu +ó defnyddio gwres cymunedol, trvs':
            'charging system linked to use of community heating, trvs',
        't+-ól un gyfradd, trvs': 'single rate heating, trvs',
        't+ól un gyfradd, rhaglennydd a trvs': 'single rate heating, programmer, trvs',
        't+ól un gyfradd, trvs': 'single rate heating, trvs',
        'trvs a falf osgoi': 'trvs and bypass',
        'rheolaeth celect': 'celect-type control',
        'rheoli r tal a llaw': 'manual charge control',
        'tal un gyfradd, thermostat ystafell yn unig': 'flat rate charging, room thermostat only',
        "rheoli'r t l llaw": "manual charge control",
        "2205 rhaglennydd ac o leiaf ddau thermostat ystafell": "programmer and at least two room thermostats",
        "2603 rhaglennydd a thermostatau ar y cyfarpar": "programmer, room thermostat",
        "2404 rheolyddion i wresogyddion storio sygçön cadw llawer o wres": "controls for high heat retention storage "
                                                                            "heaters",
        'system dalu wedigçöi chysylltu +ó defnyddio gwres cymunedol, rhaglennydd ac o leiaf ddau thermostat '
        'ystafell': 'charging system linked to use of community heating, programmer and at least two room thermostats'

    }

    NO_DATA_DESCRIPTIONS = [
        "SAP05:Main-Heating-Controls",
        "SAP:Main-Heating-Controls",
    ]

    def __init__(self, description: str):

        self.description: str = clean_description(description.lower()).strip()
        # We handle seemind occurances of mixed translations
        self.description = handle_mixed_translation(self.description)
        self.nodata = not self.description or description in self.DATA_ANOMALY_MATCHES or (
            description in self.NO_DATA_DESCRIPTIONS
        )

        translation = self.WELSH_TEXT.get(self.description)
        if translation:
            self.nodata = False
            self.description = translation

        # Remap
        remapped = self.TO_REMAP.get(self.description)
        if remapped:
            self.description = remapped

        if not self.nodata:
            if not any(
                self._keyword_in_description(keywords)
                for keywords in [
                    self.THERMOSTATIC_CONTROL_KEYWORDS,
                    self.CHARGING_SYSTEM_KEYWORDS,
                    self.SWITCH_SYSTEM_KEYWORDS,
                    self.DHW_CONTROL_KEYWORDS,
                    self.COMMUNITY_HEATING_KEYWORDS,
                    self.TRVS_KEYWORDS,
                    self.NO_CONTROL_SYSTEM_KEYWORDS,
                    self.RATE_CONTROL_KEYWORDS
                ]
            ):
                raise ValueError('Invalid description')

    def _keyword_in_description(self, keywords):
        return any(keyword in self.description for keyword in keywords)

    def process(self) -> Dict[str, Union[str, bool, None]]:

        if self.nodata:
            result = {
                "thermostatic_control": False,
                "charging_system": False,
                "switch_system": False,
                "no_control": False,
                "dhw_control": False,
                "community_heating": False,
                "multiple_room_thermostats": False,
                "auxiliary_systems": False,
                "trvs": False,
                "rate_control": False
            }
            return result

        result: Dict[str, Union[str, bool, None]] = {
            "thermostatic_control": find_keyword(self.description, self.THERMOSTATIC_CONTROL_KEYWORDS),
            "charging_system": find_keyword(self.description, self.CHARGING_SYSTEM_KEYWORDS),
            "switch_system": find_keyword(self.description, self.SWITCH_SYSTEM_KEYWORDS),
            "no_control": find_keyword(self.description, self.NO_CONTROL_SYSTEM_KEYWORDS),
            "dhw_control": find_keyword(self.description, self.DHW_CONTROL_KEYWORDS),
            "community_heating": find_keyword(self.description, self.COMMUNITY_HEATING_KEYWORDS),
            "multiple_room_thermostats": any(
                phrase in self.description for phrase in self.MULTIPLE_ROOM_THERMOSTATS_PHRASES
            ),
            "auxiliary_systems": find_keyword(self.description, self.AUXILIARY_SYSTEM_KEYWORDS),
            "trvs": find_keyword(self.description, self.TRVS_KEYWORDS),
            "rate_control": find_keyword(self.description, self.RATE_CONTROL_KEYWORDS),
        }

        if result["no_control"] == 'no room thermostat':
            result["thermostatic_control"] = None

        return result
