import logging
import os

import re

from .base import Detector


logger = logging.getLogger(__name__)


class GEval(Detector):
    metrics = ['coherence', 'consistency', 'fluency', 'relevance']
    @staticmethod
    def parse_output(output):
        matched = re.search("^ ?([\d\.]+)", output)
        if matched:
            try:
                score = float(matched.group(1))
            except:
                score = 0
        else:
            score = 0
        return score

    @staticmethod
    def normalize_score(score):
        max_score = 5  # Maximum possible score
        normalized_score = score / max_score
        return normalized_score

    def create_prompt(self, answer, summary, metric=os.getenv("GEVAL_METRIC")):
        mapping = {
            "coherence": "coh_detailed.txt",
            "consistency": "con_detailed.txt",
            "fluency": "flu_detailed.txt",
            "relevance": "rel_detailed.txt"
        }
        with open(os.path.dirname(os.path.abspath(__file__)) + f'/../prompts/{mapping[metric]}') as readfile:
            prompt = readfile.read()
        cur_prompt = prompt.replace('{{Document}}', answer).replace('{{Summary}}', summary)
        return cur_prompt

    def score(self, question, answer=None, samples=None):
        scores = {}
        if not answer:
            answer = self.ask_llm(question)[0]
        answer = answer.strip()
        summary_prompt = f"Create a summary with 20 maximum words from {answer}"
        summary = self.ask_llm(summary_prompt)[0].strip()

        for metric in self.metrics:
            prompt = self.create_prompt(answer, summary, metric)
            answers = self.ask_llm(prompt, n=int(os.getenv("GEVAL_SAMPLING_NUMBER", 5)))

            all_scores = [self.parse_output(x.strip()) for x in answers]
            score = sum(all_scores) / len(all_scores)
            scores[metric.title()] = float("{:.2f}".format(self.normalize_score(score)))
        return scores, answer, []
