import enum
import logging
import warnings

import click

from .click_common import command, format_output
from .device import Device, DeviceStatus

_LOGGER = logging.getLogger(__name__)


class PlayState(enum.Enum):
    Playing = "PLAYING"
    Stopped = "STOPPED"
    Paused = "PAUSED_PLAYBACK"
    NoMedia = "NO_MEDIA_PRESENT"
    Transitioning = "TRANSITIONING"


class TransportChannel(enum.Enum):
    Playlist = "PLAYLIST"
    OneTime = "ONETIME"
    Auxiliary = "AUX"
    Bluetooth = "BT"
    Radio = "RADIO"
    Air = "AIR"
    Qplay = "QPLAY"


class WifiSpeakerStatus(DeviceStatus):
    """Container of a speaker state.

    This contains information such as the name of the device, and what is currently
    being played by it.
    """

    def __init__(self, data):
        """Example response of a xiaomi.wifispeaker.v2:

        {"DeviceName": "Mi Internet Speaker", "channel_title\": "XXX",
         "current_state": "PLAYING", "hardware_version": "S602",
         "play_mode": "REPEAT_ALL", "track_artist": "XXX",
         "track_duration": "00:04:58", "track_title": "XXX",
         "transport_channel": "PLAYLIST"}
        """
        self.data = data

    @property
    def device_name(self) -> str:
        """Name of the device."""
        return self.data["DeviceName"]

    @property
    def channel(self) -> str:
        """Name of the channel."""
        return self.data["channel_title"]

    @property
    def state(self) -> PlayState:
        """State of the device, e.g. PLAYING."""
        return PlayState(self.data["current_state"])

    @property
    def hardware_version(self) -> str:
        return self.data["hardware_version"]

    @property
    def play_mode(self):
        """Play mode such as REPEAT_ALL."""
        # note: this can be enumized when all values are known
        return self.data["play_mode"]

    @property
    def track_artist(self) -> str:
        """Artist of the current track."""
        return self.data["track_artist"]

    @property
    def track_title(self) -> str:
        """Title of the current track."""
        return self.data["track_title"]

    @property
    def track_duration(self) -> str:
        """Total duration of the current track."""
        return self.data["track_duration"]

    @property
    def transport_channel(self) -> TransportChannel:
        """Transport channel, e.g. PLAYLIST."""
        return TransportChannel(self.data["transport_channel"])


class WifiSpeaker(Device):
    """Device class for Xiaomi Smart Wifi Speaker."""

    def __init__(self, *args, **kwargs):
        warnings.warn(
            "Please help to complete this by providing more "
            "information about possible values for `state`, "
            "`play_mode` and `transport_channel`.",
            stacklevel=2,
        )
        super().__init__(*args, **kwargs)

    @command(
        default_output=format_output(
            "",
            "Device name: {result.device_name}\n"
            "Channel: {result.channel}\n"
            "State: {result.state}\n"
            "Play mode: {result.play_mode}\n"
            "Track artist: {result.track_artist}\n"
            "Track title: {result.track_title}\n"
            "Track duration: {result.track_duration}\n"
            "Transport channel: {result.transport_channel}\n"
            "Hardware version: {result.hardware_version}\n",
        )
    )
    def status(self) -> WifiSpeakerStatus:
        """Return device status."""
        return WifiSpeakerStatus(self.send("get_prop", ["umi"]))

    @command(default_output=format_output("Powering on"))
    def power(self):
        """Toggle power on and off."""
        # is this a toggle?
        return self.send("power")

    @command(default_output=format_output("Toggling play"))
    def toggle(self):
        """Toggle play."""
        return self.send("toggle")

    @command(
        click.argument("amount", type=int),
        default_output=format_output("Increasing volume by {amount} percent"),
    )
    def volume_up(self, amount: int = 5):
        """Set volume up."""
        return self.send("vol_up", [amount])

    @command(
        click.argument("amount", type=int),
        default_output=format_output("Decreasing volume by {amount} percent"),
    )
    def volume_down(self, amount: int = 5):
        """Set volume down."""
        return self.send("vol_down", [amount])

    @command(default_output=format_output("Playing previous track"))
    def track_previous(self):
        """Move to previous track."""
        return self.send("previous_track")

    @command(default_output=format_output("Playing next track"))
    def track_next(self):
        """Move to next track."""
        return self.send("next_track")

    @command(default_output=format_output("Switching to the next transport channel"))
    def channel_next(self):
        """Change transport channel."""
        return self.send("next_channel")

    @command(default_output=format_output("Track position: {result.rel_time}"))
    def track_position(self):
        """Return current track position."""
        return self.send("get_prop", ["rel_time"])

    def volume(self):
        """Speaker volume."""
        return self.send("get_prop", ["volume"])
