import wx

from clarabot_nano.control.configure.basic.wizard import SimpleConfigurationWizard
from clarabot_nano.control.page.status import ControlStatus
from clarabot_nano.control.window import ControlWindow
from clarabot_nano.development.spawn.control.tester import ControlApplicationTester, phase_timeout


class _UpdateStateControlApplicationTester(ControlApplicationTester):
    """
    Test update-state handling recommended by server
    """

    def __init__(self, *args, email=None, password=None, expected_update_state=None, **kwargs):
        ControlApplicationTester.__init__(self, *args, **kwargs)
        self.email = email
        self.password = password
        self.expected_update_state = expected_update_state

    @phase_timeout(5.0)
    def _phase_0(self, w: ControlWindow):
        """
        Wait until login is shown.
        """
        self._check_waiting_login_get_central_widget(w)
        return True

    def _phase_1(self, w: ControlWindow):
        """
        Start login.
        """
        login_widget = self._check_waiting_login_get_central_widget(w)
        login_widget._email_field.SetValue(self.email)
        login_widget._password_field.SetValue(self.password)
        login_widget.ProcessEvent(wx.CommandEvent(wx.wxEVT_COMMAND_BUTTON_CLICKED, login_widget._login_btn.GetId()))
        return True

    @phase_timeout(5.0)
    def _phase_2(self, w: ControlWindow):
        """
        Check logged in or rejected.
        """
        central_widget = w.central_widget()
        assert isinstance(central_widget, ControlStatus)
        d = self._get_modal_dialog(w, SimpleConfigurationWizard, require=False)
        if d:
            self._find_send_command_event(d, wx.ID_CANCEL, wx.wxEVT_COMMAND_BUTTON_CLICKED)
        config = w.core_interface.get_config()
        if self.expected_update_state == -1:  # rejected
            assert (v := config["state"].get("gateway_status")) == "disconnected", str(v)
            # return len(self._tester_phases)  # jump to done
        else:
            assert (v := config["state"].get("gateway_status")) in ("connected", "active"), str(v)
        return True

    def _phase_3(self, w: ControlWindow):
        """
        Check update state.
        """
        central_widget = w.central_widget()
        assert isinstance(central_widget, ControlStatus)
        update_message = w._get_update_message_from_state(
            4 if self.expected_update_state == -1 else self.expected_update_state
        )
        if not update_message:
            assert w.GetMenuBar().GetMenuCount() == 4
            assert central_widget._update_widget is None
        else:
            menu_bar = w.GetMenuBar()
            assert menu_bar.GetMenuCount() == 5
            assert menu_bar.GetMenuLabel(4) == gettext("Update")
            update_menu = menu_bar.GetMenu(4)
            assert update_menu.GetMenuItemCount() == 1
            assert update_menu.GetMenuItems()[0].GetItemLabel() == update_message
            assert central_widget._update_widget.get_update_text() == update_message.partition(";")[0]
        return True
