import random
from db_utils import get_or_create_user, add_pull, get_db_connection
from add_character import add_character

def get_character():
    ''' Gets a random character from the database'''
    conn = get_db_connection()
    cur = conn.cursor()
    cur.execute('SELECT * FROM characters')
    characters = cur.fetchall()
    conn.close()

    if not characters:
        return None, None, None, None

    weights = [c['weight'] for c in characters]
    chosen = random.choices(characters, weights=weights, k=1)[0]

    return chosen['id'], chosen['name'], chosen['file_id'], chosen['rarity']

def is_float(val):
    try:
        float(val)
        return True
    except ValueError:
        return False


# TODO: See issue #3, separate command parsing from game logic.
def gacha_response(command,full_user, arguments,note_obj):
    '''Parses a given command with arguments, processes the game state and
    returns a response'''

    if command == "roll":
        user_id = get_or_create_user(full_user)
        character_id, character_name, file_id, rarity = get_character()

        if not character_id:
            #TODO: Can't have tuples of a single element
            # Return these as a dict or object instead.
            return(f"@{full_user} Uwaaa... something went wrong! No characters found. 😿")

        add_pull(user_id,character_id)
        stars = '⭐️' * rarity
        return([f"@{full_user} 🎲 Congrats! You rolled {stars} **{character_name}**\nShe's all yours now~ 💖✨",[file_id]])

    if command == "create":
        # Example call from bot logic
        image_url = note_obj.get("files", [{}])[0].get("url") if note_obj.get("files") else None
        if not image_url:
            return "You need an image to create a character, dumbass."

        if len(arguments) != 3:
            return "Please specify the following attributes in order: name, rarity, drop weighting"

        if not (arguments[1].isnumeric() and 1 <= int(arguments[1]) <= 5):
            return f"Invalid rarity: '{arguments[1]}' must be a number between 1 and 5"

        if not (is_float(arguments[2]) and 0.0 < float(arguments[2]) <= 1.0):
            return f"Invalid drop weight: '{arguments[2]}' must be a decimal value between 0.0 and 1.0"

        character_id, file_id = add_character(
            name=arguments[0],
            rarity=int(arguments[1]),
            weight=float(arguments[2]),
            image_url=image_url
        )
        return([f"Added {arguments[0]}, ID {character_id}.",[file_id]])
    return None