"""
Contains the code that deals with money.

*Classes*
---------
  Money
    Deals with money.
"""
import typing

import interactions  # Used for typehints

if typing.TYPE_CHECKING:
  from gwendolyn_client import Gwendolyn

class Money():
  """
  Deals with money.

  *Methods*
  ---------
    checkBalance(user: str)
    sendBalance(ctx: interactions.SlashContext)
    addMoney(user: str, amount: int)
    giveMoney(ctx: interactions.SlashContext, user: discord.User,
          amount: int)

  *Attributes*
  ------------
    bot: Gwendolyn
      The instance of Gwendolyn
    database: pymongo.Client
      The mongo database
  """

  def __init__(self, bot: "Gwendolyn"):
    """Initialize the class."""
    self.bot = bot
    self.database = bot.database

  def checkBalance(self, user: str):
    """
    Get the account balance of a user.

    *Parameters*
    ------------
      user: str
        The user to get the balance of.

    *Returns*
    ---------
      balance: int
        The balance of the user's account.
    """
    self.bot.log("checking "+user+"'s account balance")

    user_data = self.database["users"].find_one({"_id": user})

    if user_data is not None:
      return user_data["money"]
    else:
      return 0

  async def sendBalance(self, ctx: interactions.SlashContext):
    """
    Get your own account balance.

    *Parameters*
    ------------
      ctx: interactions.SlashContext
        The context of the command.
    """
    await ctx.defer()
    response = self.checkBalance("#"+str(ctx.author.id))
    user_name = ctx.author.display_name
    if response == 1:
      new_message = f"{user_name} has 1 GwendoBuck"
    else:
      new_message = f"{user_name} has {response} GwendoBucks"
    await ctx.send(new_message)

  # Adds money to the account of a user
  def addMoney(self, user: interactions.User, amount: int):
    """
    Add money to a user account.

    *Parameters*
    ------------
      user: User
        The user to give money.
      amount: int
        The amount to add to the user's account.
    """
    self.bot.log(f"adding {amount} to {user}'s account")
    user_id = f"#{user.id}"

    user_data = self.database["users"].find_one({"_id": user_id})

    if user_data is not None:
      updater = {"$inc": {"money": amount}}
      self.database["users"].update_one({"_id": user_id}, updater)
    else:
      new_user = {
        "_id": user_id,
        "user name": user.display_name,
        "money": amount
      }
      self.database["users"].insert_one(new_user)

  # Transfers money from one user to another
  async def giveMoney(self, ctx: interactions.SlashContext,
            user: interactions.User, amount: int):
    """
    Give someone else money from your account.

    *Parameters*
    ------------
      ctx: interactions.SlashContext
        The context of the command.
      user: interactions.User
        The user to give money.
      amount: int
        The amount to transfer.
    """
    await ctx.defer()
    username = user.display_name

    userid = f"#{ctx.author.id}"
    user_data = self.database["users"].find_one({"_id": userid})

    if amount <= 0:
      self.bot.log("They tried to steal")
      await ctx.send("Yeah, no. You can't do that")
    elif user_data is None or user_data["money"] < amount:
      self.bot.log("They didn't have enough GwendoBucks")
      await ctx.send("You don't have that many GwendoBuck")
    else:
      self.addMoney(ctx.author, -1 * amount)
      self.addMoney(user, amount)
      await ctx.send(f"Transferred {amount} GwendoBucks to {username}")
