package fr.univ.dblp.simulation;

import java.io.BufferedWriter;
import java.io.FileWriter;
import java.io.IOException;
import java.util.List;
import java.util.Locale;

/**
 * Classe utilitaire pour exporter les résultats de simulation au format gnuplot.
 */
public class SimulationExporter {

    /**
     * Exporte l'évolution temporelle d'une simulation unique
     *
     * @param result Résultat de la simulation
     * @param filePath Chemin du fichier de sortie
     */
    public static void exportSimulationResult(SimulationResult result, String filePath) throws IOException {
        try (BufferedWriter writer = new BufferedWriter(new FileWriter(filePath))) {
            // En-tête
            writer.write("# Evolution temporelle - " + result.getScenario() + "\n");
            writer.write("# day susceptible infected immune fraction_infected\n");

            List<Integer> susceptible = result.getSusceptibleOverTime();
            List<Integer> infected = result.getInfectedOverTime();
            List<Integer> immune = result.getImmuneCount();
            List<Double> fractions = result.getInfectedFractionOverTime();

            // Données jour par jour
            for (int day = 0; day < susceptible.size(); day++) {
                writer.write(String.format(Locale.US, "%d %d %d %d %.6f\n",
                    day,
                    susceptible.get(day),
                    infected.get(day),
                    immune.get(day),
                    fractions.get(day)
                ));
            }
        }
    }

    /**
     * Exporte la comparaison de plusieurs scénarios (fraction d'infectés uniquement)
     *
     * @param results Liste des résultats à comparer
     * @param filePath Chemin du fichier de sortie
     */
    public static void exportScenarioComparison(List<SimulationResult> results, String filePath) throws IOException {
        if (results.isEmpty()) {
            return;
        }

        try (BufferedWriter writer = new BufferedWriter(new FileWriter(filePath))) {
            // En-tête
            writer.write("# Comparaison des scénarios - Fraction d'infectés\n");
            writer.write("# day");
            for (SimulationResult result : results) {
                writer.write(" " + result.getScenario().replace(" ", "_"));
            }
            writer.write("\n");

            // Données jour par jour
            int maxDays = results.get(0).getSimulationDays();
            for (int day = 0; day <= maxDays; day++) {
                writer.write(String.valueOf(day));
                for (SimulationResult result : results) {
                    List<Double> fractions = result.getInfectedFractionOverTime();
                    writer.write(String.format(Locale.US, " %.6f", fractions.get(day)));
                }
                writer.write("\n");
            }
        }
    }

    /**
     * Exporte la comparaison de plusieurs réseaux avec le même scénario
     *
     * @param networkNames Noms des réseaux
     * @param results Résultats correspondants
     * @param filePath Chemin du fichier de sortie
     */
    public static void exportNetworkComparison(List<String> networkNames, List<SimulationResult> results, String filePath) throws IOException {
        if (results.isEmpty() || networkNames.size() != results.size()) {
            return;
        }

        try (BufferedWriter writer = new BufferedWriter(new FileWriter(filePath))) {
            // En-tête
            writer.write("# Comparaison des réseaux - Fraction d'infectés\n");
            writer.write("# day");
            for (String networkName : networkNames) {
                writer.write(" " + networkName.replace(" ", "_"));
            }
            writer.write("\n");

            // Données jour par jour
            int maxDays = results.get(0).getSimulationDays();
            for (int day = 0; day <= maxDays; day++) {
                writer.write(String.valueOf(day));
                for (SimulationResult result : results) {
                    List<Double> fractions = result.getInfectedFractionOverTime();
                    writer.write(String.format(Locale.US, " %.6f", fractions.get(day)));
                }
                writer.write("\n");
            }
        }
    }

    /**
     * Exporte un résumé des métriques de plusieurs simulations
     *
     * @param results Liste des résultats
     * @param filePath Chemin du fichier de sortie
     */
    public static void exportSummary(List<SimulationResult> results, String filePath) throws IOException {
        try (BufferedWriter writer = new BufferedWriter(new FileWriter(filePath))) {
            writer.write("# Résumé des simulations\n");
            writer.write("# scenario total_nodes immune peak_infection peak_day final_infected\n");

            for (SimulationResult result : results) {
                int finalInfected = result.getInfectedOverTime().get(result.getSimulationDays());
                writer.write(String.format("%s %d %d %d %d %d\n",
                    result.getScenario().replace(" ", "_"),
                    result.getTotalNodes(),
                    result.getImmuneCount().get(0),
                    result.getPeakInfection(),
                    result.getPeakDay(),
                    finalInfected
                ));
            }
        }
    }
}
