import re
import sys
import weakref

from lib.helpers import timing
from PyQt5.QtCore import QTimer
from PyQt5.QtGui import QKeySequence
from PyQt5.QtWidgets import QShortcut
from ui.test_test import Test_Test


class Test_Fail(Test_Test):
    def __init__(self, recipe=None, step=None, pieces=None, run_once=False, reset_on_start=True, enable_override=False,
                 parent=None):
        super().__init__(components=parent.components, recipe=recipe, step=step, pieces=pieces, run_once=run_once,
                         reset_on_start=reset_on_start, enable_override=enable_override)

        # Disable button on first click
        self.continue_b.clicked.connect(self.disable_and_emit_ok)

        self.parent = parent
        self.discard_timer = QTimer()
        self.discard_timer.timeout.connect(self.wait_discard)

    def disable_and_emit_ok(self):
        """
        Disables the `continue_b` button and emits the `ok` signal.
        """
        self.continue_b.setEnabled(False)  # Disable the button
        self.ok.emit(None)  # Emit the signal

    def start(self, recipe=None, step=None, pieces=None):
        """
        Called when the widget is initialized or reappears.
        Will re-enable the `continue_b` button.
        """
        # Re-enable the `continue_b` button when the widget starts
        self.continue_b.setEnabled(True)

        show = super().start(recipe=recipe, step=step, pieces=pieces)
        if show is False:
            return show
        if "discard_box" in self.parent.config["hardware_config"].keys():
            if self.parent.require_discard_piece:
                if self.parent_assembly_widget is not None:
                    self.continue_b.setVisible(False)  # Initially hidden until discard is done
                    self.discard_timer.start(100)  # Repeat discard check every 100ms
                    self.parent_assembly_widget().set_text(
                        text="TEST KO - INSERIRE IL PEZZO COLLAUDATO NEL CONTENITORE DI SEGREGAZIONE SCARTI",
                        text_color="black",
                        bg_color="red",
                    )
                    self.io_connection = self.components["digital_io"].out.connect(self.wait_discard)

        self.visualize()

        # Automatic testing logic (if "--test" is in args)
        if "--test" in sys.argv:
            self.test_timer = QTimer()
            self.test_timer.setSingleShot(True)
            self.test_timer.timeout.connect(self.continue_b.click)  # Simulate clicking continue
            self.test_timer.start(500)  # Simulate in 500ms

        return show

    def stop(self):
        """
        Called when the widget is stopped or closed.
        """
        if "discard_box" in self.parent.config["hardware_config"].keys():
            if hasattr(self, "io_connection"):
                self.disconnect(self.io_connection)
        super().stop()

    def wait_discard(self, data=None):
        """
        Called when waiting for the discard box event to trigger.
        """
        if data is not None:
            if len(data[0]["digital_io"]) == 0:
                return
            else:
                sensor_index = int(self.parent.config["digital_io"]["discard_idx"])
                byte_idx = int(sensor_index / 8)
                bit_idx = sensor_index % 8
                if not data[0]["digital_io"][byte_idx][bit_idx]:
                    self.disable_and_emit_ok()  # Disable the `continue_b` button and emit the signal

