from enum import IntEnum, StrEnum
from typing import Final

# Active (solicited) discovery: send a broadcast then listen for replies
ACTIVE_DISCOVERY_PORT: Final[int] = 10000
ACTIVE_DISCOVERY_MESSAGE: Final[bytes] = b"AT+IGDEVICEIP"
ACTIVE_DISCOVERY_TIMEOUT: Final[float] = 5.0

# Passive (unsolicited) discovery: listen for device-initiated broadcasts
PASSIVE_DISCOVERY_PORT: Final[int] = 8099
PASSIVE_DISCOVERY_MAGIC: Final[bytes] = b"BCF-D"
PASSIVE_DISCOVERY_BIND_ADDR: Final[str] = "0.0.0.0"  # bind address for local_addr

# Internal send-to tuple used by async_discover to broadcast the discovery message
_ACTIVE_BROADCAST_ADDR: Final[tuple[str, int]] = (
    "255.255.255.255",
    PASSIVE_DISCOVERY_PORT,
)

SET_REALTIME_ACTION: Final[str] = "47015"

DEVICE_LIMITS: Final[dict[int, dict[str, int]]] = {
    1: {"max_discharge_power": 800, "max_charge_power": 1200, "minimum_soc": 5},
    2: {"max_discharge_power": 10800, "max_charge_power": 10800, "minimum_soc": 5},
}


class IndevoltRealtimeAction(IntEnum):
    """Actions for real-time control mode."""

    STOP = 0
    CHARGE = 1
    DISCHARGE = 2


class IndevoltRealtimeState(IntEnum):
    """States for real-time control mode."""

    STANDBY = 1000
    CHARGING = 1001
    DISCHARGING = 1002


class IndevoltEnergyMode(IntEnum):
    """Energy mode values for the device."""

    OUTDOOR_PORTABLE = 0
    SELF_CONSUMED_PRIORITIZED = 1
    REAL_TIME_CONTROL = 4
    CHARGE_DISCHARGE_SCHEDULE = 5


class IndevoltOperatingModes(IntEnum):
    """Operating mode values for the device."""

    MAIN = 1000
    SUB = 1001
    STANDALONE = 1002


class IndevoltConfig(StrEnum):
    """Register keys for configurable device settings (read and write)."""

    WRITE_ENERGY_MODE = "47005"
    WRITE_DISCHARGE_LIMIT = "1142"
    WRITE_MAX_AC_OUTPUT_POWER = "1147"
    WRITE_INVERTER_INPUT_LIMIT = "1138"
    WRITE_FEEDIN_POWER_LIMIT = "1146"
    WRITE_GRID_CHARGING = "1143"
    WRITE_LIGHT = "7265"
    WRITE_BYPASS = "7266"

    READ_ENERGY_MODE = "7101"
    READ_DISCHARGE_LIMIT = "6105"
    READ_REALTIME_COMMAND = "6107"  # Deprecated, READ_REALTIME_STATE
    READ_REALTIME_STATE = "6107"
    READ_REALTIME_TARGET_SOC = "6108"
    READ_REALTIME_POWER_LIMIT = "6109"
    READ_MAX_AC_OUTPUT_POWER = "11011"
    READ_INVERTER_INPUT_LIMIT = "11009"
    READ_FEEDIN_POWER_LIMIT = "11010"
    READ_GRID_CHARGING = "2618"
    READ_LIGHT = "7171"
    READ_BYPASS = "680"


class IndevoltSystem(StrEnum):
    """Register keys for system-level AC power and energy."""

    SERIAL_NUMBER = "0"
    OPERATING_MODE = "606"
    INPUT_POWER = "2101"  # Deprecated, replaced with AC_TOTAL_INPUT_POWER
    OUTPUT_POWER = "2108"  # Deprecated, replaced with AC_TOTAL_OUTPUT_POWER
    BYPASS_POWER = "667"
    TOTAL_INPUT_ENERGY = "2107"
    TOTAL_OUTPUT_ENERGY = "2104"
    OFF_GRID_OUTPUT_ENERGY = "2105"
    BYPASS_INPUT_ENERGY = "11034"
    HEATING_STATE = "7121"
    AC_VOLTAGE = "2083"
    AC_CURRENT = "2086"
    AC_FREQUENCY = "2095"
    AC_TOTAL_NET_POWER = "2278"
    AC_TOTAL_INPUT_POWER = "2101"
    AC_TOTAL_OUTPUT_POWER = "2108"
    AC_REACTIVE_POWER = "2097"
    AC_APPARENT_POWER = "2098"
    AC_POWER_FACTOR = "2099"


class IndevoltGrid(StrEnum):
    """Register keys for grid and utility meter data."""

    METER_POWER_GEN1 = "21028"
    METER_POWER_GEN2 = "11016"
    VOLTAGE = "2600"
    FREQUENCY = "2612"
    METER_CONNECTED = "7120"


class IndevoltBattery(StrEnum):
    """Register keys for battery system parameters."""

    POWER = "6000"  # Deprecated, replaced with DC_POWER
    CHARGE_DISCHARGE_STATE = "6001"
    SOC = "6002"
    RATED_CAPACITY = "142"
    DAILY_CHARGING_ENERGY = "6004"
    DAILY_DISCHARGING_ENERGY = "6005"
    TOTAL_CHARGING_ENERGY = "6006"
    TOTAL_DISCHARGING_ENERGY = "6007"
    RATED_CAPACITY_GEN2 = "142"  # Deprecated, replaced with RATED_CAPACITY
    REMAINING_CHARGING_TIME = "11019"
    REMAINING_DISCHARGING_TIME = "11020"
    DC_VOLTAGE = "6100"
    DC_CURRENT = "6101"
    DC_POWER = "6000"

    GEN_1_INVERTER_TEMPERATURE = "7600"
    GEN_1_PACK_1_TEMPERATURE = "7605"
    GEN_1_PACK_2_TEMPERATURE = "7620"
    GEN_1_PACK_3_TEMPERATURE = "7621"
    GEN_1_MOS_TEMPERATURE_CHARGE = "7638"
    GEN_1_MOS_TEMPERATURE_DISCHARGE = "7639"

    GEN_2_CYCLE_COUNT = "8646"
    GEN_2_TRANSFORMER_TEMPERATURE = "11005"

    # Main / Battery 1
    MAIN_SERIAL_NUMBER = "9008"  # Also available in key 150
    MAIN_SOC = "9000"  # Also available in key 6009
    MAIN_SOH = "9002"
    MAIN_CYCLES = "9003"
    MAIN_TEMPERATURE = "9012"
    MAIN_VOLTAGE = "9004"
    MAIN_CURRENT = "9013"
    MAIN_HEATING_STATE = "9080"
    MAIN_MOS_TEMPERATURE = "11042"

    # Extension pack 1 / Battery 2
    PACK_1_SERIAL_NUMBER = "9032"
    PACK_1_SOC = "9016"
    PACK_1_SOH = "9018"
    PACK_1_CYCLES = "9019"
    PACK_1_TEMPERATURE = "9030"
    PACK_1_VOLTAGE = "9020"
    PACK_1_CURRENT = "19173"
    PACK_1_HEATING_STATE = "9096"
    PACK_1_MOS_TEMPERATURE = "9085"

    # Extension pack 2 / Battery 3
    PACK_2_SERIAL_NUMBER = "9051"
    PACK_2_SOC = "9035"
    PACK_2_SOH = "9037"
    PACK_2_CYCLES = "9038"
    PACK_2_TEMPERATURE = "9049"
    PACK_2_VOLTAGE = "9039"
    PACK_2_CURRENT = "19174"
    PACK_2_HEATING_STATE = "9112"
    PACK_2_MOS_TEMPERATURE = "9101"

    # Extension pack 3 / Battery 4
    PACK_3_SERIAL_NUMBER = "9070"
    PACK_3_SOC = "9054"
    PACK_3_SOH = "9056"
    PACK_3_CYCLES = "9057"
    PACK_3_TEMPERATURE = "9068"
    PACK_3_VOLTAGE = "9058"
    PACK_3_CURRENT = "19175"
    PACK_3_HEATING_STATE = "9128"
    PACK_3_MOS_TEMPERATURE = "9117"

    # Extension pack 4 / Battery 5
    PACK_4_SERIAL_NUMBER = "9165"
    PACK_4_SOC = "9149"
    PACK_4_SOH = "9151"
    PACK_4_CYCLES = "9152"
    PACK_4_TEMPERATURE = "9163"
    PACK_4_VOLTAGE = "9153"
    PACK_4_CURRENT = "19176"
    PACK_4_HEATING_STATE = "9144"
    PACK_4_MOS_TEMPERATURE = "9133"

    # Extension pack 5 / Battery 6
    PACK_5_SERIAL_NUMBER = "9218"
    PACK_5_SOC = "9202"
    PACK_5_SOH = "9204"
    PACK_5_CYCLES = "9205"
    PACK_5_TEMPERATURE = "9216"
    PACK_5_VOLTAGE = "9206"
    PACK_5_CURRENT = "19177"
    PACK_5_HEATING_STATE = "9279"
    PACK_5_MOS_TEMPERATURE = "9270"


class IndevoltSolar(StrEnum):
    """Register keys for PV/solar input and output parameters."""

    DC_OUTPUT_POWER = "1501"
    DAILY_PRODUCTION = "1502"
    CUMULATIVE_PRODUCTION = "1505"

    DC_INPUT_VOLTAGE_1 = "1600"
    DC_INPUT_VOLTAGE_2 = "1601"
    DC_INPUT_VOLTAGE_3 = "1602"
    DC_INPUT_VOLTAGE_4 = "1603"

    DC_INPUT_CURRENT_1 = "1632"
    DC_INPUT_CURRENT_2 = "1633"
    DC_INPUT_CURRENT_3 = "1634"
    DC_INPUT_CURRENT_4 = "1635"

    DC_INPUT_POWER_1 = "1664"
    DC_INPUT_POWER_2 = "1665"
    DC_INPUT_POWER_3 = "1666"
    DC_INPUT_POWER_4 = "1667"
