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

[System.Serializable]
public class EnemyData
{
    public GameObject enemyPrefab;
    public Transform spawnTransform;
    public GameObject imageOnReachPoint;
    public GameObject imageOnDeath;
}

public class dissolvenzaImmagini : MonoBehaviour
{
    // Singleton instance
    public static dissolvenzaImmagini instance;

    [Header("Image Fade Settings")]
    public GameObject[] imageGroups;
    public float fadeDuration = 3f;
    public float displayDuration = 2f;

    [Header("Enemy Spawn Settings")]
    public List<EnemyData> enemiesData;
    public List<int> enemyTriggerIndices;
    public Transform playerTransform;

    private int currentGroupIndex = 0;
    private List<GameObject> currentEnemies = new List<GameObject>();

    [Header("Player and Enemy Settings")]
    public controller playerMovement;
    public Player_combat_Mattina combat;
    public enemySpawner[] enemySpawners;

    void Awake()
    {
        // Imposta l'istanza singleton
        if (instance == null)
        {
            instance = this;
        }
        else
        {
            Destroy(gameObject);
        }
    }

    void Start()
    {
        // Imposta tutte le immagini con alpha 0 all'inizio
        foreach (GameObject group in imageGroups)
        {
            SetGroupAlpha(group, 0f);
        }

        // Disabilita il movimento e il combattimento del player all'inizio
        DisablePlayerAndEnemies();

        // Inizia la sequenza delle dissolvenze delle immagini
        StartCoroutine(ShowImageGroupsInSequence());
    }

    // Metodo per disabilitare movimento e combattimento del player e degli spawners
    void DisablePlayerAndEnemies()
    {
        if (playerMovement != null) playerMovement.enabled = false;
        if (combat != null) combat.enabled = false;

        foreach (enemySpawner spawner in enemySpawners)
        {
            if (spawner != null) spawner.enabled = false;
        }
    }

    // Metodo per abilitare movimento del player e gli spawners
    void EnablePlayerAndEnemies()
    {
        if (playerMovement != null) playerMovement.enabled = true;

        foreach (enemySpawner spawner in enemySpawners)
        {
            if (spawner != null) spawner.enabled = true;
        }
    }

    // Coroutine che gestisce la sequenza di dissolvenza delle immagini
    IEnumerator ShowImageGroupsInSequence()
    {
        while (currentGroupIndex < imageGroups.Length)
        {
            GameObject group = imageGroups[currentGroupIndex];

            yield return StartCoroutine(FadeInGroup(group));
            yield return new WaitForSeconds(displayDuration);
            yield return StartCoroutine(FadeOutGroup(group));

            // Controlla se l'indice corrente è tra quelli che devono generare un enemy
            if (enemyTriggerIndices.Contains(currentGroupIndex))
            {
                yield return SpawnAndHandleEnemies();
            }

            currentGroupIndex++;
        }

        // Alla fine della sequenza, abilita movimento e gli spawners
        EnablePlayerAndEnemies();
    }

    // Coroutine che genera un enemy e attende fino a che viene distrutto
    IEnumerator SpawnAndHandleEnemies()
    {
        int enemyIdx = enemyTriggerIndices.IndexOf(currentGroupIndex);

        if (enemyIdx < enemiesData.Count)
        {
            EnemyData data = enemiesData[enemyIdx];

            // Istanzia l'enemy nel punto di spawn designato
            GameObject enemy = Instantiate(
                data.enemyPrefab,
                data.spawnTransform.position,
                Quaternion.identity
            );
            currentEnemies.Add(enemy);

            // Aggiungi e configura il componente EnemyMovement
            EnemyMovement movement = enemy.AddComponent<EnemyMovement>();
            movement.target = playerTransform;
            movement.stopDistance = 2.0f; // Imposta la distanza di stop desiderata
            movement.playerCombat = combat; // Assegna il riferimento allo script di combattimento del player
            movement.imageFadeController = this; // Assegna il riferimento allo script di dissolvenza
            movement.imageOnReachPoint = data.imageOnReachPoint; // Assegna l'immagine specifica

            // Assicurati che l'enemy abbia un componente Health
            Health health = enemy.GetComponent<Health>();
            if (health == null)
            {
                health = enemy.AddComponent<Health>();
                health.maxHealth = 100; // Configura questo valore secondo necessità
                health.imageFadeController = this; // Assegna il riferimento allo script di dissolvenza
                health.imageOnDeath = data.imageOnDeath; // Assegna l'immagine specifica
            }

            // Abilita eventuali altri componenti necessari
            Player_combat_Mattina enemyCombatComponent = enemy.GetComponent<Player_combat_Mattina>();
            if (enemyCombatComponent != null)
            {
                enemyCombatComponent.enabled = true;
            }
        }

        // Attendi fino a quando tutti gli enemy nella lista sono stati distrutti
        while (currentEnemies.Exists(e => e != null))
        {
            yield return null;
        }
    }

    // Metodo pubblico per mostrare un'immagine con dissolvenza, accessibile dagli altri script
    public IEnumerator ShowImageWithFade(GameObject imageGroup)
    {
        if (imageGroup != null)
        {
            yield return StartCoroutine(FadeInGroup(imageGroup));
            yield return new WaitForSeconds(displayDuration);
            yield return StartCoroutine(FadeOutGroup(imageGroup));
        }
    }

    // Metodo per mostrare le immagini post-arrivo del nemico
    public IEnumerator ShowPostEnemyReachedImages()
    {
        foreach (GameObject image in imagesAfterEnemyReached)
        {
            yield return StartCoroutine(ShowImageWithFade(image));
        }
    }

    // Coroutine per dissolvere in
    public IEnumerator FadeInGroup(GameObject group)
    {
        float elapsedTime = 0f;

        while (elapsedTime < fadeDuration)
        {
            elapsedTime += Time.deltaTime;
            SetGroupAlpha(group, Mathf.Clamp01(elapsedTime / fadeDuration));
            yield return null;
        }

        SetGroupAlpha(group, 1f);
    }

    // Coroutine per dissolvere out
    public IEnumerator FadeOutGroup(GameObject group)
    {
        float elapsedTime = 0f;

        while (elapsedTime < fadeDuration)
        {
            elapsedTime += Time.deltaTime;
            SetGroupAlpha(group, Mathf.Clamp01(1f - (elapsedTime / fadeDuration)));
            yield return null;
        }

        SetGroupAlpha(group, 0f);
    }

    // Metodo per impostare l'alpha di tutte le immagini in un gruppo
    void SetGroupAlpha(GameObject group, float alpha)
    {
        if (group != null)
        {
            Image[] images = group.GetComponentsInChildren<Image>();
            foreach (Image img in images)
            {
                Color color = img.color;
                color.a = alpha;
                img.color = color;
            }
        }
    }
}"

voglio che dall ispector di questo codice si possa decidere quanti enemy instanziare, e decidere per ogni enemy quali immagini dissolvere all arrivo al punto designato e alla morte