@tool
extends 'res://scenes/контроль/прибор.gd'

enum STATE_VAL { NONE = 0, GOOD = 1, ERROR = 2 }

# Основные переменные
var unit_prd_v: Object
var ctrl_pos = 70


func _ready() -> void:
    if Engine.is_editor_hint():
        return
    var unit_name = get_meta('unit_name')[0]
    var prd_v_module = prd.prd_dict[unit_name]
    unit_prd_v = prd_v_module.unit_control
    var power_amplifier: Array = get_tree().get_nodes_in_group('power_amplifier')
    for temp in power_amplifier:
        temp.value1 = -100
    # Подписываемся на сигналы
    signaller.conn(signaller.start_contol_device, Callable(self, '_on_start_control'))
    unit_prd_v.connect('control_is_over', Callable(self, 'on_press_device'))
    unit_prd_v.connect('status_updated', Callable(self, '_on_status_updated'))
    find_labels(self)
    # Устанавливаем начальный статус
    _update_status_text(unit_prd_v.get_current_status())
    on_press_device(unit_prd_v.self_name)


func _process(_delta: float) -> void:
    if Engine.is_editor_hint():
        return
    $input_0.set_frame(unit_prd_v.ems_g_sock_dic.ems_input_1)
    $input_1.set_frame(unit_prd_v.ems_g_sock_dic.ems_input_2)
    $output_0.set_frame(unit_prd_v.ems_g_sock_dic.ems_output_1)
    $output_1.set_frame(unit_prd_v.ems_g_sock_dic.ems_output_2)


func _on_start_control() -> void:
    set_default_state(get_tree().get_nodes_in_group('default_reset'))
    set_default_state(get_tree().get_nodes_in_group('power_amplifier'))
    for um in get_tree().get_nodes_in_group('power_amplifier'):
        um.value0 = [0, 0, 0, 0, 0, 0]
    await get_tree().create_timer(1.0).timeout
    on_press_device(unit_prd_v.self_name)


static func set_default_state(default_reset_array_node: Array) -> void:
    for group in default_reset_array_node:
        group.state = STATE_VAL.NONE


func _enter_tree() -> void:
    if Engine.is_editor_hint():
        return
    if unit_prd_v:
        _update_status_text(unit_prd_v.get_current_status())


static func temperature_fill(temperature_arr_node: Array, temperature_dic: Dictionary)->void:
    for i_node_temperature in temperature_arr_node:
        var temperature_meta: String = i_node_temperature.get_meta('um')
        if not temperature_dic.has(temperature_meta): return
        i_node_temperature.value1 = temperature_dic[temperature_meta] if temperature_dic[temperature_meta] < 361 else -40


static func power_fill(pow_dic: Dictionary, fs_result: Dictionary, power_amplifier_arr_node: Array, POWER_THRESHOLD: int) -> void:
    for i_node_powapm in power_amplifier_arr_node:
        var powamp_meta: String = i_node_powapm.get_meta('um')
        var status = STATE_VAL.GOOD if pow_dic else STATE_VAL.NONE
        if not pow_dic.has(powamp_meta): return
        if powamp_meta in ['um_1', 'um_2', 'um_3', 'um_4', 'um_5', 'um_6'] and not fs_result.fs_4: return
        if powamp_meta in ['um_9', 'um_10', 'um_11', 'um_12', 'um_13', 'um_14'] and not fs_result.fs_5: return
        i_node_powapm.value0 = pow_dic[powamp_meta]
        # Проверка: если ВСЕ значения в массиве < 1 → STATE_VAL.NONE
        var power_array: Array = pow_dic[powamp_meta]
        var all_below_one: bool = true
        for i_p in power_array:
            if i_p >= 1:
                all_below_one = false
                break

        if all_below_one:
            i_node_powapm.state = STATE_VAL.NONE
            continue
        var count_above_threshold = 0
        for i_p in pow_dic[powamp_meta]:
            if i_p >= POWER_THRESHOLD:
                count_above_threshold += 1

        status = STATE_VAL.GOOD if count_above_threshold >= 3 else STATE_VAL.ERROR
        i_node_powapm.state = status


func on_press_device(_device_name: String) -> void:
    var nodes_y5: Array = get_tree().get_nodes_in_group('y-5')
    var node_ip_power_arr: Array = get_tree().get_nodes_in_group('power_supply')
    var fs_nodes: Array = get_tree().get_nodes_in_group('fs_group')
    var power_amplifier: Array = get_tree().get_nodes_in_group('power_amplifier')
    var default_reset_array_node: Array = get_tree().get_nodes_in_group('default_reset')
    var module_fs_4: Node = $kasseta_FS_VD/ref_A6
    var dou_4: Node = $dou4_A5
    var module_fs_5: Node = $kasseta_FS_VD/ref_A2
    var dou_5: Node = $dou5_A6
    var control_data = unit_prd_v.get_control_results()
    var for_control_result: Dictionary = {
        'nodes_y5': nodes_y5,
        'node_ip_power_arr': node_ip_power_arr,
        'fs_nodes': fs_nodes,
        'power_amplifier': power_amplifier,
        'default_reset_array_node': default_reset_array_node,
        'module_fs_4': module_fs_4,
        'dou_4': dou_4,
        'module_fs_5': module_fs_5,
        'dou_5': dou_5,
    }
    for_control_result.merge(control_data, true)
    on_control_result(for_control_result)


static func on_control_result(for_result_dic: Dictionary) -> void:
    temperature_fill(for_result_dic.power_amplifier,  for_result_dic.temperature_um)
    var all_y5_good: bool = true
    var block_kasseta_y5_prd_config_v: Dictionary = for_result_dic.block_kasseta_y5_config
    var nodes_y5: Array = for_result_dic.nodes_y5
    for node_y5 in nodes_y5:
        var meta_y5  = node_y5.get_meta('y5')
        if block_kasseta_y5_prd_config_v.has(meta_y5):
            if not block_kasseta_y5_prd_config_v.yau07:
                node_y5.state = STATE_VAL.ERROR if meta_y5 == 'yau07' else STATE_VAL.NONE
            else:
                node_y5.state = STATE_VAL.GOOD if block_kasseta_y5_prd_config_v[meta_y5] else STATE_VAL.ERROR
        if node_y5.state == STATE_VAL.ERROR:
            all_y5_good = false

    var block_ip_config_v: Dictionary = for_result_dic.block_ip_config
    for power_supply in for_result_dic.node_ip_power_arr:
        var meta_ip  = power_supply.get_meta('ip')
        if block_ip_config_v.has(meta_ip) and block_kasseta_y5_prd_config_v.ug and block_kasseta_y5_prd_config_v.yau07:
            power_supply.state = STATE_VAL.GOOD if block_ip_config_v[meta_ip][1] else STATE_VAL.ERROR
        else:
            power_supply.state = STATE_VAL.NONE
        if power_supply.state == STATE_VAL.ERROR:
            all_y5_good = false

    if not for_result_dic.control_is_over:
        set_default_state(for_result_dic.default_reset_array_node)
        set_default_state(for_result_dic.power_amplifier)
        return
    var result_dic: Dictionary = for_result_dic.result_dic
    for f in for_result_dic.fs_nodes:
            var fs_meta: String = f.get_meta('fs')
            if result_dic.has(fs_meta):
                f.state = result_dic[fs_meta]

    if not all_y5_good: return
    var fs_5 = true if int(result_dic.fs_5) == 1 else false
    if fs_5 and block_kasseta_y5_prd_config_v['yau07']:
        for_result_dic.module_fs_5.state = STATE_VAL.GOOD if result_dic.dkm_5 else STATE_VAL.ERROR
        for_result_dic.dou_5.state = STATE_VAL.GOOD if result_dic.dou_5 else STATE_VAL.ERROR

    var fs_4 = true if int(result_dic.fs_4) == 1 else false
    if fs_4 and block_kasseta_y5_prd_config_v['yau07']:
        for_result_dic.module_fs_4.state = STATE_VAL.GOOD if result_dic.dkm_4 else STATE_VAL.ERROR
        for_result_dic.dou_4.state = STATE_VAL.GOOD if result_dic.dou_4 else STATE_VAL.ERROR

    if block_kasseta_y5_prd_config_v['yau07']:
        power_fill(for_result_dic.power_dic, for_result_dic.result_dic, for_result_dic.power_amplifier, for_result_dic.POWER_THRESHOLD)


func find_labels(node1: Node):
    if node1 is Label:
        if node1.name in ['lbl_rname', 'rname']:
            if not node1.has_meta('tooltip_set'):
                ctrl_pos += 1
                var box_number = ceili(float(ctrl_pos) / 10.0)
                var position_number = ctrl_pos % 10
                if position_number == 0:
                    position_number = 10
                node1.tooltip_text = 'Ящик - %d, Позиция - %d' % [box_number, position_number]
                node1.mouse_filter = Control.MOUSE_FILTER_STOP
                node1.set_meta('tooltip_set', true)
    for child in node1.get_children():
        find_labels(child)


func _on_status_updated(status_text: String) -> void:
    _update_status_text(status_text)


func _update_status_text(text: String) -> void:
    $control_result.text = text
    # Можно добавить смену цвета в зависимости от статуса
    if 'Ошибка' in text or 'неисправен' in text:
        $control_result.add_theme_color_override('font_color', Color.RED)
        log.message(Logger.INFO, 'Прибор ПРД-%s неисправен' % [unit_prd_v.self_name])
    elif 'Ограничена' in text or 'Предупреждение' in text:
        $control_result.add_theme_color_override('font_color', Color.YELLOW)
    elif 'исправен' in text or 'завершён' in text:
        $control_result.add_theme_color_override('font_color', Color.GREEN)
        log.message(Logger.INFO, 'Прибор ПРД-%s исправен' % [unit_prd_v.self_name])
    else:
        $control_result.add_theme_color_override('font_color', Color.WHITE)
