import random
from typing import Callable

from tosstypes import BotAction, CoinSide, HEADS, TAILS

class Bot:
    money: float
    n_tosses: int
    odds: float

    def __init__(self, money: float, n_tosses: int, odds: float) -> None:
        self.money = money
        self.n_tosses = n_tosses
        self.odds = odds

    def handle_toss(self, toss_result: CoinSide, bet_return: float) -> None:
        pass

    def next_action(self) -> BotAction:
        return None

    def __repr__(self) -> str:
        return f'{self.__class__.__qualname__}(money={self.money})'

BotFactory = Callable[[float, int, float], Bot]

class RandomBot(Bot):
    """
    RandomBot randomly chooses a side to flip for each time. It will flip
    up to `max_tosses` times, betting `wager` each time.
    """
    max_tosses: int
    played_tosses: int
    wager: float

    def __init__(self, money: float, n_tosses: int, odds: float) -> None:
        super().__init__(money, n_tosses, odds)
        self.max_tosses = 10
        self.played_tosses = 0
        self.wager = 5

    def handle_toss(self, toss_result: CoinSide, bet_return: float) -> None:
        # Update money and number of tosses
        self.money += bet_return
        self.played_tosses += 1

    def next_action(self) -> BotAction:
        # Quit if we've played enough games
        if self.played_tosses >= self.max_tosses:
            return None

        # Toss a random side
        side = random.choice([HEADS, TAILS])
        return (side, self.wager)