using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;

public class GameManager : MonoBehaviour
{
    [Header("Cartes sur la scène")]
    [SerializeField] private List<Carte> _cartes; // Liste des cartes sur la scène

    [Header("Sprites des cartes")]
    [SerializeField] private List<Sprite> _spritesFaces; // Sprites des faces des cartes
    [SerializeField] private List<Sprite> _spritesSurbrillance; // Sprites de surbrillance des cartes
    [SerializeField] private Sprite _spriteDos; // Sprite du dos des cartes

    [Header("Champ de texte pour les affichages")]
    [SerializeField] private Text _infos; // Champ de texte pour afficher les informations du jeu

    [Header("Sons")]
    [SerializeField] private AudioClip _sonRevelerCarte; // Son lorsqu'une carte est retournée
    [SerializeField] private AudioClip _sonIdentiques; // Son lorsqu'on trouve deux cartes identiques
    [SerializeField] private AudioClip _sonDifferentes; // Son lorsqu'on trouve deux cartes différentes
    [SerializeField] private AudioClip _sonFin; // Son de fin de partie
    [SerializeField] private AudioClip _sonMelange; // Son de mélange des cartes

    private AudioSource _audio; // Composant audio du GameManager

    private bool _peutJouer; // Indique si le joueur peut jouer
    private Carte _premiereCarte; // Première carte retournée
    private Carte _deuxiemeCarte; // Deuxième carte retournée

    private int _coups; // Nombre total de coups joués
    private int _bonsCoups; // Nombre de paires de cartes identiques trouvées

    void Awake()
    {
        _audio = GetComponent<AudioSource>(); // Initialisation du composant audio
    }

    void Start()
    {
        Commencer(); // Début de la partie
    }

    public void Commencer()
    {
        JouerSon(_sonMelange); // Joue le son de mélange des cartes

        _coups = 0; // Réinitialisation du nombre de coups
        _bonsCoups = 0; // Réinitialisation du nombre de paires trouvées

        List<int> _ordre = new List<int>() { 0, 0, 1, 1, 2, 2, 3, 3, 4, 4, 5, 5 }; // Liste pour mélanger les cartes

        for (int i = 0; i < _cartes.Count; i++)
        {
            int pos = Random.Range(0, _ordre.Count); // Choix aléatoire de position dans la liste
            int valeur = _ordre[pos]; // Récupération de la valeur à cette position
            _cartes[i].Set(_spriteDos, _spritesFaces[valeur], _spritesSurbrillance[valeur]); // Initialisation des sprites de la carte
            _cartes[i].Dos(); // Affichage du dos de la carte
            _ordre.RemoveAt(pos); // Retrait de la valeur de la liste d'ordre pour éviter les répétitions
        }

        _peutJouer = true; // Le joueur peut jouer (il peut cliquer sur les cartes)

        Afficher("Bonne chance!"); // message de départ
    }

    public void Jouer(Carte carte)
    {
        // Si on ne peut pas jouer ou si la carte n'est pas cliquable, quitte la fonction
        if (_peutJouer == false || carte.EstCliquable() == false) return;

        // Si on vient de réléver la première carte d'une paire
        if (_premiereCarte == null)
        {
            _premiereCarte = carte;
            carte.Face();
            JouerSon(_sonRevelerCarte); // Son de révélation de carte
        }
        else
        {
            _coups++; // Incrémente le nombre total de coups
            AfficherCoups(); // Affiche le nombre de coups

            _deuxiemeCarte = carte;
            _deuxiemeCarte.Face();

            // Si les 2 cartes révélées sont identiques...
            if (_premiereCarte.SpriteCourant() == _deuxiemeCarte.SpriteCourant())
            {
                // Affiche les 2 cartes en surbrillance (hilite)
                _premiereCarte.Hilite();
                _deuxiemeCarte.Hilite();

                // "oublie" les 2 cartes jouées
                _premiereCarte = null;
                _deuxiemeCarte = null;

                _bonsCoups++; // Incrémente le nombre de paires trouvées

                VerifierSiFini(); // Vérifie si la partie est terminée
            }
            else // si elles sont différentes...
            {
                Invoke("MontrerDos", 1f); // Retourne les cartes après un court délai
                _peutJouer = false; // Temporairement, on ne peut plus jouer

                JouerSon(_sonRevelerCarte); // Son de révélation de carte
            }
        }
    }

    private void VerifierSiFini()
    {
        if (_bonsCoups == 6) // Si toutes les paires ont été trouvées
        {
            // Affiche le nombre de coups joués
            Afficher($"Partie terminée\nRéussite en {_coups} coups."); 

            JouerSon(_sonFin); // son de fin de partie
        }
        else
        {
            JouerSon(_sonIdentiques); // son de paires identiques trouvées
        }
    }

    private void AfficherCoups()
    {
        string s = "";
        if (_coups > 1) s = "s";
        Afficher($"{_coups} coup{s}."); // Affiche le nombre de coups joués
    }

    private void MontrerDos()
    {
        // Affiche le dos des 2 cartes
        _premiereCarte.Dos();
        _deuxiemeCarte.Dos();

        // "oublie" les 2 cartes jouées
        _premiereCarte = null;
        _deuxiemeCarte = null;

        _peutJouer = true; // Redonne la possibilité de jouer
        JouerSon(_sonDifferentes); // son de cartes différentes
    }

    // Affiche un message dans le champ d'infos
    private void Afficher(string message)
    {
        _infos.text = message; 
    }

    // Raccourci pour jouer un son
    private void JouerSon(AudioClip unSon)
    {
        _audio.PlayOneShot(unSon); 
    }
}
