from hhd.controller import Axis, Button, Configuration
from hhd.controller.physical.evdev import B, to_map
from hhd.plugins import gen_gyro_state

DEFAULT_MAPPINGS: dict[str, tuple[Axis, str | None, float, float | None]] = {
    "accel_x": ("accel_z", "accel", 1, None),
    "accel_y": ("accel_x", "accel", -1, None),
    "accel_z": ("accel_y", "accel", -1, None),
    "anglvel_x": ("gyro_z", "anglvel", 1, None),
    "anglvel_y": ("gyro_x", "anglvel", -1, None),
    "anglvel_z": ("gyro_y", "anglvel", -1, None),
    "timestamp": ("imu_ts", None, 1, None),
}

X1_MAPPING = gen_gyro_state("x", True, "z", False, "y", False)
X1_MINI_MAPPING = gen_gyro_state("z", True, "x", False, "y", True)

BTN_MAPPINGS: dict[int, Button] = {
    # Volume buttons come from the same keyboard
    B("KEY_VOLUMEUP"): "key_volumeup",
    B("KEY_VOLUMEDOWN"): "key_volumedown",
    # Turbo Button [29, 56, 125] KEY_LEFTCTRL + KEY_LEFTALT + KEY_LEFTMETA
    B("KEY_LEFTALT"): "share",
    # Short press orange [32, 125] KEY_D + KEY_LEFTMETA
    B("KEY_D"): "mode",
    # KB Button [24, 97, 125]  KEY_O + KEY_RIGHTCTRL + KEY_LEFTMETA
    B("KEY_O"): "keyboard",
}

BTN_MAPPINGS_NONTURBO: dict[int, Button] = {
    # Volume buttons come from the same keyboard
    B("KEY_VOLUMEUP"): "key_volumeup",
    B("KEY_VOLUMEDOWN"): "key_volumedown",
    # Short press orange [32, 125] KEY_D + KEY_LEFTMETA
    B("KEY_D"): "mode",
    # KB Button [24, 97, 125]  KEY_O + KEY_RIGHTCTRL + KEY_LEFTMETA
    # If we do not have turbo takeover, let turbo do its turbo thing, and
    # failover to having the keyboard button open the overlay
    B("KEY_O"): "share",
}

BTN_MAPPINGS_X2: dict[int, Button] = {
    **BTN_MAPPINGS,
    B("KEY_F15"): "extra_l1",
    B("KEY_F16"): "extra_r1",
}

BTN_MAPPINGS_NONTURBO_X2: dict[int, Button] = {
    **BTN_MAPPINGS_NONTURBO,
    B("KEY_F15"): "extra_l1",
    B("KEY_F16"): "extra_r1",
}

ONEX_DEFAULT_CONF = {
    "hrtimer": True,
}

OXP_F1_CONF = {
    "name": "ONEXPLAYER ONEXFLY",
    **ONEX_DEFAULT_CONF,
    "protocol": "mixed",
}
OXP_2_CONF = {
    "name": "ONEXPLAYER 2",
    **ONEX_DEFAULT_CONF,
    "protocol": "mixed",
    "rgb": False,
    "protocol": "none",  # explicitly disable
    "extra_buttons": "none",
}
AOKZOE_CONF = {
    "name": "AOKZOE A1",
    "hrtimer": True,
    "protocol": "none",
    "rgb": False,
    "aok": True,
    "extra_buttons": "none",
}

CONFS = {
    # Aokzoe
    "AOKZOE A1 AR07": AOKZOE_CONF,
    "AOKZOE A1 Pro": AOKZOE_CONF,
    "AOKZOE A2 Pro": AOKZOE_CONF,
    "AOKZOE A1X": {
        "name": "AOKZOE A1X",
        "hrtimer": True,
        "protocol": "hid_dual",
        "aok": True,
        "extra_buttons": "none",
        "vibration": True,
    },
    # Onexplayer
    "ONE XPLAYER": {"name": "ONE XPLAYER", **ONEX_DEFAULT_CONF},
    "ONEXPLAYER Mini Pro": {
        "name": "ONEXPLAYER Mini Pro",
        **ONEX_DEFAULT_CONF,
        "protocol": "hid_v2",
    },
    "ONEXPLAYER mini A07": {"name": "ONEXPLAYER mini", **ONEX_DEFAULT_CONF},
    # OneXFly
    "ONEXPLAYER F1": OXP_F1_CONF,
    "ONEXPLAYER F1 EVA-01": OXP_F1_CONF,
    "ONEXPLAYER F1L": OXP_F1_CONF,
    "ONEXPLAYER F1 OLED": OXP_F1_CONF,
    "ONEXPLAYER F1Pro": OXP_F1_CONF,
    "ONEXPLAYER F1 EVA-02": OXP_F1_CONF,  # F1Pro variant
    # OXP 2
    "ONEXPLAYER 2": OXP_2_CONF,
    "ONEXPLAYER 2 ARP23": OXP_2_CONF,
    "ONEXPLAYER 2 GA18": OXP_2_CONF,
    # Pro is a bit different
    "ONEXPLAYER 2 PRO ARP23": OXP_2_CONF,
    "ONEXPLAYER 2 PRO ARP23 EVA-01": OXP_2_CONF,
    # X1 Line
    "ONEXPLAYER X1 mini": {
        **ONEX_DEFAULT_CONF,
        "name": "ONEXPLAYER X1 Mini",
        "x1": True,
        "mapping": X1_MINI_MAPPING,
        "protocol": "hid_v1",
    },
    "ONEXPLAYER X1Mini Pro": {
        **ONEX_DEFAULT_CONF,
        "name": "ONEXPLAYER X1 Mini Pro",
        "x1": True,
        "mapping": X1_MINI_MAPPING,
        "protocol": "hid_v1",
    },
    "ONEXPLAYER X1 A": {
        **ONEX_DEFAULT_CONF,
        "name": "ONEXPLAYER X1 (AMD)",
        "x1": True,
        "rgb_secondary": True,
        "mapping": X1_MAPPING,
        "protocol": "serial",
    },
    "ONEXPLAYER X1z": {
        **ONEX_DEFAULT_CONF,
        "name": "ONEXPLAYER X1 (AMD)",
        "x1": True,
        "rgb_secondary": True,
        "mapping": X1_MAPPING,
        "protocol": "serial",
    },
    "ONEXPLAYER X1Pro": {
        **ONEX_DEFAULT_CONF,
        "name": "ONEXPLAYER X1 Pro (AMD)",
        "x1": True,
        "rgb_secondary": True,
        "mapping": X1_MAPPING,
        "protocol": "serial",
    },
    "ONEXPLAYER X1Pro EVA-02": {
        **ONEX_DEFAULT_CONF,
        "name": "ONEXPLAYER X1Pro EVA-02 (Intel)",
        "x1": True,
        "rgb_secondary": True,
        "mapping": X1_MAPPING,
        "protocol": "serial",
        "turbo": True,  # disable turbo takeover so that it can be used for TDP
    },
    "ONEXPLAYER X1 i": {
        **ONEX_DEFAULT_CONF,
        "name": "ONEXPLAYER X1 (Intel)",
        "x1": True,
        "rgb_secondary": True,
        "mapping": X1_MAPPING,
        "protocol": "serial",
        "turbo": False,  # disable turbo takeover so that it can be used for TDP
    },
    "ONEXPLAYER X1Air": {
        **ONEX_DEFAULT_CONF,
        "name": "ONEXPLAYER X1 (Intel)",
        "x1": True,
        "rgb_secondary": True,
        "mapping": X1_MAPPING,
        "protocol": "hid_v1",
        "turbo": False,  # disable turbo takeover so that it can be used for TDP
    },
    # X2 Line
    "ONEXPLAYER X2Mini PRO": {
        **ONEX_DEFAULT_CONF,
        "name": "ONEXPLAYER X2 Mini Pro",
        "x1": True,
        "rgb_secondary": True,
        "rgb_secondary_breathing": True,
        "mapping": X1_MINI_MAPPING,
        "protocol": "hid_v2_x2",
    },
    "ONEXPLAYER G1 i": {
        **ONEX_DEFAULT_CONF,
        "name": "ONEXPLAYER G1 (Intel)",
        "g1": True,
        "protocol": "hid_v1_g1",
        "turbo": False,  # disable turbo takeover so that it can be used for TDP
    },
    "ONEXPLAYER G1 A": {
        **ONEX_DEFAULT_CONF,
        "name": "ONEXPLAYER G1 (AMD)",
        "g1": True,
        "protocol": "hid_v1_g1",
        "turbo": True,  # disable turbo takeover so that it can be used for TDP
    },
}


def get_default_config(product_name: str, manufacturer: str):
    out = {
        "name": product_name,
        "manufacturer": manufacturer,
        "hrtimer": True,
        "untested": True,
        "x1": "X1" in product_name,
    }

    if "X1" in product_name and "mini" not in product_name.lower():
        out["rgb_secondary"] = True

    if "aokzoe" in manufacturer.lower():
        out["protocol"] = "none"
        out["rgb"] = False
        out["aok"] = True

    return out
