from typing import List, Optional
from moodle import BaseMoodle
from moodle.utils.helper import from_dict
from . import Content, FunctionsResponses, Key, MobileConfig, MobilePlugin, MobilePublicConfig


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 from_dict(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 from_dict(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 from_dict(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 from_dict(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')
        return [from_dict(MobilePlugin, data)
                for data in res['plugins']] if 'plugins' in res else []

    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 from_dict(MobilePublicConfig, data)
