import platform as pf
from logging import getLogger
from typing import Type

from PySide6.QtCore import Qt, Signal
from PySide6.QtGui import QHideEvent
from PySide6.QtWidgets import QVBoxLayout, QWidget

from rare.models.settings import RareAppSettings
from rare.shared import RareCore
from rare.utils import config_helper as config
from rare.widgets.side_tab import SideTabContents

from .widgets.overlay import DxvkConfigSettings, DxvkHudSettings, DxvkNvapiDrsSettings
from .widgets.runner import RunnerSettingsBase, RunnerSettingsType
from .widgets.wine import WineSettings

if pf.system() in {"Linux", "FreeBSD"}:
    from .widgets.overlay import MangoHudSettings
    from .widgets.proton import ProtonSettings

logger = getLogger("GlobalCompatSettings")


class CompatSettingsBase(QWidget, SideTabContents):
    # str: option key
    environ_changed: Signal = Signal(str)
    # # bool: state, str: path
    # compat_tool_enabled: Signal = Signal(bool, str)

    def __init__(
        self,
        settings: RareAppSettings,
        rcore: RareCore,
        dxvk_hud_widget: Type[DxvkHudSettings],
        dxvk_config_widget: Type[DxvkConfigSettings],
        dxvk_nvapi_drs_widget: Type[DxvkNvapiDrsSettings],
        runner_widget: Type["RunnerSettingsType"],
        mangohud_widget: Type["MangoHudSettings"] = None,
        parent=None,
    ):
        super(CompatSettingsBase, self).__init__(parent=parent)

        self.settings = settings
        self.core = rcore.core()
        self.app_name: str = "default"

        self.runner = runner_widget(settings, rcore, self)
        self.runner.environ_changed.connect(self.environ_changed)
        # self.runner.compat_tool_enabled.connect(self.compat_tool_enabled)

        self.dxvk_hud = dxvk_hud_widget(self)
        self.dxvk_hud.environ_changed.connect(self.environ_changed)

        self.dxvk_config = dxvk_config_widget(self)
        self.dxvk_config.environ_changed.connect(self.environ_changed)

        self.dxvk_nvapi_drs = dxvk_nvapi_drs_widget(self)
        self.dxvk_nvapi_drs.environ_changed.connect(self.environ_changed)

        self.mangohud = False
        if mangohud_widget is not None:
            self.mangohud = mangohud_widget(self)
            self.mangohud.environ_changed.connect(self.environ_changed)

        self.main_layout = QVBoxLayout(self)
        self.main_layout.addWidget(self.runner)
        self.main_layout.addWidget(self.dxvk_hud)
        self.main_layout.addWidget(self.dxvk_config)
        self.main_layout.addWidget(self.dxvk_nvapi_drs)
        if mangohud_widget is not None:
            self.main_layout.addWidget(self.mangohud)
        self.main_layout.setAlignment(Qt.AlignmentFlag.AlignTop)

    def hideEvent(self, a0: QHideEvent):
        if a0.spontaneous():
            return super().hideEvent(a0)
        config.save_config()
        return super().hideEvent(a0)


class GlobalRunnerSettings(RunnerSettingsBase):
    def __init__(self, settings: RareAppSettings, rcore: RareCore, parent=None):
        if pf.system() in {"Linux", "FreeBSD"}:
            super(GlobalRunnerSettings, self).__init__(settings, rcore, WineSettings, ProtonSettings, parent=parent)
        else:
            super(GlobalRunnerSettings, self).__init__(settings, rcore, WineSettings, parent=parent)


class GlobalCompatSettings(CompatSettingsBase):
    def __init__(self, settings: RareAppSettings, rcore: RareCore, parent=None):
        if pf.system() in {"Linux", "FreeBSD"}:
            super(GlobalCompatSettings, self).__init__(
                settings,
                rcore,
                dxvk_hud_widget=DxvkHudSettings,
                dxvk_config_widget=DxvkConfigSettings,
                dxvk_nvapi_drs_widget=DxvkNvapiDrsSettings,
                runner_widget=GlobalRunnerSettings,
                mangohud_widget=MangoHudSettings,
                parent=parent,
            )
        else:
            super(GlobalCompatSettings, self).__init__(
                settings,
                rcore,
                dxvk_hud_widget=DxvkHudSettings,
                dxvk_config_widget=DxvkConfigSettings,
                dxvk_nvapi_drs_widget=DxvkNvapiDrsSettings,
                runner_widget=GlobalRunnerSettings,
                parent=parent,
            )
