"""OneSignal App Client class."""
from .base_client import OneSignalBaseClient


class OneSignalAppClient(OneSignalBaseClient):
    """OneSignal Client."""

    ENDPOINTS = {
        "notifications": "notifications",
        "devices": "players",
        "csv_export": "players/csv_export",
        "apps": "apps",
    }

    AVAILABLE_EXTRA_FIELDS = ["location", "country", "rooted"]

    def __init__(self, app_id, app_api_key):
        """
        Initializes the OneSignal Client.

        :param app_id: OneSignal App ID.
        Found under OneSignal Dashboard > App Settings > Keys & IDs
        :type app_id: string
        :param app_api_key: Application REST API key.
        Found under OneSignal Dashboard > App Settings > Keys & IDs
        :type app_api_key: string
        """
        self.app_id = app_id
        self.app_api_key = app_api_key
        self.mode = self.MODE_APP

    def get_headers(self):
        """
        Build default headers for requests.
        :return: Returns dict which contains the headers
        """
        return self._get_headers()

    def create_notification(self, payload):
        """
        Creates a new notification.
        :param payload: the payload of the notification to create
        """
        return self.post(self._url(self.ENDPOINTS["notifications"]), payload=payload)

    def cancel_notification(self, notification_id):
        """
        Cancel a notification.
        :param notification_id: Notification identifier
        """
        endpoint = "{endpoint}/{nid}?app_id={app_id}".format(
            endpoint=self.ENDPOINTS["notifications"],
            nid=notification_id,
            app_id=self.app_id,
        )
        return self.delete(self._url(endpoint))

    def view_devices(self, limit=300, offset=0):
        endpoint = "{endpoint}?app_id={app_id}&limit={limit}&offset={offset}".format(
            endpoint=self.ENDPOINTS["devices"],
            app_id=self.app_id,
            limit=limit,
            offset=offset,
        )
        yield self.get(self._url(endpoint))

    def view_device(self, device_id):
        endpoint = "{endpoint}/{device_id}".format(
            endpoint=self.ENDPOINTS["devices"], device_id=device_id
        )
        return self.get(self._url(endpoint))

    def csv_export(self, extra_fields=[]):
        """
        Request a CSV export from OneSignal.
        :return: Returns the request result.
        """
        payload = {"extra_fields": []}

        if isinstance(extra_fields, list) and len(extra_fields) > 0:
            payload["extra_fields"] = [
                x for x in extra_fields if x in self.AVAILABLE_EXTRA_FIELDS
            ]

        endpoint = "{endpoint}?app_id={app_id}".format(
            endpoint=self.ENDPOINTS["csv_export"], app_id=self.app_id
        )
        return self.post(self._url(endpoint), payload=payload)

    def edit_device(self, device_id, payload):
        """
        Update an existing device in one of your OneSignal apps
        :param payload: the payload of the device to edit

        https://documentation.onesignal.com/reference/edit-device
        """
        endpoint = "{endpoint}/{device_id}".format(
            endpoint=self.ENDPOINTS["devices"], device_id=device_id
        )
        return self.put(self._url(endpoint), payload=payload)

    def edit_tags_with_external_user_id(self, external_user_id, tags):
        """
        Update an existing device in one of your OneSignal apps
        :param payload: the payload of the device to edit

        https://documentation.onesignal.com/reference/edit-device
        """
        endpoint = "{endpoint}/{app_id}/users/{external_user_id}".format(
            endpoint=self.ENDPOINTS["apps"],
            app_id=self.app_id,
            external_user_id=external_user_id,
        )
        return self.put(self._url(endpoint), payload=tags)

    def delete_user_record(self, player_id):
        """
        Delete a user record
        Used to delete a single, specific Player ID record from a specific OneSignal app.

        https://documentation.onesignal.com/reference/delete-user-record
        """
        endpoint = "{endpoint}/{player_id}?app_id={onesignal_app_id}".format(
            endpoint=self.ENDPOINTS["devices"],
            player_id=player_id,
            onesignal_app_id=self.app_id,
        )
        return self.delete(self._url(endpoint))
