import json_repair
import warnings
from litellm import completion


def get_match_description(match_info):
    source_domain = match_info["source_domain"]
    source_values = []
    if "value_name" in source_domain.columns:
        source_values = source_domain["value_name"].tolist()

    target_domain = match_info["target_domain"]
    target_values = []
    if "value_name" in target_domain.columns:
        target_values = target_domain["value_name"].tolist()

    description = (
        f"Source column: {match_info['source_column']}, unique values: {source_values}.\n"
        f"Target column: {match_info['target_column']}, unique values: {target_values}.\n"
        f"Similarity score: {match_info['similarity']}"
    )

    return description


def evaluate_match(
    match_info, model_name="openai/gpt-4o-mini", verbose=False, **model_kwargs
):
    match_description = get_match_description(match_info)

    response = completion(
        model=model_name,
        messages=[
            {
                "role": "system",
                "content": (
                    "Your task is to evaluate the quality of matches between columns from a source and a target dataset. "
                    "These matches are generated by an automated method and may be correct or incorrect. "
                    "You will be provided with the following information: column names, a similarity score, unique values for the columns (if available), "
                    "the list of values in the source and target may differ in length or spelling."
                    "Evaluate the match critically, ensuring your evaluation is consistent with the provided details. "
                    "Your output must strictly follow this format: a Python dictionary containing exactly two fields: "
                    "'response': Choose one of the following values to evaluate the match: 'accept', 'need review', or 'reject'. "
                    "'explanation': Provide a concise and clear justification for your decision, ensuring it directly references the similarity score, column names, "
                    "unique values, and the method's logic (if available). "
                    "Double-check that your explanation aligns with the 'response' you provide. "
                    "Return only the Python dictionary as output with no additional text or formatting. "
                    "Do not include quotation marks in the dictionary keys or values."
                ),
            },
            {
                "role": "user",
                "content": f"These are the details of the match: {match_description}",
            },
        ],
        **model_kwargs,
    )

    response_message = response.choices[0].message.content
    try:
        response_dict = json_repair.loads(response_message)
        decision_class = response_dict["response"]
        decision_explanation = response_dict["explanation"]
        return decision_class, decision_explanation
    except:
        if verbose:
            warnings.warn(
                f"Failed to parse response: {response_message}. ",
                UserWarning,
            )

        return {"response": "unknown", "explanation": "unknown"}
