import logging
import os
import signal
import sys
from pathlib import Path
from threading import Thread

from PySide6.QtCore import QTimer, QUrl, QObject
from PySide6.QtGui import QIcon
from PySide6.QtQml import QQmlApplicationEngine
from PySide6.QtQuickControls2 import QQuickStyle
from PySide6.QtWidgets import QApplication

from .core.bridge import Bridge
from .core.config import ConfigManager
from .core.monitor import SelectionMonitor
from .core.translator import TranslationService
from .ui.tray import TrayManager

logger = logging.getLogger(__name__)


class TranApp(QApplication):
    # View statuses mapping to QML "enum"
    STATUS_HINT = 0
    STATUS_LOADING = 1
    STATUS_RESULT = 2
    STATUS_ERROR = 3

    def __init__(self, sys_argv):
        super().__init__(sys_argv)
        self.setQuitOnLastWindowClosed(False)
        QQuickStyle.setStyle("Basic")
        
        self._setup_paths()
        self._setup_logging()
        self._setup_graceful_quit()
        
        # Periodic timer for responsiveness in some environments
        self.timer = QTimer()
        self.timer.start(500)
        self.timer.timeout.connect(lambda: None)

        # Components
        self.config = ConfigManager(self.config_dir)
        self.bridge = Bridge(self.config)
        self.translator = TranslationService(self.bridge, self.mirror_path)
        
        # UI Setup
        self.setWindowIcon(QIcon(str(self.icon_path)))
        self.tray = TrayManager(self, self.bridge)
        
        self.engine = QQmlApplicationEngine()
        self.engine.rootContext().setContextProperty("bridge", self.bridge)
        
        self.main_window = None
        self.monitor = None

    def _setup_paths(self):
        # Base paths
        self.package_dir = Path(__file__).parent
        self.resources_dir = self.package_dir / "resources"
        self.config_dir = Path.home() / ".config" / "tran"
        
        # Files
        self.icon_path = self.resources_dir / "icon.png"
        self.qml_path = self.resources_dir / "qml" / "main.qml"
        
        user_mirror = self.config_dir / "mirror.json"
        default_mirror = self.resources_dir / "mirror.json"
        self.mirror_path = user_mirror if user_mirror.exists() else default_mirror

    def _setup_logging(self):
        logging.basicConfig(
            level=logging.INFO,
            format="%(asctime)s - %(name)s - %(levelname)s - %(message)s",
        )
        # Suppress accessibility warnings
        os.environ["QT_LOGGING_RULES"] = "qt.accessibility.atspi=false"

    def _setup_graceful_quit(self):
        signal.signal(signal.SIGINT, lambda *args: self.quit())
        self.aboutToQuit.connect(self._on_quit)

    def _on_quit(self):
        if self.monitor:
            self.monitor.stop()
        logger.info("Application shutting down.")

    def run(self):
        # Load QML
        self.engine.load(QUrl.fromLocalFile(str(self.qml_path.absolute())))
        if not self.engine.rootObjects():
            return -1
        
        self.main_window = self.engine.rootObjects()[0]
        
        # Setup Monitor
        self.monitor = SelectionMonitor(self.bridge, self.translator, self)
        self.monitor.start()
        
        # Connections
        self._connect_signals()
        
        self.tray.show()
        return self.exec()

    def _connect_signals(self):
        self.bridge.retranslateRequest.connect(self._trigger_retranslate)
        self.bridge.translationError.connect(self._on_translation_error)
        self.bridge.hideSignal.connect(self.main_window.hide)

    def _trigger_retranslate(self, text):
        if not self.main_window:
            return
            
        self.main_window.setProperty("viewStatus", self.STATUS_LOADING)
        self.main_window.setProperty("result", None)
        
        request_id = self.bridge.incrementRequestId()
        Thread(target=self.translator.translate, args=(text, request_id), daemon=True).start()

    def _on_translation_error(self, error_msg):
        if self.main_window:
            self.main_window.setProperty("viewStatus", self.STATUS_ERROR)
        self.bridge.showToast("Network Error")
