import asyncio
import os
import pandas as pd
from belief import Belief
from ring import Ring

class RingExperiment:
    debug = True
    def __init__(self, models: list[str], player_id: int, version: str, temperature: float, iterations: int, output_file: str):
        self.models = models
        self.player_id = player_id
        self.version = version
        self.temperature = temperature
        self.iterations = iterations
        self.output_file = output_file  # Path to the CSV output file

    # Helper function to escape double quotes in the motivations string
    def protect_reasoning(self, reasoning):
        if reasoning:
            # Échapper les guillemets doubles dans motivations en doublant les guillemets
            return f'"{reasoning.replace("\"", "\"\"")}"'
        return reasoning

    async def run_experiment(self):
        beliefs = [Belief.GIVEN, Belief.EXPLICIT, Belief.IMPLICIT]
        file_exists = os.path.isfile(self.output_file)  # Check if file already exists
        # Run the dictator game for each model and preference
        for model in self.models:
            if self.debug:
                print(f"Running experiment for model: {model}")
            for belief in beliefs:
                print(f"Running with belief: {belief.name}")
                for iteration in range(1, self.iterations + 1):
                    print(f"Iteration: {iteration}")
                    # Initialize the Ring player for the current iteration
                    game_agent = Ring(
                        player_id=self.player_id,
                        belief=belief,
                        swap=True,
                        version=self.version,  # Corrected placement
                        model=model,
                        temperature=self.temperature
                    ) if iteration % 2 == 0 else Ring(
                        player_id=self.player_id,
                        belief=belief,
                        swap=False,
                        version=self.version,  # Corrected placement
                        model=model,
                        temperature=self.temperature
                    )
                    try:
                        agent_response = await game_agent.run()
                        action = agent_response['action']
                        rationality = agent_response['rationality']
                        reasoning = agent_response['reasoning']
                        # Protect the reasoning string by escaping double quotes
                        reasoning = self.protect_reasoning(reasoning)

                    except Exception as e:
                        print(f"Error in iteration {iteration} for model {model} : {e}")
                        action, reasoning, rationality = None, None, None

                    # Create a single-row DataFrame for the current result
                    df = pd.DataFrame([{
                        'Iteration': iteration,
                        'Model': model,
                        'Temperature': self.temperature,
                        'Belief': belief.label,
                        'action': action,
                        'rationality': rationality,
                        'reasoning': reasoning
                    }])
                    # Append results to the CSV file
                    df.to_csv(self.output_file, mode='a', header=not file_exists, index=False)
                    file_exists = True  # Ensure header is only written once


# Running the experiment
if __name__ == "__main__":
    models = ["llama3.3:latest", "deepseek-r1:7b", "mixtral:8x7b"] # "gpt-4.5-preview-2025-02-27", "llama3", "mistral-small", "deepseek-r1"
    temperature = 0.7
    iterations = 30
    player_id = 1
    version = "d"
    output_file = f"../../data/ring/ring.{player_id}.{version}.csv"
    experiment = RingExperiment(models=models, player_id = player_id, version = version, temperature = temperature, iterations=iterations, output_file = output_file)
    asyncio.run(experiment.run_experiment())
    print(f"Experiment results saved to {output_file}")