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

import os
import json
import subprocess
from aptsources.sourceslist import SourcesList
from logging_config import logger

UPDATE_INDICATOR = "deb-software-indicator.service"

class SettingsModel:
    """
    Settings model for Debian Software Manager.
    """
    def __init__(self, main_model):
        self.model = main_model
        self.sources = SourcesList(deb822=True)

    def reload_sources(self):
        """
        Reload the sources.
        """
        self.sources = SourcesList(deb822=True)

    # -----------------------------
    # Repository logic
    # -----------------------------
    def get_repositories(self) -> list[tuple[str, bool]]:
        """
        Returns a deduplicated list of repositories.
        """
        return list(
            dict.fromkeys(
                (src.uri, not src.disabled)
                for src in self.sources.list
                if src.type == "deb"
            )
        )

    # -----------------------------
    # User config logic
    # -----------------------------
    def get_check_interval(self) -> int:
        """
        Returns the check interval in seconds.

        Returns:
            int: Check interval in seconds.
        """
        interval = self.model.config["check_interval"]
        path = os.path.join(self.model.save_dir, "config.json")

        if os.path.exists(path):
            with open(path, "r", encoding="utf-8") as f:
                user_cfg = json.load(f)
                interval = user_cfg.get("check_interval", interval)

        return interval

    def set_check_interval(self, interval: int) -> bool:
        """
        Sets the check interval in seconds.
        
        Args:
            interval (int): Check interval in seconds.

        Returns:
            bool: True if successful, False otherwise.
        """
        path = os.path.join(self.model.save_dir, "config.json")
        tmp_path = path + ".tmp"

        try:
            logger.info("Setting check interval to %d seconds...", interval)
            # Load existing config if present
            cfg = {}
            if os.path.exists(path):
                with open(path, "r", encoding="utf-8") as f:
                    try:
                        cfg = json.load(f)
                    except json.JSONDecodeError:
                        # Corrupted config > start fresh
                        cfg = {}

            # Update interval
            cfg["check_interval"] = interval

            # Ensure directory exists
            os.makedirs(self.model.save_dir, exist_ok=True)

            # Write atomically
            with open(tmp_path, "w", encoding="utf-8") as f:
                json.dump(cfg, f, indent=4)

            os.replace(tmp_path, path)
            return True

        except Exception as e:    # pylint: disable=broad-except
            logger.error("Failed to set check interval: %s", e)
            # Cleanup temp file if something went wrong
            if os.path.exists(tmp_path):
                try:
                    os.remove(tmp_path)
                except OSError:
                    pass
            return False

    # -----------------------------
    # Update indicator logic
    # -----------------------------
    def is_update_indicator_active(self) -> bool:
        """
        Checks if the update indicator service is enabled (not masked/disabled).

        Returns:
            bool: True if enabled, False otherwise.
        """
        result = subprocess.run(
            ["systemctl", "--user", "is-active", UPDATE_INDICATOR],
            stdout=subprocess.DEVNULL,
            stderr=subprocess.DEVNULL,
            check=False
        )
        return result.returncode == 0

    def enable_update_indicator(self) -> bool:
        """
        Enables and starts the update indicator.
        
        Returns:
            bool: True if successful, False otherwise.
        """
        try:
            if self.is_update_indicator_active():
                return True

            logger.info("Enabling update indicator...")
            logger.debug("Unmasking update indicator...")
            subprocess.run(["systemctl", "--user", "unmask", UPDATE_INDICATOR], check=True)
            logger.debug("Enabling update indicator...")
            subprocess.run(["systemctl", "--user", "enable", UPDATE_INDICATOR], check=True)
            logger.debug("Starting update indicator...")
            subprocess.run(["systemctl", "--user", "start", UPDATE_INDICATOR], check=True)
            logger.debug("Done enabling update indicator.")

            return self.is_update_indicator_active()

        except Exception as e:    # pylint: disable=broad-except
            logger.error("Failed to enable update indicator: %s", e)
            return False

    def disable_update_indicator(self) -> bool:
        """
        Stops and disables the update indicator.
        
        Returns:
            bool: True if successful, False otherwise.
        """
        try:
            if not self.is_update_indicator_active():
                return True

            logger.info("Disabling update indicator...")
            logger.debug("Stopping update indicator...")
            subprocess.run(["systemctl", "--user", "stop", UPDATE_INDICATOR], check=True)
            logger.debug("Disabling update indicator...")
            subprocess.run(["systemctl", "--user", "disable", UPDATE_INDICATOR], check=True)
            logger.debug("Masking update indicator...")
            subprocess.run(["systemctl", "--user", "mask", UPDATE_INDICATOR], check=True)
            logger.debug("Done disabling update indicator.")

            return not self.is_update_indicator_active()

        except Exception as e:    # pylint: disable=broad-except
            logger.error("Failed to disable update indicator: %s", e)
            return False

    def restart_update_indicator(self) -> None:
        """
        Restarts the update indicator.
        
        Returns:
            bool: True if successful, False otherwise.
        """
        try:
            if not self.is_update_indicator_active():
                return

            logger.info("Restarting update indicator...")
            subprocess.run(["systemctl", "--user", "restart", UPDATE_INDICATOR], check=True)
            logger.debug("Done restarting update indicator.")

        except Exception as e:    # pylint: disable=broad-except
            logger.error("Failed to restart update indicator: %s", e)
            return
