using System;
using System.Collections;
using System.Collections.Generic;
using System.Linq;
using UnityEngine;
using UnityEngine.InputSystem;
using UnityEngine.SceneManagement;
using UnityEngine.UI;

public class SausageGamePlay : MonoBehaviour
{
    private CountdownBeforeStart cbs;
    private PlayerInput pi;

    public SpriteRenderer a, b, x, y;

    public Transform character;

    private List<SpriteRenderer> currentCombinaison;

    public Sprite asprite, bsprite, xsprite, ysprite, aspriteok, bspriteok, xspriteok, yspriteok;

    public AudioSource wrongSound, progressSound, miamSound;
    public AudioClip slurpClip, miamClip, painnClip;
    public SausageSystem system;

    public GameObject bloodPrefab;

    private float drunkDirection = 1f;
    private float cptDrunk = 0f;
    private bool goChange;

    public int CurrentIdx { get
        {
            var currentIdx = 0;
            if (a.sprite == aspriteok) currentIdx++;
            if (b.sprite == bspriteok) currentIdx++;
            if (x.sprite == xspriteok) currentIdx++;
            if (y.sprite == yspriteok) currentIdx++;
            return currentIdx;
        } }

    private int score;

    public SpriteRenderer CurrentButton
    {
        get
        {
            if (currentCombinaison != null && currentCombinaison.Count == 4 && CurrentIdx < 4)
            {
                return currentCombinaison[CurrentIdx];
            }
            return null;
        }
    }

    private Vector3 initPos;

    public Text scoreText;

    public bool go = false;

    // Start is called before the first frame update
    void Start()
    {
        cbs = FindObjectOfType<CountdownBeforeStart>();
        if (!cbs) return;
        pi = GetComponent<PlayerInput>();
        system = FindObjectOfType<SausageSystem>();
        if (system.levelType == LevelType.Bottle) miamSound.clip = slurpClip;
        if (system.levelType == LevelType.Sausage) miamSound.clip = miamClip;
        if (system.levelType == LevelType.Knife) miamSound.clip = painnClip;
    }

    public void OnStart()
    {
        if (!cbs && PlayersTracking.Instance.players.Count >= 1)
        {
            SceneManager.LoadScene(1);
        }
        else
        {
            SceneManager.LoadScene(0);
        }
    }

    public void OnA(InputAction.CallbackContext context)
    {
        if (!context.started) return;
        if (!cbs)
        {
            transform.position = initPos + Vector3.up * -0.1f;
        }
        if (!CurrentButton) return;
        if (CurrentButton.name.StartsWith("A"))
        {
            progressSound.Play();
            CurrentButton.sprite = aspriteok;
        }
        else
        {
            wrongSound.Play();
            Shuffle();
        }
    }

    public void OnB(InputAction.CallbackContext context)
    {
        if (!context.started) return;
        if (!cbs)
        {
            transform.position = initPos + Vector3.right * 0.1f;
        }
        if (!CurrentButton) return;
        if (CurrentButton.name.StartsWith("B"))
        {
            progressSound.Play();
            CurrentButton.sprite = bspriteok;
        }
        else
        {
            wrongSound.Play();
            Shuffle();
        }
    }

    public void OnX(InputAction.CallbackContext context)
    {
        if (!context.started) return;
        if (!cbs)
        {
            transform.position = initPos + Vector3.left * 0.1f;
        }
        if (!CurrentButton) return;
        if (CurrentButton.name.StartsWith("X"))
        {
            progressSound.Play();
            CurrentButton.sprite = xspriteok;
        }
        else
        {
            wrongSound.Play();
            Shuffle();
        }
    }

    public void OnY(InputAction.CallbackContext context)
    {
        if (!context.started) return;
        if (!cbs)
        {
            transform.position = initPos + Vector3.up * 0.1f;
        }
        if (!CurrentButton) return;
        if (CurrentButton.name.StartsWith("Y"))
        {
            progressSound.Play();
            CurrentButton.sprite = yspriteok;
        }
        else
        {
            wrongSound.Play();
            Shuffle();
        }
    }

    public string Init(int players, int mul=5)
    {
        Debug.Log("INIT " + players + this.gameObject.name);
        transform.position = Vector3.right * (-7f + players * mul) - Vector3.up*2f;
        initPos = transform.position;
        scoreText.text = "";
        switch (players)
        {
            case 0:
                character.GetComponent<SpriteRenderer>().color = Color.magenta;
                return "Magenta";
            case 1:
                character.GetComponent<SpriteRenderer>().color = Color.green;
                return "Green";
            case 2:
                character.GetComponent<SpriteRenderer>().color = Color.cyan;
                return "Cyan";
            case 3:
                character.GetComponent<SpriteRenderer>().color = Color.yellow;
                return "Yellow";
        }
        return "Error";
    }

    public void Shuffle()
    {
        currentCombinaison = new List<SpriteRenderer> { a, b, x, y };
        currentCombinaison[0].sprite = asprite;
        currentCombinaison[1].sprite = bsprite;
        currentCombinaison[2].sprite = xsprite;
        currentCombinaison[3].sprite = ysprite;

        currentCombinaison.Sort((x, y) => UnityEngine.Random.Range(-1, 1));

        for(int i = 0; i < currentCombinaison.Count; i++)
        {
            currentCombinaison[i].transform.position = character.position + Vector3.up * 3f + Vector3.right * -2f + Vector3.right * i * 1.2f;
        }
    }

    IEnumerator KillSausage(GameObject sausage)
    {
        yield return null;
        float cpt = 0;
        while (Vector3.Distance(sausage.transform.position, character.transform.position + Vector3.up * 1f) > 0.1f)
        {
            sausage.transform.position = Vector3.Lerp(sausage.transform.position, character.position + Vector3.up * 1f, cpt);
            cpt += Time.deltaTime * 0.5f;
            yield return new WaitForEndOfFrame();
        }
        Destroy(sausage);        
    }

    // Update is called once per frame
    void Update()
    {
        if (!cbs)
        {
            a.enabled = false;
            b.enabled = false;
            x.enabled = false;
            y.enabled = false;
            return;
        }
        a.enabled = go;
        b.enabled = go;
        x.enabled = go;
        y.enabled = go;

        PlayersTracking.Instance.players.Where(p => p.Idx == pi.playerIndex).First().SausageScore = score;

        if (go)
        {
            if(system.levelType == LevelType.Bottle)
            {
                cptDrunk += Time.deltaTime;

                if(cptDrunk > score*0.3f)
                {
                    drunkDirection = -drunkDirection;
                    cptDrunk = 0f;
                }

                transform.eulerAngles = new Vector3(0, 0, transform.eulerAngles.z + drunkDirection * Time.deltaTime*score*8f);
            }
            if(system.levelType == LevelType.Knife)
            {
                cptDrunk += Time.deltaTime;

                if (cptDrunk > score * 0.2f)
                {
                    drunkDirection = -drunkDirection;
                    cptDrunk = 0f;
                }

                transform.eulerAngles = new Vector3(0, 0, transform.eulerAngles.z + drunkDirection * Time.deltaTime * score * 3f);

                a.transform.localScale += Time.deltaTime * drunkDirection * (score / 10f) * Vector3.one;
                b.transform.localScale += Time.deltaTime * drunkDirection * (score / 10f) * Vector3.one;
                x.transform.localScale += Time.deltaTime * drunkDirection * (score / 10f) * Vector3.one;
                y.transform.localScale += Time.deltaTime * drunkDirection * (score / 10f) * Vector3.one;

                a.transform.eulerAngles += Vector3.forward * score * Time.deltaTime * 5f * drunkDirection;
                b.transform.eulerAngles += Vector3.forward * score * Time.deltaTime * 5f;
                x.transform.eulerAngles += Vector3.forward * score * Time.deltaTime * 5f * drunkDirection;
                y.transform.eulerAngles += Vector3.forward * score * Time.deltaTime * 5f;

                if (score % 2 == 0 && goChange)
                {
                    goChange = false;
                    StartCoroutine(BloodCo());
                }
                else if(score%2!=0)
                {
                    goChange = true;
                }
            }

            if (currentCombinaison == null || currentCombinaison.Count == 0)
            {
                Shuffle();                
            }
            else
            {
                if (CurrentIdx == 4)
                {
                    GameObject highestSausage = null;
                    float highest = float.NegativeInfinity;
                    Transform box = system.sausageBox.transform;
                    
                    for (int i = 0; i < box.childCount;i++)
                    {
                        var s = box.GetChild(i).gameObject;
                        if(s.transform.position.y > highest)
                        {
                            highestSausage = s;
                            highest = s.transform.position.y;
                        }
                    }
                    highestSausage.transform.parent = null;
                    if (box.childCount == 0)
                    {
                        // FIN
                        go = false;
                    }

                    highestSausage.GetComponent<Rigidbody2D>().isKinematic = true;
                    StartCoroutine(KillSausage(highestSausage.gameObject));
                    score++;
                    scoreText.text = score + "";
                    Shuffle();
                    miamSound.pitch = UnityEngine.Random.Range(0.8f, 1.2f);
                    miamSound.Play();
                }
            }
        }        
    }

    IEnumerator BloodCo()
    {
        for (int i = 0; i < score; i++)
        {
            yield return new WaitForSeconds(0.1f);
            Instantiate(bloodPrefab, transform.position + Vector3.up * UnityEngine.Random.Range(0.5f, 1.5f) + Vector3.right * UnityEngine.Random.Range(-0.5f, 0.5f), Quaternion.identity);
        }
    }
}
