from typing import List, Optional

from moodle import BaseMoodle
from . import (
    Content,
    FunctionsResponses,
    Key,
    MobileConfig,
    MobilePlugin,
    MobilePublicConfig,
    TokenPrivateToken,
)
from .validated_key import ValidatedKey


class BaseMobile(BaseMoodle):
    def call_external_functions(
            self,
            requests: List[FunctionsResponses.Request]) -> FunctionsResponses:
        """Call multiple external functions and return all responses.

        Args:
            requests (List[FunctionsResponses.Request]): Functions requests

        Returns:
            FunctionsResponses: Functions Response
        """
        res = self.moodle.post('tool_mobile_call_external_functions')
        return self._tr(FunctionsResponses, **res)

    def get_autologin_key(self, privatetoken: str) -> Key:
        """Creates an auto-login key for the current user.
        Is created only in https sites and is restricted by time, ip address
        and only works if the request comes from the Moodle mobile or desktop app.

        Args:
            privatetoken (str): Private token, usually generated by login/token.php

        Returns:
            Key: Key object containing auto-login
        """
        res = self.moodle.post('tool_mobile_get_autologin_key',
                               privatetoken=privatetoken)
        return self._tr(Key, **res)

    def get_config(self, section: Optional[str] = None) -> MobileConfig:
        """Returns a list of the site configurations, filtering by section.

        Args:
            section (str, optional): Settings section name. Defaults to None.

        Returns:
            MobileConfig: Returns a list of the site configurations, filtering by section.
        """
        res = self.moodle.get('tool_mobile_get_config', section=section or '')
        return self._tr(MobileConfig, **res)

    def get_content(self,
                    component: str,
                    method: str,
                    args: Optional[Content.Args] = None) -> Content:
        """Get a piece of content to be displayed in the Mobile app.

        Args:
            component (str): Component where the class is e.g. mod_assign.
            method (str): Method to execute in class \\$component\\output\\mobile.
            args (Optional[Content.Args], optional): Args for the method are optional.. Defaults to None.

        Returns:
            Content: Returns a piece of content to be displayed in the Mobile app.
        """
        res = self.moodle.post(
            'tool_mobile_get_content',
            component=component,
            method=method,
            args=args,
        )
        return self._tr(Content, **res)

    def get_plugins_supporting_mobile(self) -> List[MobilePlugin]:
        """Get a list of Moodle plugins supporting the mobile app.

        Returns:
            List[MobilePlugin]: Returns a list of Moodle plugins supporting the mobile app.
        """
        res = self.moodle.get('tool_mobile_get_plugins_supporting_mobile')
        results: List[MobilePlugin] = list()
        if not res:
            return results
        plugins = res['plugins']
        for plugin in plugins:
            results.append(MobilePlugin(**plugin))  # type: ignore
        return results

    def get_public_config(self) -> MobilePublicConfig:
        """Get a list of the site public settings, those not requiring authentication.

        Returns:
            MobilePublicConfig: Returns a list of the site public settings, those not requiring authentication.
        """
        data = self.moodle.get('tool_mobile_get_public_config')
        return self._tr(MobilePublicConfig, **data)

    def get_tokens_for_qr_login(self, qrloginkey: str,
                                userid: int) -> TokenPrivateToken:
        """Returns a WebService token (and private token) for QR login.

        Args:
            qrloginkey (str): The user key for validating the request.
            userid (int): The user the key belongs to.

        Returns:
            TokenPrivateToken: WebService token (and private token)
        """
        data = self.moodle.post(
            'tool_mobile_get_tokens_for_qr_login',
            qrloginkey=qrloginkey,
            userid=userid,
        )
        return self._tr(TokenPrivateToken, **data)

    def validate_subscription_key(self, key: str) -> ValidatedKey:
        data = self.moodle.post(
            'tool_mobile_validate_subscription_key',
            key=key,
        )
        return self._tr(ValidatedKey, **data)
