from typing import Dict

from grottext.ha.ha_types import (
    ApparentPower,
    BaseSensor,
    BatteryChargeSensor,
    CurrentSensor,
    DiagnosticSensor,
    DurationSensor,
    EnergySensor,
    FrequencySensor,
    IncreasingEnergySensor,
    PercentSensor,
    PowerFactor,
    PowerSensor,
    ReactivePower,
    TemperatureSensor,
    VoltageSensor,
)

mapping: Dict[str, BaseSensor] = {
    "datalogserial": DiagnosticSensor("Datalogger serial"),
    "pvserial": DiagnosticSensor("serial"),
    "pv1voltage": VoltageSensor("PV1 Voltage"),
    "pv1current": CurrentSensor("PV1 Current"),
    "pv1watt": PowerSensor("PV1 Watt"),
    "pv2voltage": VoltageSensor("PV2 Voltage"),
    "pv2current": CurrentSensor("PV2 Current"),
    "pv2watt": PowerSensor("PV2 Watt"),
    "pv3voltage": VoltageSensor("PV3 Voltage"),
    "pv3current": CurrentSensor("PV3 Current"),
    "pv3watt": PowerSensor("PV3 Watt"),
    "pvpowerin": PowerSensor("PV Input (Actual)", icon="mdi:solar-power"),
    "pvpowerout": PowerSensor("PV Output (Actual)"),
    "pvfrequentie": FrequencySensor("Grid Frequency", icon="mdi:waveform"),
    "frequency": FrequencySensor("Grid Frequency", icon="mdi:waveform"),
    "line_freq": FrequencySensor("Grid Frequency", icon="mdi:waveform"),
    "outputfreq": FrequencySensor("Inverter output frequency", icon="mdi:waveform"),
    "outputvolt": VoltageSensor("Inverter output Voltage"),
    # Grid config
    "grid_volt": VoltageSensor("Grid Voltage"),
    "bus_volt": VoltageSensor("Bus Voltage"),
    "pvgridvoltage": VoltageSensor("Phase 1 voltage"),
    "pvgridvoltage2": VoltageSensor("Phase 2 voltage"),
    "pvgridvoltage3": VoltageSensor("Phase 3 voltage"),
    "pvgridcurrent": CurrentSensor("Phase 1 current"),
    "pvgridcurrent2": CurrentSensor("Phase 2 current"),
    "pvgridcurrent3": CurrentSensor("Phase 3 current"),
    "pvgridpower": PowerSensor("Phase 1 power"),
    "pvgridpower2": PowerSensor("Phase 2 power"),
    "pvgridpower3": PowerSensor("Phase 3 power"),
    # End grid
    "pvenergytoday": EnergySensor("Generated energy (Today)", icon="mdi:solar-power"),
    "epvtoday": EnergySensor("Solar energy today", icon="mdi:solar-power"),
    "epvToday": EnergySensor("Solar energy today", icon="mdi:solar-power"),
    "epv1today": EnergySensor("Solar PV1 energy today", icon="mdi:solar-power"),
    "epv2today": EnergySensor("Solar PV2 energy today", icon="mdi:solar-power"),
    "pvenergytotal": IncreasingEnergySensor("Generated energy (Total)", icon="mdi:solar-power"),
    "epvtotal": IncreasingEnergySensor("Lifetime solar energy", icon="mdi:solar-power"),
    "epv1total": IncreasingEnergySensor("Solar PV1 production (Total)", icon="mdi:solar-power"),
    "epv1tot": IncreasingEnergySensor("Solar PV1 production (Total)", icon="mdi:solar-power"),
    "epv2total": IncreasingEnergySensor("Solar PV2 production (Total)", icon="mdi:solar-power"),
    "epv2tot": IncreasingEnergySensor("Solar PV3 production (Total)", icon="mdi:solar-power"),
    # For SPH compatibility
    "epvTotal": IncreasingEnergySensor("Generated PV energy (Total)", icon="mdi:solar-power"),
    "pactouserr": PowerSensor("Import from grid", icon="mdi:transmission-tower-export"),
    "pactousertot": PowerSensor("Import from grid total", icon="mdi:transmission-tower-export"),
    "pactogridr": PowerSensor("Export to grid", icon="mdi:solar-power"),
    "pactogridtot": PowerSensor("Export to grid total", icon="mdi:solar-power"),
    "pvstatus": DiagnosticSensor("PV Status", icon="mdi:power-settings"),
    "totworktime": DurationSensor(
        "Working time",
        value_template="{{ value_json.totworktime| float / 7200 | round(2) }}",
    ),
    "pvtemperature": TemperatureSensor("Inverter temperature", icon="mdi:thermometer"),
    "pvipmtemperature": TemperatureSensor("Intelligent Power Management temperature", icon="mdi:thermometer"),
    "pvboottemperature": TemperatureSensor("Inverter boost temperature", icon="mdi:thermometer"),
    "pvboosttemp": TemperatureSensor("Inverter boost temperature", icon="mdi:thermometer"),
    # Energy
    "etogrid_tod": EnergySensor("Export to Grid Energy - Today", icon="mdi:transmission-tower-import"),
    "etogrid_tot": IncreasingEnergySensor("Export to Grid Energy - Total", icon="mdi:transmission-tower-import"),
    "etouser_tod": EnergySensor("Import from Grid Energy - Today", icon="mdi:transmission-tower-export"),
    "etouser_tot": IncreasingEnergySensor("Import from Grid Energy - Total", icon="mdi:transmission-tower-export"),
    # Need to investigate
    "elocalload_tod": EnergySensor("Load Consumption Energy - Today", icon="mdi:solar-power"),
    "elocalload_tot": IncreasingEnergySensor("Load Consumption Energy - Total", icon="mdi:solar-power"),
    "AC_InWatt": PowerSensor("Grid input power"),
    "AC_InVA": ApparentPower("Grid input apparent power"),
    "plocaloadr": PowerSensor("Local load consumption", icon="mdi:transmission-tower-export"),
    # extension data
    "grott_last_push": BaseSensor(
        "Grott last data push",
        device_class="timestamp",
        value_template="{{value_json.grott_last_push}}",
    ),
    "grott_last_measure": BaseSensor(
        "Grott last measure",
        device_class="timestamp",
        value_template="{{value_json.grott_last_measure}}",
    ),
    # batteries
    "eacharge_today": EnergySensor("Battery charge from AC (Today)", icon="mdi:battery-arrow-up"),
    "eacCharToday": EnergySensor("Battery charge from grid today", icon="mdi:battery-arrow-up"),
    "eacharge_total": IncreasingEnergySensor("Battery charge from AC (Total)", icon="mdi:battery-arrow-up"),
    "eacCharTotal": IncreasingEnergySensor("Lifetime battery charge from grid", icon="mdi:battery-arrow-up"),
    "eacDischarToday": EnergySensor("Battery dischage today", icon="mdi:battery-arrow-down"),
    "eacDischarTotal": IncreasingEnergySensor("Lifetime battery discharge", icon="mdi:battery-arrow-down"),
    "vbat": VoltageSensor("Battery voltage"),
    "SOC": BatteryChargeSensor(
        "Battery charge",
        icon="mdi:battery-charging-60",
        # The battery charge is directly a percentage,
        # there is an error in the layout.
        value_template="{{ value_json.SOC | int }}",
    ),
    "loadpercent": PercentSensor("Load percentage"),
    "batterySoc": BatteryChargeSensor("Battery charge", icon="mdi:battery-charging-60"),
    # register 28
    "bat_Volt": VoltageSensor("Battery voltage"),
    # register 29
    "bat_dsp": VoltageSensor("Battery bus voltage"),
    "ACDischarWatt": PowerSensor("Load power"),
    "ACDischarVA": ApparentPower("Load reactive power"),
    "BatDischarWatt": PowerSensor("Battery discharge power"),
    "BatWatt": PowerSensor("Battery discharge power", icon="mdi:battery"),
    "BatDischarVA": ApparentPower("Battery discharge reactive power"),
    # taken from register 1048 of RTU manual v1.20
    "batterytype": BaseSensor(
        "Battery type",
        icon="mdi:power-settings",
        value_template="{% if value_json.batterytype == '0' %}Lithium"
        "{% elif value_json.batterytype == '1' %}Lead-acid"
        "{% elif value_json.batterytype == '2' %}Other"
        "{% else %}Unknown{% endif %}",
    ),
    "p1charge1": PowerSensor("Battery Charging Power", icon="mdi:battery-arrow-up"),
    "eharge1_tod": EnergySensor("Battery charge (Today)", icon="mdi:battery-arrow-up"),
    "eharge1_tot": IncreasingEnergySensor("Battery charge (Total)", icon="mdi:battery-arrow-up"),
    "edischarge1_tod": EnergySensor("Battery discharge (Today)", icon="mdi:battery-arrow-down"),
    "edischarge1_tot": IncreasingEnergySensor("Battery discharge (Total)", icon="mdi:battery-arrow-down"),
    "ebatDischarToday": EnergySensor("Battery discharged today", icon="mdi:battery-arrow-down"),
    "ebatDischarTotal": IncreasingEnergySensor("Lifetime battery discharged", icon="mdi:battery-arrow-down"),
    "pdischarge1": PowerSensor("Battery discharging W", icon="mdi:battery-arrow-down"),
    "ACCharCurr": CurrentSensor("Battery charging current"),
    "acchr_watt": PowerSensor("Storage charging from grid"),
    "acchr_VA": ApparentPower("Storage charging from grid reactive power"),
    "battemp": TemperatureSensor("Battery temperature", icon="mdi:thermometer"),
    "invtemp": TemperatureSensor("Inverter temperature", icon="mdi:thermometer"),
    "dcdctemp": TemperatureSensor("Battery charger temperature", icon="mdi:thermometer"),
    "spbusvolt": VoltageSensor("SP bus voltage"),
    # faults
    "faultcode": DiagnosticSensor(name="Fault code"),
    "systemfaultword1": DiagnosticSensor(name="System fault register 1"),
    "systemfaultword2": DiagnosticSensor(name="System fault register 2"),
    "systemfaultword3": DiagnosticSensor(name="System fault register 3"),
    "systemfaultword4": DiagnosticSensor(name="System fault register 4"),
    "systemfaultword5": DiagnosticSensor(name="System fault register 5"),
    "systemfaultword6": DiagnosticSensor(name="System fault register 6"),
    "systemfaultword7": DiagnosticSensor(name="System fault register 7"),
    "spdspstatus": DiagnosticSensor(name="SP DSP status"),
    "faultBit": DiagnosticSensor(name="Fault message"),
    "warningBit": DiagnosticSensor(name="Warning message"),
    "faultValue": DiagnosticSensor(name="Fault value"),
    "warningValue": DiagnosticSensor(name="Warning value"),
    "constantPowerOK": DiagnosticSensor(name="Constant power OK"),
    "systemfaultword0": DiagnosticSensor(name="System Fault Word 0"),
    "uwsysworkmode": DiagnosticSensor(name="System work mode"),
    "isof": VoltageSensor("ISO fault", icon="mdi:alert"),
    "gfcif": CurrentSensor("GFCI fault", icon="mdi:alert"),
    "dcif": CurrentSensor("DCI fault", icon="mdi:alert"),
    "vpvfault": VoltageSensor("PV voltage fault", icon="mdi:alert"),
    "vacfault": VoltageSensor("AC voltage fault", icon="mdi:alert"),
    "facfault": FrequencySensor("AC frequency fault", icon="mdi:alert"),
    "tmpfault": TemperatureSensor("Temperature fault", icon="mdi:alert"),
    # PV
    "vpv1": VoltageSensor("PV1 voltage"),
    "vpv2": VoltageSensor("PV2 voltage"),
    "ppv1": PowerSensor("PV1 Wattage"),
    "ppv2": PowerSensor("PV2 Wattage"),
    "buck1curr": CurrentSensor("Buck1 current"),
    "buck2curr": CurrentSensor("Buck2 current"),
    "op_watt": PowerSensor("Inverter active power"),
    "op_va": ApparentPower("Inverter apparent power"),
    "Inv_Curr": CurrentSensor("Inverter current"),
    "OP_Curr": CurrentSensor("Inverter consumption current"),
    "eactoday": EnergySensor("Self-Consumption (Solar + Battery) Energy - Today (eactoday)"),
    "eactotal": IncreasingEnergySensor("Self-Consumption (Solar + Battery) Energy - Total (eactotal)"),
    # temperature
    "buck1_ntc": TemperatureSensor("Buck1 temperature", icon="mdi:thermometer"),
    "buck2_ntc": TemperatureSensor("Buck2 temperature", icon="mdi:thermometer"),
    # TODO: To map
    # "nbusvolt": "",
    # "rac": "",
    # "eractoday": "",
    # "eractotal": "",
    # "plocaloadtot": "",
    # "Vac_RS": "",
    # "Vac_ST": "",
    # "Vac_TR": "",
    # "temp4": "",
    # "uwBatVolt_DSP": "",
    "voltage_l1": VoltageSensor("Phase1 Voltage"),
    "voltage_l2": VoltageSensor("Phase2 Voltage"),
    "voltage_l3": VoltageSensor("Phase3 Voltage"),
    "Current_l1": CurrentSensor("Phase1 Current"),
    "Current_l2": CurrentSensor("Phase2 Current"),
    "Current_l3": CurrentSensor("Phase3 Current"),
    "voltageL1": VoltageSensor("Phase1 Voltage"),
    "voltageL2": VoltageSensor("Phase2 Voltage"),
    "voltageL3": VoltageSensor("Phase3 Voltage"),
    "currentL1": CurrentSensor("Phase1 Current"),
    "currentL2": CurrentSensor("Phase2 Current"),
    "currentL3": CurrentSensor("Phase3 Current"),
    "L1-2_voltage": VoltageSensor("Phase1-2 Voltage"),
    "L2-3_voltage": VoltageSensor("Phase2-3 Voltage"),
    "L3-1_voltage": VoltageSensor("Phase3-1 Voltage"),
    "act_power_l1": PowerSensor("Active power L1"),
    "act_power_l2": PowerSensor("Active power L2"),
    "act_power_l3": PowerSensor("Active power L3"),
    "app_power_l1": ApparentPower("Apparent power L1"),
    "app_power_l2": ApparentPower("Apparent power L2"),
    "app_power_l3": ApparentPower("Apparent power L3"),
    "react_power_l1": ReactivePower("Reactive power L1"),
    "react_power_l2": ReactivePower("Reactive power L2"),
    "react_power_l3": ReactivePower("Reactive power L3"),
    "powerfactor_l1": PowerFactor("Power factor L1"),
    "powerfactor_l2": PowerFactor("Power factor L2"),
    "powerfactor_l3": PowerFactor("Power factor L3"),
    # "pos_rev_act_power": "",
    # "pos_act_power": "",
    # "rev_act_power": "",
    # "app_power": "",
    # "react_power": "",
    "powerfactor": PowerFactor("Power factor"),
    "power_factor": PowerFactor("Power factor"),
    # "pos_act_energy": "",
    # "rev_act_energy": "",
    # "pos_act_energy_kvar": "",
    # "rev_act_energy_kvar": "",
    # "app_energy_kvar": "",
    # "act_energy_kwh": "",
    # "react_energy_kvar": "",
    # "device": "",
    # "logstart": "",
    # "active_energy": "",
    # "reactive_energy": "",
    "activePowerL1": PowerSensor("Active power L1"),
    "activePowerL2": PowerSensor("Active power L2"),
    "activePowerL3": PowerSensor("Active power L3"),
    "reactivePowerL1": ReactivePower("Reactive power L1"),
    "reactivePowerL2": ReactivePower("Reactive power L2"),
    "reactivePowerL3": ReactivePower("Reactive power L3"),
    "apperentPowerL1": ApparentPower("Apparent power L1"),
    "apperentPowerL2": ApparentPower("Apparent power L2"),
    "apperentPowerL3": ApparentPower("Apparent power L3"),
    "powerFactorL1": PowerFactor("Power factor L1"),
    "powerFactorL2": PowerFactor("Power factor L2"),
    "powerFactorL3": PowerFactor("Power factor L3"),
    # "power": "",
    # "active_power": "",
    # "reverse_active_power": "",
    # "apparent_power": "",
    # "reactive_power": "",
    # "posiActivePower": "",
    # "reverActivePower": "",
    # "posiReactivePower": "",
    # "reverReactivePower": "",
    # "apparentEnergy": "",
    # "totalActiveEnergyL1": "",
    # "totalActiveEnergyL2": "",
    # "totalActiveEnergyL3": "",
    # "totalRectiveEnergyL1": "",
    # "totalRectiveEnergyL2": "",
    # "totalRectiveEnergyL3": "",
    # "total_energy": "",
    "l1Voltage2": VoltageSensor("Phase 1-2 Voltage"),
    "l2Voltage3": VoltageSensor("Phase 2-3 Voltage"),
    "l3Voltage1": VoltageSensor("Phase 3-1 Voltage"),
}
