import sys
from pathlib import Path

import wx
from clarabot_nano_common.ui.utility import change_font_to_bold, Slots

from clarabot_nano import __version__
from clarabot_nano.common.i18n import LOCALIZATION
from clarabot_nano.control.client import WxCoreInterface
from clarabot_nano.control.icon import get_wx_nano_icon


class AboutDialog(wx.Dialog, Slots):
    def __init__(self, core_interface: WxCoreInterface, parent):
        wx.Dialog.__init__(self, parent, wx.ID_ANY, gettext("About"), style=wx.DEFAULT_DIALOG_STYLE | wx.RESIZE_BORDER)
        Slots.__init__(self)
        self.SetSizeHints(320, 320)
        self.SetIcon(get_wx_nano_icon())
        self.SetSize(600, 400)

        self.cc_config_appropriate = gettext("Current configuration is appropriate for the CC certification.")
        self.cc_config_not_correct = gettext("Some configuration is NOT correct for the CC certification.")

        layout = wx.BoxSizer(wx.VERTICAL)
        self._title_label = wx.StaticText(self, wx.ID_ANY, f"Clarabot Nano {__version__}")
        change_font_to_bold(self._title_label)
        layout.Add(self._title_label, 0, wx.ALL | wx.EXPAND, 8)

        self._tabs = wx.Notebook(self)
        layout.Add(self._tabs, 1, wx.LEFT | wx.RIGHT | wx.BOTTOM | wx.EXPAND, 16)

        # NOTE: TE_RICH is MSW-specific to allow longer value than 64K characters.
        _long_text_ctrl_style = wx.TE_RICH | wx.TE_MULTILINE | wx.TE_READONLY

        self._license_text = wx.TextCtrl(
            self._tabs, wx.ID_ANY, self.read_license(), style=_long_text_ctrl_style | wx.TE_WORDWRAP | wx.TE_AUTO_URL
        )
        self._tabs.AddPage(self._license_text, gettext("License"))
        self.Bind(wx.EVT_TEXT_URL, self._on_url, self._license_text)

        self._used_text = wx.TextCtrl(
            self._tabs, wx.ID_ANY, self.read_used_legal(), style=_long_text_ctrl_style | wx.TE_DONTWRAP
        )
        self._tabs.AddPage(self._used_text, gettext("Used software"))

        self._cc_text = wx.TextCtrl(self._tabs, wx.ID_ANY, style=_long_text_ctrl_style | wx.TE_AUTO_URL)
        self._tabs.AddPage(self._cc_text, "Common Criteria")
        self.Bind(wx.EVT_TEXT_URL, self._on_url, self._cc_text)

        buttons = self.CreateButtonSizer(wx.OK)
        if buttons:
            layout.Add(buttons, 0, wx.LEFT | wx.RIGHT | wx.BOTTOM | wx.EXPAND, 8)

        self.SetSizer(layout)

        self.bind_signal(core_interface.config_changed, self._on_config_changed)
        self._on_config_changed(core_interface.get_config())

    def _on_config_changed(self, config):
        # collect relevant configs
        require_explicit_peer_trust = config["remote"]["require_explicit_peer_trust"] is True
        # select summary
        summary = self.cc_config_appropriate if all([require_explicit_peer_trust]) else self.cc_config_not_correct
        # compile user-text
        cc_text = gettext(
            "Not all versions of Nano may be certified.\n"
            "Check the certification status of %(version)s (this version) at https://www.clarabot.com/download\n\n"
            "SUMMARY: %(summary)s\n\n"
            "The following configurations must be ON for CC certificated operation:\n"
            "  - Require explicit peer trust: %(require_explicit_peer_trust)s\n"
        ) % {
            "version": __version__,
            "summary": summary,
            "require_explicit_peer_trust": gettext("ON") if require_explicit_peer_trust else gettext("OFF"),
        }
        self._cc_text.SetValue(cc_text)

    def _on_url(self, evt: wx.TextUrlEvent):
        mouse = evt.GetMouseEvent()
        # NOTE: There is no "Up" event on Windows here.
        if mouse.LeftDown():
            text_ctrl: wx.TextCtrl = evt.GetEventObject()
            url = text_ctrl.GetRange(evt.GetURLStart(), evt.GetURLEnd())
            wx.LaunchDefaultBrowser(url)

    def read_license(self) -> str:
        languages = []
        if LOCALIZATION.DETECTED_SYSTEM_LANGUAGE:
            languages.append("_" + LOCALIZATION.DETECTED_SYSTEM_LANGUAGE)
        languages.append("_en")  # fallback is English
        try:
            exe_dir = Path(sys.executable).parent
            for lang in languages:
                lang_path = exe_dir / f"LICENSE{lang.upper()}.txt"
                if lang_path.is_file():
                    return lang_path.read_text(encoding="utf-8-sig")
        except OSError:
            pass
        return "Clarabot Nano\nCopyright (c) 2021-2023 Clarabot Zrt.\n\nCould not load detailed license."

    def read_used_legal(self) -> str:
        try:
            third_party_text = (Path(sys.executable).parent / "THIRDPARTYSOFTWARE.txt").read_text(encoding="utf-8")
        except OSError:
            third_party_text = gettext("Could not load legal information of third-party software.")
        return third_party_text
