from db import fetch_db_rows_as_dicts
import google.generativeai as genai
import json
import os

GOOGLE_API_KEY=os.getenv('GEMINI_API_KEY')
genai.configure(api_key=GOOGLE_API_KEY)
model = genai.GenerativeModel(model_name = "gemini-pro")

def load_json_from_string(json_string):
    try:
        data = json.loads(json_string)
        return data
    except json.JSONDecodeError as e:
        print(f"Error decoding JSON: {e}")
    except Exception as e:
        print(f"An error occurred: {e}")

def concatenate_keys(keys):
    concatenated_string = ""
    for i, d in enumerate(keys, start=1):
        concatenated_string += f"{d} "
    return concatenated_string.strip()

def transform_to_dict_of_dicts(columns, rows):
    # Initialize the result dictionary
    result = {}

    # Iterate over each row
    for row in rows:
        print(dict(row))
        # The first element of the row is the key for the outer dictionary
        outer_key = row[0].strip()
        
        # Initialize the inner dictionary
        inner_dict = {}
        
        # Iterate over the rest of the elements in the row
        for i, value in enumerate(row[1:], start=1):
            # The corresponding column name is the key for the inner dictionary
            inner_key = columns[i].strip()
            # Add the key-value pair to the inner dictionary
            inner_dict[inner_key] = value
        
        # Add the inner dictionary to the result dictionary with the outer key
        result[outer_key] = inner_dict

    return result


def transform_topologies_to_dict(columns, rows):
    # Initialize the result dictionary
    result = {}

    # Iterate over each row
    for row in rows:
        print(dict(row))
        # The first element of the row is the key for the outer dictionary
        outer_key = row[0].strip()
        
        # Initialize the inner dictionary
        inner_dict = {}
        
        # Iterate over the rest of the elements in the row
        for i, value in enumerate(row[1:], start=1):
            # The corresponding column name is the key for the inner dictionary
            inner_key = columns[i].strip()
            # Add the key-value pair to the inner dictionary
            inner_dict[inner_key] = value
        
        # Add the inner dictionary to the result dictionary with the outer key
        result[outer_key] = inner_dict

    return result

def findTop3MoneyNeeds(proposition):
    moneyNeeds, rows = fetch_db_rows_as_dicts('money_needs.sqlite', 'money_needs')
    moneyNeedsDict = transform_to_dict_of_dicts(moneyNeeds, rows)
    print(list(moneyNeedsDict.keys()))
    needs = findTop3Needs(proposition, list(moneyNeedsDict.keys()))
    needDictIndexes = []
    for need in needs:
        needDictIndexes.append(moneyNeedsDict[need])

    print(needDictIndexes)
    return needs, needDictIndexes


def findTop3Needs(proposition, moneyNeeds):
    
    moneyNeedsString = concatenate_keys(moneyNeeds)

    prompt = '''You have these listed needs of customers
    {}

    Now given a proposition 
    "{}" 
    
    Find the best 3 strings out of the list which matches this proposition. Return output strictly only in json under a list called matches
    '''

    moneyNeedsPrompt = prompt.format(moneyNeedsString, proposition)
    response = model.generate_content([moneyNeedsPrompt])
    output = response.text
    output = output.replace('```json', '')
    output = output.replace('```', '')
    obj = load_json_from_string(output)
    print(obj)
    return obj['matches']


def findTop3Topologies(proposition):
    topologies, rows = fetch_db_rows_as_dicts('topologies.sqlite', 'topologies')
    
    topologiesDict = transform_to_dict_of_dicts(topologies, rows)
    print(topologiesDict)
    # prompt = '''You have these listed needs of customers
    # {}

    # Now given a proposition 
    # "{}" 
    
    # Find the best 3 strings out of the list which matches this proposition. Return output strictly only in json under a list called matches
    # '''

    # moneyNeedsPrompt = prompt.format(moneyNeedsString, proposition)
    # response = model.generate_content([moneyNeedsPrompt])
    # output = response.text
    # output = output.replace('```json', '')
    # output = output.replace('```', '')
    # obj = load_json_from_string(output)
    # print(obj)
    # return obj['matches']


def findTop3Needs(proposition, moneyNeeds):
    
    moneyNeedsString = concatenate_keys(moneyNeeds)

    prompt = '''You have these listed needs of customers
    {}

    Now given a proposition 
    "{}" 
    
    Find the best 3 strings out of the list which matches this proposition. Return output strictly only in json under a list called matches
    '''

    moneyNeedsPrompt = prompt.format(moneyNeedsString, proposition)
    response = model.generate_content([moneyNeedsPrompt])
    output = response.text
    output = output.replace('```json', '')
    output = output.replace('```', '')
    obj = load_json_from_string(output)
    print(obj)
    return obj['matches']


#findTop3Topologies('We have a product for family people giving them discounts and low interest loans for home appliances. They can pay us back in small instalments over the course of 4 years')
#findTop3MoneyNeeds('We have a product for family people giving them discounts and low interest loans for home appliances. They can pay us back in small instalments over the course of 4 years')

#We provide a credit card which gives 10% discount on purchasing home appliances and also provides low interest rates based loans