import io
import random
from typing import List, Optional

import matplotlib
matplotlib.use("Agg")
import matplotlib.pyplot as plt
import numpy as np

from .errors import (
    CoolingNotEffectiveError,
    InvalidSliceCountError,
    TargetNotFoundError,
    TextTooLargeError,
)


def draw(return_bytes: bool = False) -> Optional[bytes]:
    x = np.linspace(-2, 2, 100)
    y = np.sqrt(np.clip(1 - (x / 2) ** 2, 0, None))
    fig, ax = plt.subplots()
    ax.fill_between(x, y, -y, color="green")
    ax.set_title("Here's your Kheera")
    ax.axis("equal")
    ax.axis("off")
    if return_bytes:
        buffer = io.BytesIO()
        fig.savefig(buffer, format="png", bbox_inches="tight")
        plt.close(fig)
        buffer.seek(0)
        return buffer.read()
    plt.show()
    plt.close(fig)
    return None


def slice(count: int = 5) -> List[str]:
    if count <= 0:
        raise InvalidSliceCountError(count)
    return [f"Kheera slice {index + 1}" for index in range(count)]


def cool_down(temp: int = 10) -> str:
    if temp <= 0:
        raise CoolingNotEffectiveError(temp)
    return f"Kheera applied. Temperature reduced by {temp}°C"


def rate_kheera() -> str:
    rating = random.randint(1, 10)
    return f"Kheera rating: {rating}/10"


def is_fresh() -> str:
    return random.choice(["Fresh", "Not Fresh"])


def throw(target: str) -> str:
    if not target:
        raise TargetNotFoundError()
    return f"Kheera thrown at {target}. SPLAT!"


def calculate_coolness(name: str) -> str:
    score = random.randint(0, 100)
    return f"{name} coolness score based on kheera: {score}"


def cucumberify(text: str) -> str:
    if len(text) > 4096:
        raise TextTooLargeError(len(text))
    return text.replace(" ", " kheera ")


def yoga_mode() -> str:
    return "Kheera yoga activated. Place kheera slices on eyes and relax."
