#!/usr/bin/python3


from __future__ import annotations

import logging
from pathlib import Path
from typing import Any, Optional

import tomlkit

from slpkg.blacklist import Blacklist
from slpkg.config import config_load
from slpkg.utilities import Utilities

logger = logging.getLogger(__name__)


class BlacklistCmd:  # pylint: disable=[R0902]
    """Manage and display the blacklisted packages."""

    def __init__(self, options: Optional[dict[str, Any]] = None) -> None:
        logger.debug("Initializing BlacklistCmd.")
        self.blacklist_file: Path = Path(config_load.etc_path, "blacklist.toml")
        self.bold = config_load.bold
        self.grey = config_load.grey
        self.cyan = config_load.cyan
        self.green = config_load.green
        self.endc = config_load.endc
        self.quiet: bool = (options or {}).get("option_quiet", False)
        self.black = Blacklist()
        self.utils = Utilities()

    def _read_toml(self) -> tomlkit.TOMLDocument:
        """Read the blacklist TOML file, returning an empty document if absent."""
        if self.blacklist_file.is_file():
            return tomlkit.parse(self.blacklist_file.read_text(encoding="utf-8"))
        doc = tomlkit.document()
        doc.add("PACKAGES", tomlkit.array())
        return doc

    def _write_toml(self, doc: tomlkit.TOMLDocument) -> None:
        """Write the TOML document back to the blacklist file."""
        self.blacklist_file.write_text(tomlkit.dumps(doc), encoding="utf-8")

    def add(self, packages: list[str]) -> None:
        """Add packages to the blacklist (skips duplicates)."""
        doc = self._read_toml()
        current: list[str] = [str(p) for p in doc.get("PACKAGES", [])]
        added: list[str] = []
        for name in packages:
            if name not in current:
                current.append(name)
                added.append(name)
            else:
                print(f"{name}: already in blacklist")
                logger.info("Package '%s' already in blacklist, skipping.", name)

        arr = tomlkit.array()
        arr.extend(current)
        doc["PACKAGES"] = arr
        self._write_toml(doc)

        for name in added:
            print(f"  {self.green}+{self.endc} {name}")
            logger.info("Added '%s' to blacklist.", name)

        if added:
            noun = "package" if len(added) == 1 else "packages"
            print(f"\nAdded {self.cyan}{len(added)}{self.endc} {noun} to the blacklist.")
            print(f"{self.grey}{self.blacklist_file}{self.endc}")

    def remove(self, packages: list[str]) -> None:
        """Remove packages from the blacklist.

        If packages is empty, removes all entries (clear).
        Warns for any name not found in the list.
        """
        doc = self._read_toml()
        current: list[str] = [str(p) for p in doc.get("PACKAGES", [])]
        removed: list[str] = []
        if not packages:
            removed = current[:]
            current = []
        else:
            for name in packages:
                if name in current:
                    current.remove(name)
                    removed.append(name)
                else:
                    print(f"{name}: not in blacklist")
                    logger.info("Package '%s' not found in blacklist, skipping.", name)

        arr = tomlkit.array()
        arr.extend(current)
        doc["PACKAGES"] = arr
        self._write_toml(doc)

        for name in removed:
            print(f"  {self.cyan}-{self.endc} {name}")
            logger.info("Removed '%s' from blacklist.", name)

        if removed:
            noun = "package" if len(removed) == 1 else "packages"
            print(f"\nRemoved {self.cyan}{len(removed)}{self.endc} {noun} from the blacklist.")
            print(f"{self.grey}{self.blacklist_file}{self.endc}")

    def view(self) -> None:
        """Display blacklisted packages."""
        pkgs = sorted(self.black.packages())

        if self.quiet:
            for name in pkgs:
                print(name)
            logger.info("Blacklist view completed (quiet). %d entries.", len(pkgs))
            return

        print(f"{self.bold}Blacklisted packages (excluded from all operations):{self.endc}")

        if not pkgs:
            print(" No blacklisted packages found.")
            print(f"\n{self.grey}{self.blacklist_file}{self.endc}")
            logger.info("Blacklist is empty.")
            return

        for name in pkgs:
            print(f"  {self.green}{name}{self.endc}")

        count = len(pkgs)
        noun = "package" if count == 1 else "packages"
        print(f"\nFound {self.cyan}{count}{self.endc} blacklisted {noun}.")
        print(f"{self.grey}{self.blacklist_file}{self.endc}")
        logger.info("Blacklist view completed. %d entries.", count)
