import itertools
import operator
from pathlib import Path

import requests

from . import settings
from .utils import Utils


class SpigetAPI:
    headers: dict = {
        "user-agent": settings.USER_AGENT,
    }

    @staticmethod
    def build_api_url(api_request: str) -> str:
        return f"{settings.API_URL}{api_request}"

    # noinspection PyDefaultArgument
    def call_api(self, api_request: str, params: dict = {}) -> requests.Response:
        response: requests.Response = requests.get(
            self.build_api_url(api_request),
            params=params,
            headers=self.headers,
        )
        return response

    def search_plugins(self, plugin_name: str) -> list:
        response_tag = self.call_api(
            f"/search/resources/{plugin_name}",
            {
                "field": "tag",
                "sort": "-downloads",
                "size": 10,
            },
        )
        response_name = self.call_api(
            f"/search/resources/{plugin_name}",
            {
                "field": "name",
                "sort": "-downloads",
                "size": 10,
            },
        )

        if response_name.status_code == 404:
            return Utils.error(f"No plugin with name {plugin_name} found.")

        # Merge tag search and title searches together
        plugin_list: list = response_tag.json() + response_name.json()

        # Sort the list by highest download, then IDs
        plugin_list.sort(key=operator.itemgetter("downloads", "id"), reverse=True)

        # remove duplicate ids from list
        plugin_list = [id_field[0] for id_field in itertools.groupby(plugin_list)]

        return plugin_list[:5]

    def get_latest_version(self, plugin_name: str) -> dict:
        # TODO
        pass

    def download_plugin(self, plugin: dict) -> dict:
        """
        Download a plugin

        :param plugin: Dict containing plugin name, tag, and ID
        :return: dict as generated by Utils.status_dict
        """
        response = self.call_api(
            f"/resources/{plugin.get('id')}/download",
        )

        safe_plugin_name = Utils.create_jar_name(plugin.get("name"))
        with open(Path(f"./{safe_plugin_name}.jar").__str__(), "wb") as f:
            f.write(response.content)
            pass

        return Utils.status_dict(True)
