package com.example.boidelov3;

import android.content.Context;
import android.content.Intent;
import android.content.SharedPreferences;
import android.os.Build;
import android.os.Bundle;
import android.text.Editable;
import android.text.TextWatcher;
import android.view.View;
import android.widget.AdapterView;
import android.widget.ArrayAdapter;
import android.widget.AutoCompleteTextView;
import android.widget.Button;
import android.widget.CompoundButton;

import com.google.android.material.switchmaterial.SwitchMaterial;
import android.widget.EditText;
import android.widget.SeekBar;
import android.widget.TextView;
import android.widget.Toast;

import androidx.annotation.NonNull;
import androidx.appcompat.app.AppCompatActivity;

import com.example.boidelov3.utils.ErrorHandler;

import java.io.IOException;
import java.util.ArrayList;
import java.util.List;

import okhttp3.Call;
import okhttp3.Callback;
import okhttp3.OkHttpClient;
import okhttp3.Request;
import okhttp3.Response;

public class JeuxParametres extends AppCompatActivity {

    private SeekBar seekBar1, seekBar2, seekBar3, seekBarDuration;
    private TextView textView1, textView2, textView5, textViewRatioGen, questionCountValue, gorgeesValue, durationValue;
    private SwitchMaterial checkBoxGPT;
    private Button buttonTestApi;
    private EditText editText, editTextKeyGPT;
    private AutoCompleteTextView autoCompleteProvider;
    private String keyGPT;
    private OpenAIService.AIProvider selectedProvider = OpenAIService.AIProvider.OPENAI;
    private int nbQuestions;

    private List<String> toutlesjoueurs;


    @Override
    protected void onCreate(Bundle savedInstanceState) {
        toutlesjoueurs = getIntent().getStringArrayListExtra("EXTRA_LIST_JOUEUR");
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_jeux_parametres);

        // Initialisation des vues
        seekBar1 = findViewById(R.id.seekBar1);
        seekBar2 = findViewById(R.id.seekBar2);
        seekBar3 = findViewById(R.id.seekBar3);
        seekBarDuration = findViewById(R.id.seekBarDuration);
        textView1 = findViewById(R.id.textView1);
        textView2 = findViewById(R.id.textView2);
        textView5 = findViewById(R.id.textView5);
        editTextKeyGPT = findViewById(R.id.editTextGPT);
        autoCompleteProvider = findViewById(R.id.autoCompleteProvider);
        buttonTestApi = findViewById(R.id.ButtonTestApi);
        textViewRatioGen = findViewById(R.id.textViewRatioGen);
        questionCountValue = findViewById(R.id.questionCountValue);
        gorgeesValue = findViewById(R.id.gorgeesValue);
        durationValue = findViewById(R.id.durationValue);

        // Configuration du dropdown pour le provider IA
        String[] providers = new String[]{
            OpenAIService.AIProvider.OPENAI.getDisplayName(),
            OpenAIService.AIProvider.OPENROUTER.getDisplayName(),
            OpenAIService.AIProvider.ZAI.getDisplayName()
        };
        ArrayAdapter<String> adapter = new ArrayAdapter<>(this, android.R.layout.simple_dropdown_item_1line, providers);
        autoCompleteProvider.setAdapter(adapter);

        // Charger le provider sauvegardé
        SharedPreferences providerPrefs = getSharedPreferences("MyPrefs", MODE_PRIVATE);
        String savedProvider = providerPrefs.getString("aiProvider", OpenAIService.AIProvider.OPENAI.getDisplayName());
        autoCompleteProvider.setText(savedProvider, false);

        // Définir le provider sélectionné
        if (savedProvider.equals(OpenAIService.AIProvider.OPENROUTER.getDisplayName())) {
            selectedProvider = OpenAIService.AIProvider.OPENROUTER;
        } else if (savedProvider.equals(OpenAIService.AIProvider.ZAI.getDisplayName())) {
            selectedProvider = OpenAIService.AIProvider.ZAI;
        } else {
            selectedProvider = OpenAIService.AIProvider.OPENAI;
        }

        // Listener pour le changement de provider
        autoCompleteProvider.setOnItemClickListener(new AdapterView.OnItemClickListener() {
            @Override
            public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
                String selected = (String) parent.getItemAtPosition(position);
                SharedPreferences.Editor editor = providerPrefs.edit();
                editor.putString("aiProvider", selected);
                editor.apply();

                if (selected.equals(OpenAIService.AIProvider.OPENROUTER.getDisplayName())) {
                    selectedProvider = OpenAIService.AIProvider.OPENROUTER;
                } else if (selected.equals(OpenAIService.AIProvider.ZAI.getDisplayName())) {
                    selectedProvider = OpenAIService.AIProvider.ZAI;
                } else {
                    selectedProvider = OpenAIService.AIProvider.OPENAI;
                }
            }
        });

        // Initialiser les TextView avec les valeurs par défaut
        int initialQuestions = 50;
        int initialGorgees = 0;
        int initialRatio = 8;
        int initialDuration = 0;  // 0 pour avoir 4-10 tours par défaut (MIN_DEFI_ROUNDS=4)

        questionCountValue.setText(String.valueOf(initialQuestions));
        gorgeesValue.setText(String.valueOf(initialGorgees));
        durationValue.setText("0"); // Afficher 0 par défaut pour avoir 4-10 tours
        textView5.setText("Palier : Grosse merde");
        textViewRatioGen.setText("Ratio BDD/OPENAI : 1/" + initialRatio);

        // Configuration de la seekBar1
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
            seekBar1.setMin(20);
        }
        seekBar1.setMax(150);
        seekBar1.setProgress(50);

        // Configuration de la seekBar2
        seekBar2.setMax(20);
        seekBar2.setProgress(0);

        // Configuration de la seekBar3
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
            seekBar2.setMin(0);
            seekBar3.setMin(1);
        }
        seekBar3.setMax(15);
        seekBar3.setProgress(8);

        // Configuration de la seekBarDuration (permet valeurs négatives pour offset)
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
            seekBarDuration.setMin(-5); // Permet un offset négatif jusqu'à -5
        }
        seekBarDuration.setMax(15);
        seekBarDuration.setProgress(0); // Valeur par défaut à 0 pour avoir 4-10 tours (MIN_DEFI_ROUNDS=4)

        // Configuration des listeners pour les seekBars
        seekBar1.setOnSeekBarChangeListener(new SeekBar.OnSeekBarChangeListener() {
            @Override
            public void onProgressChanged(SeekBar seekBar, int progress, boolean fromUser) {
                // Ajustement de la valeur au multiple de 10 le plus proche
                int adjustedProgress = Math.round(progress / 10) * 10;
                seekBar.setProgress(adjustedProgress);
                questionCountValue.setText(String.valueOf(adjustedProgress));
            }

            @Override
            public void onStartTrackingTouch(SeekBar seekBar) {
            }

            @Override
            public void onStopTrackingTouch(SeekBar seekBar) {
            }
        });

        seekBar2.setOnSeekBarChangeListener(new SeekBar.OnSeekBarChangeListener() {
            @Override
            public void onProgressChanged(SeekBar seekBar, int progress, boolean fromUser) {
                // Mise à jour du gorgeesValue en fonction de la valeur de la seekBar2
                gorgeesValue.setText(String.valueOf(progress));
                // Mise à jour du textView5 en fonction de la valeur de la seekBar2
                switch (progress) {
                    case 0:
                        textView5.setText("Palier : Grosse merde");
                        break;
                    case 2:
                        textView5.setText("Palier : Petite merde");
                        break;
                    case 4:
                        textView5.setText("Palier : Petit joueur");
                        break;
                    case 6:
                        textView5.setText("Palier : Un p'tit verre ?!");
                        break;
                    case 8:
                        textView5.setText("Palier : ça commence à aller");
                        break;
                    case 10:
                        textView5.setText("Palier : Alcoolique");
                        break;
                    case 12:
                        textView5.setText("Palier : COMA ETHYLIX");
                        break;
                    case 13:
                        textView5.setText("Palier : APÉROOOOO !!");
                        break;
                    case 14:
                        textView5.setText("Palier : LA J'SUIS BIENG");
                        break;
                    case 15:
                        textView5.setText("Palier : J'VOIS PLUS RIENG");
                        break;
                    case 17:
                        textView5.setText("Palier : J'AI PLUS DE VERRES");
                        break;
                    case 18 :
                        textView5.setText("Palier : Soirée Murge");
                        break;
                    case 19:
                        textView5.setText("Palier : Soirée Pétée");
                        break;
                    case 20:
                        textView5.setText("Palier : L'ENDER DRAGON");
                        break;
                }
            }

            @Override
            public void onStartTrackingTouch(SeekBar seekBar) {
            }

            @Override
            public void onStopTrackingTouch(SeekBar seekBar) {
            }
        });

        // Configuration du checkBox // Q : IL sert à quoi ?
        // R : Il sert à activer/désactiver les vues en dessous

        Button buttonTestApi = findViewById(R.id.ButtonTestApi);

        checkBoxGPT = findViewById(R.id.checkBoxGPT);
        checkBoxGPT.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() {
            @Override
            public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
                // Activation/désactivation des vues en fonction de l'état du checkBox
                autoCompleteProvider.setEnabled(isChecked);
                // Pour le champ API key : on garde le layout activé pour le toggle password,
                // mais on désactive l'édition du texte
                editTextKeyGPT.setFocusable(isChecked);
                editTextKeyGPT.setFocusableInTouchMode(isChecked);
                editTextKeyGPT.setClickable(isChecked);
                editTextKeyGPT.setCursorVisible(isChecked);
                if (!isChecked) {
                    editTextKeyGPT.clearFocus();
                }
                textViewRatioGen.setEnabled(isChecked);
                seekBar3.setEnabled(isChecked);
                buttonTestApi.setEnabled(isChecked);
            }
        });

        // Configuration de la seekBar3
        seekBar3.setOnSeekBarChangeListener(new SeekBar.OnSeekBarChangeListener() {
            @Override
            public void onProgressChanged(SeekBar seekBar3, int progress, boolean fromUser) {
                textViewRatioGen.setText("Ratio BDD/OPENAI : 1/" + progress);
            }

            @Override
            public void onStartTrackingTouch(SeekBar seekBar3) {
            }

            @Override
            public void onStopTrackingTouch(SeekBar seekBar3) {
            }
        });

        // Configuration de la seekBarDuration
        seekBarDuration.setOnSeekBarChangeListener(new SeekBar.OnSeekBarChangeListener() {
            @Override
            public void onProgressChanged(SeekBar seekBar, int progress, boolean fromUser) {
                // Afficher avec signe +/- pour bien voir l'offset, mais sans signe pour 0
                String displayValue;
                if (progress > 0) {
                    displayValue = "+" + progress;
                } else {
                    displayValue = String.valueOf(progress); // Affiche "0" ou "-X"
                }
                durationValue.setText(displayValue);
            }

            @Override
            public void onStartTrackingTouch(SeekBar seekBar) {
            }

            @Override
            public void onStopTrackingTouch(SeekBar seekBar) {
            }
        });

        // Partie OpenAI : enregistrement de la clé en dur.
        // Récupérer une instance des SharedPreferences
        SharedPreferences sharedPreferences = getSharedPreferences("MyPrefs", MODE_PRIVATE);
        final SharedPreferences.Editor editor = sharedPreferences.edit();
        // Récupérer l'EditText
        final EditText editText = findViewById(R.id.editTextGPT);
        // Récupérer la valeur enregistrée dans les SharedPreferences
        String apiKey = editText.getText().toString();

        // Récupérer la valeur enregistrée dans les SharedPreferences
        String savedText = sharedPreferences.getString("savedText", "");
        editText.setText(savedText);

        // Enregistrer le contenu de l'EditText lorsque l'utilisateur modifie le texte
        editText.addTextChangedListener(new TextWatcher() {
            @Override
            public void beforeTextChanged(CharSequence s, int start, int count, int after) {
            }

            @Override
            public void onTextChanged(CharSequence s, int start, int before, int count) {
            }

            @Override
            public void afterTextChanged(Editable s) {
                // Enregistrer le texte dans les SharedPreferences
                editor.putString("savedText", editText.getText().toString());
                editor.apply();
            }
        });
    }

    public void onClickButtonTestAPI(View view) {
        String apiKey = editTextKeyGPT.getText().toString();

        if (apiKey == null || apiKey.isEmpty()) {
            Toast.makeText(this, "Veuillez entrer une clé API", Toast.LENGTH_SHORT).show();
            return;
        }

        // Créer un client OkHttpClient pour effectuer la requête
        OkHttpClient client = new OkHttpClient.Builder()
                .connectTimeout(10, java.util.concurrent.TimeUnit.SECONDS)
                .readTimeout(10, java.util.concurrent.TimeUnit.SECONDS)
                .build();

        // Déterminer l'URL, le modèle et le format selon le provider sélectionné
        String testUrl;
        String testModel;
        String jsonBody;
        boolean isAnthropicFormat = (selectedProvider == OpenAIService.AIProvider.ZAI);

        switch (selectedProvider) {
            case OPENROUTER:
                testUrl = "https://openrouter.ai/api/v1/chat/completions";
                testModel = "openai/gpt-3.5-turbo";
                // Format OpenAI
                jsonBody = "{\"model\":\"" + testModel + "\",\"messages\":[{\"role\":\"user\",\"content\":\"Test\"}],\"max_tokens\":5}";
                break;
            case ZAI:
                testUrl = "https://api.z.ai/v1/messages";
                testModel = "claude-3-5-sonnet";
                // Format Anthropic
                jsonBody = "{\"model\":\"" + testModel + "\",\"messages\":[{\"role\":\"user\",\"content\":\"Test\"}],\"max_tokens\":5}";
                break;
            case OPENAI:
            default:
                testUrl = "https://api.openai.com/v1/chat/completions";
                testModel = "gpt-3.5-turbo";
                jsonBody = "{\"model\":\"" + testModel + "\",\"messages\":[{\"role\":\"user\",\"content\":\"Test\"}],\"max_tokens\":5}";
                break;
        }

        // Construire la requête
        Request.Builder requestBuilder = new Request.Builder()
                .url(testUrl)
                .addHeader("Content-Type", "application/json");

        // Ajouter les headers selon le provider
        switch (selectedProvider) {
            case OPENAI:
            case OPENROUTER:
                requestBuilder.addHeader("Authorization", "Bearer " + apiKey);
                break;
            case ZAI:
                requestBuilder.addHeader("x-api-key", apiKey);
                requestBuilder.addHeader("anthropic-version", "2023-06-01");
                break;
        }

        // Headers spécifiques pour OpenRouter
        if (selectedProvider == OpenAIService.AIProvider.OPENROUTER) {
            requestBuilder.addHeader("HTTP-Referer", "https://boidelo.app");
            requestBuilder.addHeader("X-Title", "Boidelo");
        }

        Request request = requestBuilder
                .post(okhttp3.RequestBody.create(jsonBody, okhttp3.MediaType.get("application/json")))
                .build();

        // Exécuter la requête de test
        client.newCall(request).enqueue(new Callback() {
            @Override
            public void onFailure(@NonNull Call call, IOException e) {
                String operation = "Test de connexion API " + selectedProvider.getDisplayName();
                String details = "Échec de connexion lors du test de l'API";
                ErrorHandler.logErrorOnly("JeuxParametres", operation + " - " + details, e);
                runOnUiThread(() -> {
                    String userMessage = "Échec de connexion " + selectedProvider.getDisplayName() + " : " + e.getMessage();
                    Toast.makeText(getApplicationContext(), userMessage, Toast.LENGTH_SHORT).show();
                });
            }

            @Override
            public void onResponse(Call call, Response response) throws IOException {
                if (response.isSuccessful()) {
                    runOnUiThread(() -> {
                        Toast.makeText(getApplicationContext(),
                                "Connexion " + selectedProvider.getDisplayName() + " réussie !",
                                Toast.LENGTH_SHORT).show();
                    });
                } else {
                    runOnUiThread(() -> {
                        Toast.makeText(getApplicationContext(),
                                "Erreur " + selectedProvider.getDisplayName() + " (HTTP " + response.code() + ")",
                                Toast.LENGTH_SHORT).show();
                    });
                }
                response.close();
            }
        });
    }

    public void onClickButtonStart(View view) {
        // Récupérer les paramètres de la partie
        int nombreQuestions = seekBar1.getProgress();
        int ajoutGorgees = seekBar2.getProgress();
        int ratioBddOpenAI = seekBar3.getProgress();
        int durationDefis = seekBarDuration.getProgress();
        boolean openAI = checkBoxGPT.isChecked();

        toutlesjoueurs = getIntent().getStringArrayListExtra("EXTRA_LIST_JOUEUR");
        // Récupérer les joueurs (vous devrez définir comment vous les récupérez)
        SharedPreferences sharedPreferences = getSharedPreferences("Joueurs", Context.MODE_PRIVATE);
        ArrayList<String> joueurs = new ArrayList<>();

        for (int i = 1; i <= 3; i++) {
            String joueur = sharedPreferences.getString("J" + i, "");
            if (!joueur.isEmpty()) {
                joueurs.add(joueur);
            }
        }

        // Récupérer les joueurs supplémentaires en utilisant une boucle
        int i = 4;
        String nomJoueur = sharedPreferences.getString("J" + i, "");
        while (!nomJoueur.isEmpty()) {
            joueurs.add(nomJoueur);
            i++;
            nomJoueur = sharedPreferences.getString("J" + i, "");
        }

        // Créer une instance de la classe Jeux avec les paramètres récupérés
        Jeux jeux = new Jeux();

        // Lancer l'activité Jeux avec les paramètres
        Intent intent = new Intent(this, Jeux.class);
        intent.putExtra("EXTRA_NOMBRE_QUESTIONS", nombreQuestions);
        intent.putExtra("EXTRA_AJOUT_GORGEE", ajoutGorgees);
        intent.putExtra("EXTRA_RATIO_OPENAI", ratioBddOpenAI);
        intent.putExtra("EXTRA_DURATION_DEFIS", durationDefis);
        intent.putExtra("EXTRA_OPENAI", openAI);
        final EditText editText = findViewById(R.id.editTextGPT);
        intent.putExtra("EXTRA_KEY_OPENAI", editText.getText().toString());
        intent.putExtra("EXTRA_AI_PROVIDER", selectedProvider.name());

        toutlesjoueurs = getIntent().getStringArrayListExtra("EXTRA_LIST_JOUEUR");
        intent.putStringArrayListExtra("EXTRA_LIST_JOUEUR", (ArrayList<String>) toutlesjoueurs);
        startActivity(intent);
    }
}