using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.SceneManagement;

public class ADNController : MonoBehaviour
{
    private int maxVirus;
    private int currentPlayerLine = 0;
    private int currentVirusLine;

    [SerializeField]
    AudioClip gameMusic;

    [SerializeField]
    AudioClip correctSound;

    [SerializeField]
    GameObject combinations = null;

    [SerializeField]
    Sprite aminoRed = null;

    [SerializeField]
    Sprite aminoBlue = null;

    [SerializeField]
    Sprite aminoGreen = null;

    [SerializeField]
    Sprite aminoOrange = null;

    [SerializeField]
    Sprite virus = null;


    // ################################### //

    List<Sprite> adnL, adnR = null;
    List<int> correctAdnL, correctAdnR = null;
    private int duplaCount = 0;
    List<Sprite> aminoacidos = new List<Sprite>();

    void Start()
    {
        
        if(!SoundManager.Instance.MusicSource.isPlaying ||
            (SoundManager.Instance.MusicSource.isPlaying && SoundManager.Instance.MusicSource.clip != gameMusic))
        {
            SoundManager.Instance.PlayMusic(gameMusic);
        }
            

        InitAminoacidos();
        duplaCount = transform.childCount;
        adnL = new List<Sprite>(duplaCount);
        adnR = new List<Sprite>(duplaCount);
        correctAdnL = new List<int>(duplaCount);
        correctAdnR = new List<int>(duplaCount);
        maxVirus = Mathf.FloorToInt(duplaCount / 2 + duplaCount / 4);

        currentVirusLine = duplaCount - 1;

        for(int i = 0; i < duplaCount; i++)
        {
            adnL.Add(null);
            adnR.Add(null);
            correctAdnL.Add(-2);
            correctAdnR.Add(-2);
        }

        SetInitialADN();
        SetCombinations();
        CheckInitLine();
        // Obtenemos las duplas de ADN
        /*for (int i = 0; i < transform.childCount; i++)
        {
            Transform dupla = transform.GetChild(i);
            for(int j = 0; j < dupla.childCount; j++)
            {
                Transform aminoacido = dupla.GetChild(j);
                aminoacido.GetComponent<SpriteRenderer>().color = virus;
            }
        }*/
    }

    private void InitAminoacidos()
    {
        aminoacidos.Add(aminoGreen);
        aminoacidos.Add(aminoRed);
        aminoacidos.Add(aminoBlue);
        aminoacidos.Add(aminoOrange);
    }

    private void SetInitialADN()
    {
        int virusToSet = maxVirus;
        Debug.Log(virusToSet);
        Debug.Log("SETEO DE VIRUS");
        Debug.Log("#########################################");
        do
        {
            int line = Random.Range(0, 2);
            int duplaIndex = Random.Range(0, duplaCount - 1);
            if (adnL[duplaIndex] == null &&
                adnR[duplaIndex] == null)
            {
                virusToSet = virusToSet - 1;
                switch (line)
                {
                    case 0:
                        SetVirus(duplaIndex, adnL, correctAdnL);
                        SetAminoacido(duplaIndex, adnR, correctAdnR);
                        break;
                    case 1:
                        SetVirus(duplaIndex, adnR, correctAdnR);
                        SetAminoacido(duplaIndex, adnL, correctAdnL);
                        break;
                }
                Debug.Log("ADNR" + duplaIndex + ": " + adnR[duplaIndex]);
                Debug.Log("ADNL" + duplaIndex + ": " + adnL[duplaIndex]);
            }
        } while (virusToSet != 0);

        Debug.Log("FIN SETEO DE VIRUS");
        Debug.Log("###############################################");


        for (int i = 0; i < duplaCount; i++)
        {
            
            if (adnL[i] == null &&
                adnR[i] == null)
            {
                SetAminoacido(i, adnL, correctAdnL);
                SetAminoacido(i, adnR, correctAdnR);
            }
        }

        // Obtenemos las duplas de ADN
        for (int i = 0; i < transform.childCount; i++)
        {
            Transform dupla = transform.GetChild(i);

            Transform aminoacidoL = dupla.GetChild(0);
            Transform aminoacidoR = dupla.GetChild(1);


            aminoacidoL.GetComponent<SpriteRenderer>().sprite = adnL[i];
            aminoacidoR.GetComponent<SpriteRenderer>().sprite = adnR[i];
        }
    }

    private void SetUIAdnAminoacido(int line, int direction, Sprite aminSprite)
    {
        Transform dupla = transform.GetChild(line);
        Transform aminoacido = dupla.GetChild(direction);

        aminoacido.GetComponent<SpriteRenderer>().sprite = aminSprite;
        Debug.Log("SETEAR SPRITE: " + aminSprite);
        Debug.Log(aminoacido);
    }

    private void SetUIAdnVirus(int line, Sprite virus)
    {
        Transform dupla = transform.GetChild(line);
        Transform aminoacido = null;

        if (GetAminoType(adnL[line]) != -1)
        {
            aminoacido = dupla.GetChild(0);
        } else if (GetAminoType(adnR[line]) != -1)
        {
            aminoacido = dupla.GetChild(1);
        }

        aminoacido.GetComponent<SpriteRenderer>().sprite = virus;
    }

    private void SetVirus(int index, List<Sprite> adn, List<int> correctAdn)
    {
        adn[index] = virus;
        int aminoIndex = Random.Range(0, aminoacidos.Count);
        correctAdn[index] = GetAminoType(aminoacidos[aminoIndex]);
    }

    private void SetAminoacido(int index, List<Sprite> adn, List<int> correctAdn)
    {
        int aminoIndex = Random.Range(0, aminoacidos.Count);
        adn[index] = aminoacidos[aminoIndex];
        correctAdn[index] = GetAminoType(adn[index]);
    }

    public void InsertAminoacido(int aminoType)
    {
        CheckInitLine();

        if (GetAminoType(adnL[currentPlayerLine]) == -1)
        {
            Debug.Log("VIRUS EN IZQUIERDA");
            Debug.Log("Línea: " + currentPlayerLine);
            Debug.Log("Sprite: " + adnL[currentPlayerLine].name);
            Debug.Log("ADN Correcto: " + GetAminoSprite(correctAdnL[currentPlayerLine]));
            Debug.Log("ADN Elegido: " + GetAminoSprite(aminoType));
            if (correctAdnL[currentPlayerLine] == aminoType)
            {
                Debug.Log("HAS ELEGIDO EL CORRECTO");
                SoundManager.Instance.RandomSoundEffect(correctSound);
                SetUIAdnAminoacido(currentPlayerLine, 0, GetAminoSprite(aminoType));
                adnL[currentPlayerLine] = GetAminoSprite(aminoType);
                if (isPlayerLineComplete(currentPlayerLine))
                {
                    Debug.Log("PLAYER LINEA COMPLETADA");
                    CheckWin();
                    currentPlayerLine = currentPlayerLine + 1;
                }
            }
            else
            {
                Debug.Log("HAS ELEGIDO EL INCORRECTO");
                SetUIAdnVirus(currentVirusLine, virus);
                if (GetAminoType(adnL[currentVirusLine]) != -1)
                {
                    adnL[currentVirusLine] = virus;
                }
                else if (GetAminoType(adnR[currentVirusLine]) != -1)
                {
                    adnR[currentVirusLine] = virus;
                }
                if (isVirusLineComplete(currentVirusLine))
                {
                    Debug.Log("VIRUS LINEA COMPLETADA");
                    currentVirusLine = currentVirusLine - 1;
                    CheckLose();
                }
            }
        } else if (GetAminoType(adnR[currentPlayerLine]) == -1)
        {
            Debug.Log("VIRUS EN DERECHA");
            Debug.Log("Línea: " + currentPlayerLine);
            Debug.Log("Sprite: " + adnR[currentPlayerLine].name);
            Debug.Log("ADN Correcto: " + GetAminoSprite(correctAdnR[currentPlayerLine]));
            Debug.Log("ADN Elegido: " + GetAminoSprite(aminoType));
            if (correctAdnR[currentPlayerLine] == aminoType)
            {
                Debug.Log("HAS ELEGIDO EL CORRECTO");
                SoundManager.Instance.RandomSoundEffect(correctSound);
                SetUIAdnAminoacido(currentPlayerLine, 1, GetAminoSprite(aminoType));
                adnR[currentPlayerLine] = GetAminoSprite(aminoType);
                if (isPlayerLineComplete(currentPlayerLine))
                {
                    Debug.Log("PLAYER LINEA COMPLETADA");
                    CheckWin();
                    currentPlayerLine = currentPlayerLine + 1;
                }
            }
            else
            {
                Debug.Log("HAS ELEGIDO EL INCORRECTO");
                SetUIAdnVirus(currentVirusLine, virus);
                if (GetAminoType(adnL[currentVirusLine]) != -1)
                {
                    adnL[currentVirusLine] = virus;
                }
                else if (GetAminoType(adnR[currentVirusLine]) != -1)
                {
                    adnR[currentVirusLine] = virus;
                }
                if (isVirusLineComplete(currentVirusLine))
                {
                    Debug.Log("VIRUS LINEA COMPLETADA");
                    currentVirusLine = currentVirusLine - 1;
                    CheckLose();
                }
                    
            }
        }
    }

    private bool isPlayerLineComplete(int currentLine)
    {
        return (GetAminoType(adnL[currentLine]) != -1) &&
            (GetAminoType(adnR[currentLine]) != -1);
    }

    private bool isVirusLineComplete(int currentLine)
    {
        return (GetAminoType(adnL[currentLine]) == -1) &&
            (GetAminoType(adnR[currentLine]) == -1);
    }

    private int GetAminoType(Sprite aminoSprite)
    {
        int aminoType = -1; // Virus

        if (aminoSprite.Equals(aminoGreen))
        {
            aminoType = 0;
        } else if (aminoSprite.Equals(aminoRed))
        {
            aminoType = 1;
        } else if (aminoSprite.Equals(aminoBlue))
        {
            aminoType = 2;
        } else if (aminoSprite.Equals(aminoOrange))
        {
            aminoType = 3;
        }

        return aminoType;
    }

    private Sprite GetAminoSprite(int aminoType)
    {
        Sprite aminoSprite = virus; // Virus

        if (aminoType == 0)
        {
            aminoSprite = aminoGreen;
        }
        else if (aminoType == 1)
        {
            aminoSprite = aminoRed;
        }
        else if (aminoType == 2)
        {
            aminoSprite = aminoBlue;
        }
        else if (aminoType == 3)
        {
            aminoSprite = aminoOrange;
        }

        return aminoSprite;
    }

    public void SetCombinations()
    {
        List<int> correctAdnLDesordenada = new List<int>(correctAdnL);
        List<int> correctAdnRDesordenada = new List<int>(correctAdnR);

        Transform uiCombinations = combinations.transform;

        DesordenarListas(correctAdnLDesordenada, correctAdnRDesordenada);

        for (int i = 0; i < uiCombinations.childCount; i++)
        {
            Transform dupla = uiCombinations.GetChild(i);

            Transform aminoacidoL = dupla.GetChild(0);
            Transform aminoacidoR = dupla.GetChild(1);


            aminoacidoL.GetComponent<SpriteRenderer>().sprite = GetAminoSprite(correctAdnLDesordenada[i]);
            aminoacidoR.GetComponent<SpriteRenderer>().sprite = GetAminoSprite(correctAdnRDesordenada[i]);
        }
    }

    private void DesordenarListas(List<int> list1, List<int> list2)
    {
        List<int> arrDes1 = new List<int>(list1);
        List<int> arrDes2 = new List<int>(list2);

        list1.Clear();
        list2.Clear();

        while (arrDes1.Count > 0)
        {
            int val = Random.Range(0, arrDes1.Count - 1);
            list1.Add(arrDes1[val]);
            list2.Add(arrDes2[val]);
            arrDes1.RemoveAt(val);
            arrDes2.RemoveAt(val);
        }
    }

    public void CheckInitLine()
    {
        if (isPlayerLineComplete(currentPlayerLine))
        {
            currentPlayerLine = currentPlayerLine + 1;
        }

        if (isVirusLineComplete(currentVirusLine))
        {
            currentVirusLine = currentVirusLine - 1;
        }
    }

    public void CheckWin()
    {
        bool allPlayerLinesComplete = true;
        for(int i = 0; i < duplaCount; i++)
        {
            if (!isPlayerLineComplete(i))
            {
                allPlayerLinesComplete = false;
                break;
            }
        }

        if(allPlayerLinesComplete)
        {
            SceneManager.LoadScene("WinScene", LoadSceneMode.Single);
        } 
    }

    public void CheckLose()
    {
        if (currentVirusLine <= currentPlayerLine)
        {
            SceneManager.LoadScene("LoseScene", LoadSceneMode.Single);
        }
    }
}
