import configparser
from os.path import exists
from NoiseGatev2 import AudioStream

PDB_ACCEPTABLE_HANDLERS = {'gqrx': {
                               'Modes': ['wfm', 'fm']
                           },
                           'op25': {
                               'Modes': ['d', 'p25']
                           }}
PDB_KNOWN_BOT_IDS = {756327271597473863: "Greada", 915064996994633729: "Jorn", 943742040255115304: "Brent"}

DEFAULT_NOISEGATE_THRESHOLD = 50


def check_if_config_exists():
    if exists('./config.ini'):
        config = configparser.SafeConfigParser()
        config.read('./config.ini')
        if config.has_section('Bot_Info') and config.has_section('Device') and config.has_section('Config'):
            return True
        else:
            return False
    else:
        return False


def read_config_file():
    config = configparser.ConfigParser()
    config.read('./config.ini')

    config_return = {
        'Bot Token': config['Bot_Info']['Token'],
        'Device ID': int(config['Device']['ID']),
        'Device Name': str(config['Device']['Name']),
        'Mention Group': str(config['Bot_Info']['Mention_Group']),
        'Channel ID': int(config['Bot_Info']['Channel_ID']),
        'Handler': str(config['Config']['Handler'])
    }

    print("Found config options:")
    for key in config_return.keys():
        print(f"\t{key} : {config_return[key]}")

    return config_return


def write_config_file(**kwargs):
    config = configparser.SafeConfigParser()

    if not kwargs['init'] and exists('./config.ini'):
        config.read('./config.ini')

    if not config.has_section('Bot_Info'):
        config.add_section('Bot_Info')

    if not config.has_section('Config'):
        config.add_section('Config')

    if not config.has_section('Device'):
        config.add_section('Device')

    if 'handler' in kwargs.keys():
        config['Config']['Handler'] = str(kwargs['handler'])
    elif kwargs['init']:
        config['Config']['Handler'] = str(get_handler())

    if 'token' in kwargs.keys():
        config['Bot_Info']['Token'] = str(kwargs['token'])
    elif kwargs['init']:
        config['Bot_Info']['Token'] = str(get_user_token())

    if 'device_id' in kwargs.keys() or 'device_name' in kwargs.keys():
        config['Device']['ID'] = str(kwargs['device_id'])
        config['Device']['Name'] = str(kwargs['device_name'])
    elif kwargs['init']:
        device_id, device_name = get_user_device_selection()
        config['Device']['ID'] = str(device_id)
        config['Device']['Name'] = str(device_name)

    if 'mention_group' in kwargs.keys():
        config['Bot_Info']['Mention_Group'] = str(kwargs['mention_group'])
    elif kwargs['init']:
        config['Bot_Info']['Mention_Group'] = str(get_user_mention_group())

    if 'channel_id' in kwargs.keys():
        config['Bot_Info']['Channel_ID'] = str(kwargs['channel_id'])
    elif kwargs['init']:
        config['Bot_Info']['Channel_ID'] = str(get_user_mention_channel_id())

    with open('./config.ini', 'w') as config_file:
        config.write(config_file)

    print("Config Saved")

    return True


def get_device_list():
    list_of_devices = sound.query_devices().items()
    print(list_of_devices)
    return list_of_devices


def get_user_device_selection():
    device_list = get_device_list()
    org_device_list = []
    for device, dev_id in device_list:
        print(f"{dev_id + 1}\t-\t{device}")
        org_device_list.append((dev_id, device))
    selected_list_id = None
    selected_device = None
    while not selected_list_id:
        print(f"selected device: {selected_list_id}")
        print(device_list)

        try:
            selected_list_id = int(input(f"Please select the input device from above:\t"))            

        except Exception as e:
            print(e)
            continue             

        if int(selected_list_id) < int(len(device_list)):
            print("ford")
            continue
        elif selected_list_id > int(len(device_list)):
            print("Out of range, try again...")
            selected_list_id = None
            continue
        else:
            selected_list_id = None
            print("Internal error, try again")
            continue

    for dev_dict in org_device_list:
        print(list(device_list)[selected_list_id-1][0])
        if dev_dict[1] == list(device_list)[selected_list_id-1][0]:            
            selected_device = dev_dict
            print(selected_device)

    return selected_device


def get_user_token():
    token = None
    while not token:
        token = str(input(f"Please enter your Discord bot API token now:\t"))
        if len(token) == 59:
            return token
        else:
            print('Length error in token, please try again...')
            token = None
            continue


def get_user_mention_group():
    mention_group = None
    while not mention_group:
        mention_group = str(input(f"Please enter the name of the group you would like to mention:\t"))
        return mention_group


def get_user_mention_channel_id():
    channel_id = None
    while not channel_id:
        channel_id = int(input(f"Please enter the channel ID of the the default channel you would like messages to be sent in:\t"))
        if len(str(channel_id)) == len('757379843792044102'):
            return channel_id
        else:
            print("Length error in ID, please try again")
            channel_id = None
            continue


def get_handler():
    handler = None
    while not handler:
        handler = str(input(f"Please enter the name of the handler you would like to use:\t"))
        if handler in PDB_ACCEPTABLE_HANDLERS:
            return handler
        elif handler == ['', "none"]:
            handler = "None"
            return handler


def check_negative(s):
    try:
        f = float(s)
        if (f < 0):
            return True
        # Otherwise return false
        return False
    except ValueError:
        return False


# Check if message is a ping request and respond even if it is a bot
async def check_and_reply_to_ping(bot, message):
    if "check_modules" in message.content:
        ctx = await bot.get_context(message)
        await bot.invoke(ctx)
        return True
    else:
        await bot.process_commands(message)
        return False
