#%%
import pandas as pd 
from utils import get_random_string
from dotenv import load_dotenv
import os
import langchain
from langchain.prompts import PromptTemplate
from langchain.llms import OpenAI
from langchain.chat_models import ChatOpenAI
from openai import OpenAI
import json 
import requests
import datetime
import langid
import subprocess

load_dotenv()

llm = ChatOpenAI(model="gpt-3.5-turbo", temperature=0)

base_city = 'ChIJSXCeQSucgkcRKkOLNE9pK2U'

async def listen_audio(context, update):
    file = await context.bot.get_file(update.message.voice.file_id)

    print("file_id: " + str(update.message.voice.file_id))
    #save file 
    with open('data/taxi.ogg', 'wb') as f:
        await file.download_to_memory(f)
    
    #convert file
    subprocess.call([convert_script, input_file])

# transcript the audio 
def speech_to_text():
    
    client = OpenAI()
    audio_file= open("//Users/alessiogandelli/dev/cantiere/noi-hackaton-mooovex/data/taxi.mp3", "rb")
    transcript = client.audio.transcriptions.create(
    model="whisper-1", 
    file=audio_file
    )
    return transcript.text

# create a mp3 file from a text
def text_to_speech(text):
    client = OpenAI()

    speech_file_path = "data/reply.mp3"
    response = client.audio.speech.create(
    model="tts-1",
    voice="alloy",
    input=text
    )
    response.stream_to_file(speech_file_path)

# parse the text to extract the fields
def parse_trip(transcript):
    prompt = PromptTemplate.from_template("""you are a voice assistant of a taxi driver, you have to extract from his query the following fields, the starting point should be or a address or a point of interest (include the city in the address), if it is a point of interest just say the name and the place without conjunctions, if no date is provided write None, if no time is provided write None, infer the language that can be it, en or de: starting_point, end_point, number_of_passengers(int), date(format it like this "%Y-%m-%d"), time(format it like this"%H:%M:%S"), language(en, de, it) .Format it as a JSON. The query is  {query}?""")
    p = prompt.format(query=transcript)
    reply = llm.invoke(p)
    trip = json.loads(reply.content)

    if trip['date'] == 'None' or trip['date'] == None: 
        trip['date'] = datetime.datetime.now().strftime("%Y-%m-%d")
    
    if trip['time'] == 'None' or trip['time'] == None:
        trip['time'] = datetime.datetime.now().strftime("%H:%M:%S")

    if trip['language'] == 'None':
        langid.set_languages(['en', 'it', 'de'])  # limit detection to these languages
        language, _ = langid.classify(transcript)
        trip['language'] = language



    return trip

# parse the answer of the users and return or yes or no
def confirm_trip(transcript):
    prompt = PromptTemplate.from_template("the user have been asked if something is correct,< {query}> is the reply, you have to tell me if the user is confirming, you can only reply <yes> or <no>, lower case, without punctuation. The user could talk in italian or english or german")
    p = prompt.format(query=transcript)
    reply = llm.invoke(p)
    print(reply.content)
    # maybe return a boolean and interpret it here 
    return reply.content

# return the number of passengers in the voice message and return it 
def number_of_passangers(transcript):

    prompt = PromptTemplate.from_template("how many passengers? reply with json format with field named 'passengers' type int: {query}")
    p = prompt.format(query=transcript)
    reply = llm.invoke(p)
    n = json.loads(reply.content)['passengers']
    print(n)
    return n

# get google place id from mooovex api
def get_place_id(trip, context, update):

    url =  'https://dev.api.mooovex.com/hackathon/autocomplete'

    data_autocomplete_start = {
        'query': trip['starting_point'],
        'language': trip['language']
    }

    data_autocomplete_end = {
        'query': trip['end_point'],
        'language': trip['language']
    }

    print(trip)


    try:
        start_response = requests.post(url, json = data_autocomplete_start, timeout=30)
        place_id_start = start_response.json()[0]['google_place_id']

    except Exception as e:
        print("did not understand the starting point\n")
        # wait for user message 
        place_id_start = None

    try:
        end_response = requests.post(url, json = data_autocomplete_end)
        place_id_end = end_response.json()[0]['google_place_id']
    except Exception as e:
        print("did not understand the destination \n", e)        
        place_id_end = None

    return place_id_start, place_id_end

# search the route in mooovex api
def search_route(place_id_start, place_id_end, trip):
    url_route = 'https://dev.api.mooovex.com/hackathon/routedetails'

    data_route = {
        'origin_google_place_id': str(place_id_start),
        'destination_google_place_id': str(place_id_end),
        'passenger_count': trip['number_of_passengers'],
        'when':{
            'date': trip['date'],
            'time':  trip['time']
        },
        'language': trip['language']
    }

    route_response = requests.post(url_route, json = data_route)

    return route_response.json()

# generate the reply that the bot should say
def generate_reply(route, trip):
    # generate the reply
    try:
        msg = 'start: '+route['origin_place']['formatted_address'] + '\n'
        msg += 'end: '+route['destination_place']['formatted_address'] + '\n'
        msg += 'number of passengers: '+str(trip['number_of_passengers']) + '\n'
        msg += 'date: '+str(trip['date']) + '\n'
        msg += 'price: '+str(route['price']) + '\n'

    except:
        msg = 'error, try again'
    

    prompt = PromptTemplate.from_template("you are the taxidriver assistant, summarize the following trip in a short and syntetic message and ask to confirm, the trip, write it in the following language{language}: {query}")
    p = prompt.format(query=msg, language=trip['language'])
    reply = llm.invoke(p)
    print(reply.content)
    return reply.content




# %%

langchain.prompts.PromptTemplate.from_template langchain.chat_models.ChatOpenAI
[((347, 360), 'dotenv.load_dotenv', 'load_dotenv', ([], {}), '()\n', (358, 360), False, 'from dotenv import load_dotenv\n'), ((368, 416), 'langchain.chat_models.ChatOpenAI', 'ChatOpenAI', ([], {'model': '"""gpt-3.5-turbo"""', 'temperature': '(0)'}), "(model='gpt-3.5-turbo', temperature=0)\n", (378, 416), False, 'from langchain.chat_models import ChatOpenAI\n'), ((757, 802), 'subprocess.call', 'subprocess.call', (['[convert_script, input_file]'], {}), '([convert_script, input_file])\n', (772, 802), False, 'import subprocess\n'), ((868, 876), 'openai.OpenAI', 'OpenAI', ([], {}), '()\n', (874, 876), False, 'from openai import OpenAI\n'), ((1181, 1189), 'openai.OpenAI', 'OpenAI', ([], {}), '()\n', (1187, 1189), False, 'from openai import OpenAI\n'), ((1460, 2095), 'langchain.prompts.PromptTemplate.from_template', 'PromptTemplate.from_template', (['"""you are a voice assistant of a taxi driver, you have to extract from his query the following fields, the starting point should be or a address or a point of interest (include the city in the address), if it is a point of interest just say the name and the place without conjunctions, if no date is provided write None, if no time is provided write None, infer the language that can be it, en or de: starting_point, end_point, number_of_passengers(int), date(format it like this "%Y-%m-%d"), time(format it like this"%H:%M:%S"), language(en, de, it) .Format it as a JSON. The query is  {query}?"""'], {}), '(\n    \'you are a voice assistant of a taxi driver, you have to extract from his query the following fields, the starting point should be or a address or a point of interest (include the city in the address), if it is a point of interest just say the name and the place without conjunctions, if no date is provided write None, if no time is provided write None, infer the language that can be it, en or de: starting_point, end_point, number_of_passengers(int), date(format it like this "%Y-%m-%d"), time(format it like this"%H:%M:%S"), language(en, de, it) .Format it as a JSON. The query is  {query}?\'\n    )\n', (1488, 2095), False, 'from langchain.prompts import PromptTemplate\n'), ((2167, 2192), 'json.loads', 'json.loads', (['reply.content'], {}), '(reply.content)\n', (2177, 2192), False, 'import json\n'), ((2774, 3055), 'langchain.prompts.PromptTemplate.from_template', 'PromptTemplate.from_template', (['"""the user have been asked if something is correct,< {query}> is the reply, you have to tell me if the user is confirming, you can only reply <yes> or <no>, lower case, without punctuation. The user could talk in italian or english or german"""'], {}), "(\n    'the user have been asked if something is correct,< {query}> is the reply, you have to tell me if the user is confirming, you can only reply <yes> or <no>, lower case, without punctuation. The user could talk in italian or english or german'\n    )\n", (2802, 3055), False, 'from langchain.prompts import PromptTemplate\n'), ((3337, 3470), 'langchain.prompts.PromptTemplate.from_template', 'PromptTemplate.from_template', (['"""how many passengers? reply with json format with field named \'passengers\' type int: {query}"""'], {}), '(\n    "how many passengers? reply with json format with field named \'passengers\' type int: {query}"\n    )\n', (3365, 3470), False, 'from langchain.prompts import PromptTemplate\n'), ((5125, 5166), 'requests.post', 'requests.post', (['url_route'], {'json': 'data_route'}), '(url_route, json=data_route)\n', (5138, 5166), False, 'import requests\n'), ((5715, 5935), 'langchain.prompts.PromptTemplate.from_template', 'PromptTemplate.from_template', (['"""you are the taxidriver assistant, summarize the following trip in a short and syntetic message and ask to confirm, the trip, write it in the following language{language}: {query}"""'], {}), "(\n    'you are the taxidriver assistant, summarize the following trip in a short and syntetic message and ask to confirm, the trip, write it in the following language{language}: {query}'\n    )\n", (5743, 5935), False, 'from langchain.prompts import PromptTemplate\n'), ((2490, 2530), 'langid.set_languages', 'langid.set_languages', (["['en', 'it', 'de']"], {}), "(['en', 'it', 'de'])\n", (2510, 2530), False, 'import langid\n'), ((2591, 2618), 'langid.classify', 'langid.classify', (['transcript'], {}), '(transcript)\n', (2606, 2618), False, 'import langid\n'), ((3535, 3560), 'json.loads', 'json.loads', (['reply.content'], {}), '(reply.content)\n', (3545, 3560), False, 'import json\n'), ((4027, 4087), 'requests.post', 'requests.post', (['url'], {'json': 'data_autocomplete_start', 'timeout': '(30)'}), '(url, json=data_autocomplete_start, timeout=30)\n', (4040, 4087), False, 'import requests\n'), ((4340, 4386), 'requests.post', 'requests.post', (['url'], {'json': 'data_autocomplete_end'}), '(url, json=data_autocomplete_end)\n', (4353, 4386), False, 'import requests\n'), ((2273, 2296), 'datetime.datetime.now', 'datetime.datetime.now', ([], {}), '()\n', (2294, 2296), False, 'import datetime\n'), ((2401, 2424), 'datetime.datetime.now', 'datetime.datetime.now', ([], {}), '()\n', (2422, 2424), False, 'import datetime\n')]