from typing import Union

from tmtccmd.tc import DefaultPusQueueHelper
from tmtccmd.tc.pus_200_fsfw_modes import Mode
from tmtccmd.util import ObjectIdU32, ObjectIdBase

from eive_tmtc.tmtc.common import pack_mode_cmd_with_info
import eive_tmtc.config.object_ids as obj_ids


class OpCode:
    THERMAL_CONTROLLER = [obj_ids.THERMAL_CONTROLLER_ID.hex(), "ctrl-th"]
    CORE_CONTROLLER = [obj_ids.CORE_CONTROLLER_ID.hex(), "ctrl-core"]


class Info:
    THERMAL_CONTROLLER = "Thermal controller"
    CORE_CONTROLLER = "ACS controller"


def pack_cmd_ctrl_to_prompted_mode(
    q: DefaultPusQueueHelper, object_id: ObjectIdU32, gui: bool
):
    from eive_tmtc.pus_tc.prompt_parameters import (
        prompt_parameters_cli,
    )

    param_list = [
        {"name": "Mode", "defaultValue": "2"},
        {"name": "Submode", "defaultValue": "0"},
    ]
    if gui:
        from eive_tmtc.pus_tc.prompt_parameters import prompt_parameters_gui

        parameters = prompt_parameters_gui(param_list)
    else:
        parameters = prompt_parameters_cli(param_list)
    mode = int(parameters["Mode"])
    if mode < 0 or mode > 2:
        print("Invalid Mode, defaulting to OFF")
        mode = 0
    submode = int(parameters["Submode"])
    pack_mode_cmd_with_info(
        object_id=object_id.as_bytes,
        mode=mode,
        submode=submode,
        q=q,
        info=f"Commanding {object_id} to {mode}, {submode}",
    )


def pack_cmd_ctrl_to_off(
    q: DefaultPusQueueHelper, object_id: Union[ObjectIdBase, ObjectIdU32]
):
    pack_mode_cmd_with_info(
        object_id=object_id.as_bytes,
        mode=Mode.OFF,
        submode=0,
        q=q,
        info=f"Commanding {object_id} OFF",
    )


def pack_cmd_ctrl_to_on(q: DefaultPusQueueHelper, object_id: ObjectIdU32):
    pack_mode_cmd_with_info(
        object_id=object_id.as_bytes,
        mode=Mode.ON,
        submode=0,
        q=q,
        info=f"Commanding {object_id} ON",
    )


def pack_cmd_ctrl_to_nml(
    q: DefaultPusQueueHelper, object_id: Union[ObjectIdBase, ObjectIdU32]
):
    pack_mode_cmd_with_info(
        object_id=object_id.as_bytes,
        mode=Mode.NORMAL,
        submode=0,
        q=q,
        info=f"Commanding {object_id} NORMAL",
    )


def get_object_from_op_code(op_code: str):
    try:
        return bytes.fromhex(op_code)
    except:
        pass

    if op_code in OpCode.THERMAL_CONTROLLER:
        return obj_ids.THERMAL_CONTROLLER_ID
    if op_code in OpCode.CORE_CONTROLLER:
        return obj_ids.CORE_CONTROLLER_ID