import requests
import pandas as pd
import io
from transformers import AutoModelForCausalLM, AutoTokenizer
import torchaudio
from transformers import Wav2Vec2ForCTC, Wav2Vec2Tokenizer
from gtts import gTTS
import tempfile
import torch
import gradio as gr

# Device configuration
device = torch.device("cuda" if torch.cuda.is_available() else "cpu")

# Load conversational language model
language_model_name = "microsoft/DialoGPT-medium"  # Use a suitable model
tokenizer = AutoTokenizer.from_pretrained(language_model_name)
language_model = AutoModelForCausalLM.from_pretrained(language_model_name).to(device)

# Load Speech-to-Text (Wav2Vec2) model
stt_model_name = "facebook/wav2vec2-base-960h"
stt_tokenizer = Wav2Vec2Tokenizer.from_pretrained(stt_model_name)
stt_model = Wav2Vec2ForCTC.from_pretrained(stt_model_name).to(device)

# URL of the GitHub raw CSV file
CSV_URL = "https://raw.githubusercontent.com/your-username/your-repo/main/medical_advice.csv"

def load_medical_advice():
    try:
        response = requests.get(CSV_URL)
        response.raise_for_status()  # Ensure the request was successful
        csv_data = response.content.decode('utf-8')
        advice_df = pd.read_csv(io.StringIO(csv_data))
        return pd.Series(advice_df.advice.values, index=advice_df.symptom).to_dict()
    except requests.exceptions.RequestException as e:
        print(f"Error loading medical advice: {e}")
        return {}

# Load the advice dictionary
medical_advice_data = load_medical_advice()

def transcribe_audio(audio_path):
    # Existing transcription code...
    waveform, sample_rate = torchaudio.load(audio_path)
    if sample_rate != 16000:
        resampler = torchaudio.transforms.Resample(orig_freq=sample_rate, new_freq=16000)
        waveform = resampler(waveform)
    input_values = stt_tokenizer(waveform.squeeze().numpy(), return_tensors="pt", sampling_rate=16000).input_values.to(device)

    with torch.no_grad():
        logits = stt_model(input_values).logits
    predicted_ids = torch.argmax(logits, dim=-1)
    return stt_tokenizer.batch_decode(predicted_ids)[0].lower()

def get_medical_advice(user_input):
    for key in medical_advice_data:
        if key in user_input:
            return medical_advice_data[key]
    return "I'm sorry, I don't have specific advice on that. Please consult a healthcare professional."

def get_bot_response(user_input):
    global chat_history_ids
    new_user_input_ids = tokenizer.encode(user_input + tokenizer.eos_token, return_tensors='pt').to(device)
    if chat_history_ids is not None:
        bot_input_ids = torch.cat([chat_history_ids, new_user_input_ids], dim=-1)
    else:
        bot_input_ids = new_user_input_ids

    chat_history_ids = language_model.generate(
        bot_input_ids, max_length=1000, pad_token_id=tokenizer.eos_token_id, no_repeat_ngram_size=3,
        do_sample=True, top_p=0.95, temperature=0.7
    )

    response = tokenizer.decode(chat_history_ids[:, bot_input_ids.shape[-1]:][0], skip_special_tokens=True)
    return response

def chatbot_interface(audio):
    if audio is None:
        return "Please provide an audio input.", "No response available.", None
    
    try:
        user_input = transcribe_audio(audio)
        if not user_input.strip():
            return "Sorry, I could not understand the audio.", "No response available.", None
    except Exception as e:
        return f"Error in transcription: {str(e)}", "No response available.", None

    try:
        medical_advice = get_medical_advice(user_input)
        bot_response = get_bot_response(user_input)
        combined_response = bot_response + "\n\n" + medical_advice

    except Exception as e:
        combined_response = f"Error in generating response: {str(e)}"

    try:
        audio_file = text_to_speech(combined_response)
    except Exception as e:
        return f"Error in generating speech: {str(e)}", "No response available.", None

    return f"You: {user_input}", combined_response, audio_file

# Same Gradio interface setup...
with gr.Blocks() as demo:
    gr.Markdown("# 🏥 Healthcare AI Chatbot")
    gr.Markdown("**Ask health-related questions. Please consult a professional for medical advice.**")

    with gr.Row():
        audio_input = gr.Audio(type="filepath", label="Your Voice")
        submit_btn = gr.Button("Submit")

    with gr.Row():
        user_text = gr.Textbox(label="You:", interactive=False, lines=2)
        bot_text = gr.Textbox(label="Bot:", interactive=False, lines=5)
    
    with gr.Row():
        bot_audio = gr.Audio(label="Bot's Voice")

    submit_btn.click(
        fn=chatbot_interface,
        inputs=audio_input,
        outputs=[user_text, bot_text, bot_audio]
    )

demo.launch()

Add medical advice data from github raw data