import os
import json
import time
import pandas as pd
from dotenv import load_dotenv

import sys
sys.path.append(os.path.abspath('.'))
from app.services.chatbot.vector_retriever import VectorRetriever

from langchain_google_genai import ChatGoogleGenerativeAI, GoogleGenerativeAIEmbeddings
from ragas import evaluate, EvaluationDataset
from ragas.metrics import AnswerRelevancy, ContextPrecision, Faithfulness
from ragas.llms import LangchainLLMWrapper
from ragas.embeddings import LangchainEmbeddingsWrapper

load_dotenv(override=True)
os.environ["GOOGLE_API_KEY"] = "AIzaSyAAa4oW7ly9XjBjCkzJjMN3CaXHgDk9jro"

v = VectorRetriever(table_name="document_chunks")
gemini_llm = ChatGoogleGenerativeAI(model="gemini-2.5-flash", temperature=0.0)
eval_llm = LangchainLLMWrapper(gemini_llm)
gemini_emb = GoogleGenerativeAIEmbeddings(model="models/embedding-001")
eval_emb = LangchainEmbeddingsWrapper(gemini_emb)
metrics = [Faithfulness(llm=eval_llm), AnswerRelevancy(llm=eval_llm, embeddings=eval_emb), ContextPrecision(llm=eval_llm)]

raw_data = json.load(open('data/eval_dataset.json', 'r'))
out_csv = 'results/evaluation_results_system_b_final.csv'

df = pd.DataFrame(columns=['user_input', 'retrieved_contexts', 'response', 'reference', 'faithfulness', 'answer_relevancy', 'context_precision'])

for i, item in enumerate(raw_data):
    print(f"Memproses Soal {i+1}/{len(raw_data)}: {item['query']}")
    
    # Vector Search
    chunks = v.similarity_search_by_hash(item['query'], item['active_hash'], top_k=5)
    contexts = [c['content'] for c in chunks]
    if not contexts:
        contexts = ["Tidak ada informasi di database."]
        
    # Generate Answer
    prompt = f"Gunakan HANYA konteks berikut untuk menjawab pertanyaan.\nKonteks:\n{chr(10).join(contexts)}\n\nPertanyaan: {item['query']}"
    
    try:
        ans = gemini_llm.invoke(prompt).content
    except Exception as e:
        ans = "Gagal memproses."
        print(f"LLM Error: {e}")
        time.sleep(10)
        
    sample = [{
        "user_input": item['query'],
        "retrieved_contexts": contexts,
        "response": ans,
        "reference": item['ground_truth'] or "N/A"
    }]
    
    # Ragas Evaluate
    try:
        res = evaluate(dataset=EvaluationDataset.from_list(sample), metrics=metrics, llm=eval_llm, embeddings=eval_emb, show_progress=False)
        f_score = res['faithfulness']
        ar_score = res['answer_relevancy']
        cp_score = res['context_precision']
    except Exception as e:
        print(f"Ragas Error: {e}")
        f_score, ar_score, cp_score = 0.0, 0.0, 0.0
        
    df.loc[i] = [item['query'], str(contexts), ans, item['ground_truth'], f_score, ar_score, cp_score]
    df.to_csv(out_csv, index=False)
    
    print(f"Selesai Soal {i+1}. Tidur 20 detik untuk menghindari limit Google...")
    time.sleep(20)

print("EVALUASI SELESAI!")
