#  Copyright (c) 2025  Jeffrey Hsu - JITToolBox
#  #
#  This program is free software: you can redistribute it and/or modify
#  it under the terms of the GNU General Public License as published by
#  the Free Software Foundation, either version 3 of the License, or
#  (at your option) any later version.
#  #
#  This program is distributed in the hope that it will be useful,
#  but WITHOUT ANY WARRANTY; without even the implied warranty of
#  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
#  GNU General Public License for more details.
#  #
#  You should have received a copy of the GNU General Public License
#  along with this program.  If not, see <https://www.gnu.org/licenses/>.

import os
from dataclasses import dataclass
from typing import Callable

from PySide6.QtGui import QIcon, QShowEvent
from qfluentwidgets import FluentIcon, MSFluentWindow, NavigationItemPosition, MessageBox, setThemeColor

from ui import MAIN_THEME_COLOR, BLUE_BACKGROUND_COLOR
from ui.pyui.about_ui import AboutWidget
from ui.pyui.achievement_ui import AchievementWidget
from ui.pyui.defense_ui import DefenseWidget
from ui.pyui.picker_ui import PickerWidget
from ui.pyui.test_ui import TestWidget
from utils.function import RELEASE_ENV


@dataclass(frozen=True)
class InterfaceSpec:
    key: str
    factory: Callable[[], object]
    icon: FluentIcon
    nav_text: str
    position: NavigationItemPosition = NavigationItemPosition.TOP
    enabled: bool = True


class MainWindow(MSFluentWindow):
    def __init__(self):
        super().__init__()

        setThemeColor(MAIN_THEME_COLOR)
        self.setCustomBackgroundColor(BLUE_BACKGROUND_COLOR, BLUE_BACKGROUND_COLOR)
        self.interface_specs = self.build_interface_specs()
        self.interfaces = self.create_interfaces(self.interface_specs)
        self.bind_error_handlers()

        self.initNavigation()
        self.initWindow()

    def build_interface_specs(self) -> list[InterfaceSpec]:
        return [
            InterfaceSpec(
                key="achievement",
                factory=lambda: AchievementWidget('Achievement Interface', self),
                icon=FluentIcon.SPEED_HIGH,
                nav_text='达成度',
                enabled=True,
            ),
            InterfaceSpec(
                key="defense",
                factory=lambda: DefenseWidget('Defense Interface', self),
                icon=FluentIcon.FEEDBACK,
                nav_text='答辩',
                enabled=True,
            ),
            InterfaceSpec(
                key="picker",
                factory=lambda: PickerWidget('Picker Interface', self),
                icon=FluentIcon.PEOPLE,
                nav_text='提问',
                enabled=not RELEASE_ENV,
            ),
            InterfaceSpec(
                key="test",
                factory=lambda: TestWidget('Test Interface', self),
                icon=FluentIcon.VIEW,
                nav_text='测试',
                enabled=not RELEASE_ENV,
            ),
            InterfaceSpec(
                key="about",
                factory=lambda: AboutWidget('About Interface', self),
                icon=FluentIcon.INFO,
                nav_text='关于',
                position=NavigationItemPosition.BOTTOM,
                enabled=True
            ),
        ]

    def create_interfaces(self, specs: list[InterfaceSpec]) -> dict[str, object]:
        interfaces: dict[str, object] = {}
        for spec in specs:
            if not spec.enabled:
                continue
            widget = spec.factory()
            interfaces[spec.key] = widget
            setattr(self, f"{spec.key}Interface", widget)
        return interfaces

    def bind_error_handlers(self):
        achievement = self.interfaces.get("achievement")
        defense = self.interfaces.get("defense")

        if achievement and hasattr(achievement, "error"):
            achievement.error.connect(self.showError)
        if defense and hasattr(defense, "errorSignal"):
            defense.errorSignal.connect(self.showError)

    def initNavigation(self):
        for spec in self.interface_specs:
            widget = self.interfaces.get(spec.key)
            if not widget:
                continue
            self.addSubInterface(widget, spec.icon, spec.nav_text, position=spec.position)

    def initWindow(self):
        self.resize(900, 700)
        self.setWindowTitle('教学工具箱')
        self.setWindowIcon(QIcon(':/images/logo.png'))

    def showError(self, title: str, message: str):
        box = MessageBox(title, message, self)
        box.yesButton.setText("关闭")
        box.cancelButton.hide()
        box.exec()

    def showEvent(self, event: QShowEvent):
        super().showEvent(event)
        if RELEASE_ENV:
            import pyi_splash
            pyi_splash.update_text('正在加载...')
            pyi_splash.close()
