#!/usr/bin/env python3
"""
Main model for Debian Software Manager.

Author: Arjen Balfoort
Date: 2026-03-26
"""

import os
import sys
import json
import gettext

from app_shared import (
    show_dialog,
    DialogIcon,
    detect_desktop
)
from app_downloads import DownloadsHandler
from app_info import SoftwareManager
from image import ImageHandler
from logging_config import logger
from app_view import SoftwareView

import gi
gi.require_version('Gtk', '4.0')
from gi.repository import Gtk, Gdk  #pylint: disable=wrong-import-position

_ = gettext.translation('deb-software', fallback=True).gettext

class MainModel:
    """Holds the application state, data, and business logic."""

    def __init__(self, app):
        self.app = app
        self.desktop: str = detect_desktop()
        logger.debug("Desktop environment: %s", self.desktop)

        self.save_dir: str = os.path.expanduser("~/.config/deb-software")
        self.cache_dir: str = os.path.expanduser("~/.cache/deb-software")
        self.script_dir: str = os.path.abspath(os.path.dirname(__file__))
        self.data_dir: str = os.path.join(self.script_dir, "data")
        self.images_dir: str = os.path.join(self.script_dir, "images")

        display = Gdk.Display.get_default()
        self.icon_theme = Gtk.IconTheme.get_for_display(display)

        # Load configuration
        self.config = self._load_config()

        # Initialize handlers
        self.downloads_handler = DownloadsHandler()
        self.software_manager = None
        self.image_handler = None
        self.favorites = []
        self.pending_files = []
        self.parser_args = None
        self.software_view = None

        # Initialize managers
        self.initialize_managers()

        # Global exception handler
        sys.excepthook = self._handle_exception

    def _load_config(self):
        """Load configuration from JSON files."""
        config = {}
        with open(file=os.path.join(self.data_dir, "config.json"),
                  mode="r",
                  encoding="utf-8") as f:
            config = json.load(f)

        user_config = os.path.join(self.save_dir, "config.json")
        if os.path.exists(user_config):
            with open(file=user_config, mode="r", encoding="utf-8") as f:
                config.update(json.load(f))
        return config

    def _handle_exception(self, exc_type, exc_value, exc_traceback):
        """Global exception handler."""
        logger.error("Uncaught exception", exc_info=(exc_type, exc_value, exc_traceback))
        show_dialog(
            self.app.app_name,
            _("An unexpected error occurred.\nPlease check the log file for details."),
            icon=DialogIcon.ERROR
        )

    def initialize_managers(self):
        """Initialize software and image managers."""
        self.software_manager = SoftwareManager(self)
        self.image_handler = ImageHandler()
        self.software_view = SoftwareView(
            self.software_manager,
            self.image_handler,
            self.icon_theme,
            self.images_dir
        )
        self._load_favorites()

    def _load_favorites(self):
        """Load favorite packages."""
        with open(os.path.join(self.data_dir, "favorites.json"), "r", encoding="utf-8") as f:
            for key, packages in json.load(f).items():
                if key in ['all', self.desktop]:
                    for package in packages:
                        info = self.software_manager.get_package_summary(package, "debian")
                        if info:
                            self.favorites.append(info)

    def refresh_data(self):
        """Refresh the list of updates."""
        if self.software_manager:
            self.software_manager.refresh_data()

    def get_package_details(self, package_id, origin):
        """Get package details."""
        if self.software_manager:
            return self.software_manager.get_package_details(package_id, origin)
        return None

    def set_updates_label(self, label):
        """Set the updates label text."""
        if self.software_manager:
            label.set_text(
                f"{self.get_category_translation('updates')} "
                f"({self.software_manager.upgradable_count})"
            )

    @staticmethod
    def get_category_translation(category: str) -> str:
        """Get translated category name."""
        cat = category.lower()
        translations = {
            'accessor': _('Accessories'),
            'develop': _('Development'),
            'education': _('Education'),
            'games': _('Games'),
            'graphic': _('Graphics'),
            'internet': _('Internet'),
            'multimedia': _('Multimedia'),
            'office': _('Office'),
            'science': _('Science'),
            'system': _('System'),
            'update': _('Updates'),
        }
        return translations.get(cat, category.capitalize())
