"""Mariner search command."""

import datetime as dt
import logging

import humanize
from cliff import lister

from mariner.models.torrent import Torrent
from mariner.utils import color

_DATE_FORMAT = "%Y-%m-%d"
_NAME_DISPLAY_WIDTH = 60


class Search(lister.Lister):
    """Search for torrents."""

    log = logging.getLogger(__name__)

    @staticmethod
    def _format_date(date: dt.datetime | None) -> str:
        """Format a datetime for display, or empty string if None."""
        if date is None:
            return ""
        return date.strftime(_DATE_FORMAT)

    @staticmethod
    def _availability(torrent: Torrent) -> str:
        """Show whether it is available as torrent, magnet link or both."""
        availability = []
        if torrent.magnet:
            availability.append("Magnet link")
        if torrent.download:
            availability.append("Torrent")
        if availability:
            return ", ".join(availability)
        if torrent.details_url:
            return "See details"
        return ""

    def get_parser(self, prog_name):
        """Add arguments to argument parser.

        Args:
            prog_name: Application name.

        Returns:
            Instance of argument parser.

        """
        parser = super().get_parser(prog_name)
        parser.add_argument("title", help="Title to search for", nargs="+")
        parser.add_argument(
            "--all",
            "-a",
            action="store_true",
            help="Search all available trackers",
        )
        parser.add_argument(
            "--anime",
            "-A",
            action="store_true",
            help="(deprecated) Has no effect",
        )
        parser.add_argument(
            "--filter",
            "-F",
            help="(deprecated) Has no effect",
            default=None,
        )
        parser.add_argument(
            "--legal",
            "-L",
            action="store_true",
            help="(deprecated) Has no effect",
        )
        parser.add_argument(
            "--limit",
            "-l",
            nargs="?",
            default=self.app.config["results"],
            help="Limit the number of results shown. Default is 50.",
            type=int,
        )
        parser.add_argument(
            "--newest",
            "-n",
            action="store_true",
            help="Sort results by newest",
        )
        parser.add_argument(
            "--trackers",
            "-t",
            action="append",
            choices=self.app.engine.available_trackers,
            help="Trackers that should be searched",
            default=[],
        )
        return parser

    _DEPRECATED_MSG = (
        "%s is deprecated and has no effect."
        " Use --trackers to select specific trackers."
    )

    def _warn_deprecated_filters(self, parsed_args) -> None:
        """Log deprecation warnings for removed filter flags."""
        if parsed_args.legal:
            self.log.warning(self._DEPRECATED_MSG, "--legal")
        if parsed_args.anime:
            self.log.warning(self._DEPRECATED_MSG, "--anime")
        if parsed_args.filter:
            self.log.warning(self._DEPRECATED_MSG, "--filter")

    def _parse_trackers(self, parsed_args):
        """Return a list of trackers to use.

        Args:
            parsed_args: List of parsed arguments.

        Returns:
            List of trackers to use.

        """
        if parsed_args.all:
            return self.app.engine.available_trackers

        if not parsed_args.trackers:
            parsed_args.trackers.append(self.app.config["default_tracker"])
        return [t.lower() for t in set(parsed_args.trackers)]

    def take_action(self, parsed_args):
        """Search for a torrent.

        Args:
            parsed_args: List of parsed arguments.

        Returns:
            List of torrents found.

        """
        self._warn_deprecated_filters(parsed_args)

        title = " ".join(parsed_args.title)
        limit = parsed_args.limit
        newest = parsed_args.newest

        trackers = self._parse_trackers(parsed_args)

        self.log.info(f"Searching for {color.cyan(title)}.")
        self.log.debug("title=%s limit=%s trackers=%s", title, limit, trackers)
        results = self.app.engine.search(title, trackers, limit, sort_by_newest=newest)

        headers = (
            "ID",
            "Name",
            "Tracker",
            "Seeds",
            "Size",
            "Uploaded",
            "Available as",
        )
        colored_headers = [color.cyan(h) for h in headers]
        columns = (
            (
                tid,
                color.yellow(t.name[:_NAME_DISPLAY_WIDTH]),
                t.tracker,
                color.green(t.seeders),
                humanize.naturalsize(t.size, binary=True) if t.size else "",
                self._format_date(t.date),
                self._availability(t),
            )
            for tid, t in results
        )
        return (colored_headers, columns)
