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

public class Radio : MonoBehaviour {

    public float tempoTotal = 30f;
    public float velocidade;
    public float hora;
    public bool tocando;

    public List<Programa> programacao;
    public Programa programaAtual;
    public GameObject hudProgramas;
    
//*************************************** PLAYBACK
    float time;
    int audienciaInicial;
    int indexPrograma;
    int horaFechada;
    public int audienciaAtual;
    public float dinheiroDia;
    public Programa melhorMusica;
    public Programa piorMusica;
    public RectTransform areaAgulha;
    public GameObject agulha;

//*************************************** INSTANCIACAO DE PROGRAMAS
    public float maxQualidade = 0.2f;
    public List<Programa> marketProgramas = new List<Programa>();
    public List<Programa> marketAds = new List<Programa>();

    // Use this for initialization
    void Start () {
        SetVelocidadePadrao();
        programacao = new List<Programa>();
        audienciaInicial = audienciaAtual = 20;
        
        AtualizaProgramasDisponiveis();
        
	}
	
	// Update is called once per frame
	void Update () {
        if (tocando) {
            var deltaTime = Time.time - time;
            time = Time.time;
            hora += deltaTime * velocidade;
            Vector2 posAgulha = agulha.GetComponent<Image>().rectTransform.anchoredPosition;
            agulha.GetComponent<Image>().rectTransform.anchoredPosition = new Vector2((hora / 24 * areaAgulha.rect.width) - areaAgulha.rect.width / 2, posAgulha.y);

            //ajuste de audiência de acordo com preferencia (50% de mudar)
            if (programaAtual != null) {
                //se for hora cheia
                var audienceShift = 0;
                if (Random.Range(0f, 1f) >= 0.7f) {
                    //normaliza de 0..1
                    float preferencia = GameManager.instance.ouvintes.Preferencia(programaAtual) * (1 / PoolOuvintes.MAX_PREFERENCE);

                    if (preferencia > ThresholdPreferencia()) {
                        audienceShift = 1;
                    } else {
                        audienceShift = -1;
                    }
                }

                audienciaAtual += audienceShift;
                audienciaAtual = Mathf.Clamp(audienciaAtual, 0, PoolOuvintes.instance.maxOuvintes);
                Debug.Log("Audiencia : " + audienciaAtual + "\n\tDinheiro : " + dinheiroDia);
            }

            //se terminou o programa
            if (programaAtual != null && hora > programaAtual.horaInicial + programaAtual.duracao) {
                //atualiza melhor/pior do dia
                AtualizaMelhorPior(programaAtual);

                //calcula custos/ganhos
                var mediaAudiencia = audienciaAtual + audienciaInicial / 2;
                var dinheiro = programaAtual.dinheiroDiario * (programaAtual.ad ? mediaAudiencia : 1);

                dinheiroDia += dinheiro;

                //passa pro próximo programa
                //programacao.RemoveAt(0);
                programaAtual = null;
            }

            //se começou outro programa
            if (programaAtual == null && programacao.Count > 0 && indexPrograma < programacao.Count) {
                if (hora >= programacao[indexPrograma].horaInicial && hora <= programacao[indexPrograma].horaInicial + programacao[indexPrograma].duracao) {
                    programaAtual = programacao[indexPrograma++];
                    audienciaInicial = audienciaAtual;
                }
            }

            //se terminou o dia
            if (hora >= 24) {
                tocando = false;
                PoolOuvintes.instance.AtualizaPreferencias(melhorMusica.genero, piorMusica.genero);
                AtualizaProgramasDisponiveis();

                GameManager.instance.dinheiro += dinheiroDia;

                if (GameManager.instance.dinheiro < 0) {
                    SceneManager.LoadScene(2);
                }
            }
        }
	}

    public void Tocar() {
        if (!tocando && programacao.Count > 0) {
            dinheiroDia = 0f;
            hora = 0f;
            time = Time.time;
            tocando = true;
            indexPrograma = 0;
            horaFechada = 0;

            //audiencia atual se mantem do dia anterior;
        } else if (programacao.Count == 0) {
            Debug.LogError("Programação vazia. Para tocar deve ter algum programa.");
        }
    }

    public void Acelerar() {
        SetVelocidadePadrao();
        velocidade = velocidade * 3;
    }

    public void SetVelocidadePadrao() {
        velocidade = 24f / tempoTotal;
    }

    float ThresholdPreferencia() {
        return Random.Range(0f, 1f);
    }

    void AtualizaMelhorPior(Programa programa) {
        if (melhorMusica == null || programa.qualidade > melhorMusica.qualidade) {
            melhorMusica = programa;
        } 
        if (piorMusica == null || programa.qualidade < piorMusica.qualidade) {
            piorMusica = programa;
        }
    }

    void AtualizaProgramasDisponiveis() {
        var gens = System.Enum.GetValues(typeof(Programa.Genero));

        if (marketProgramas.Count == 0) {
            for (int i = 0; i < 10; i++) {
                Programa progNovo = new Programa();
                progNovo.genero = (Programa.Genero)gens.GetValue(Random.Range(0, gens.Length));
                progNovo.qualidade = Random.Range(0.1f, maxQualidade);
                progNovo.dinheiroDiario = (int) -(Random.Range(500, 1500) * progNovo.qualidade);
                progNovo.duracao = Random.Range(1, 4);
                
                GameObject btnProg = (GameObject) Instantiate(Resources.Load("BtnPrograma"));
                BtnMarket btnMarket = btnProg.GetComponent<BtnMarket>();
                btnMarket.programa = progNovo;
                btnMarket.radio = this;
                btnProg.transform.SetParent(GameObject.FindGameObjectWithTag("MusicContent").transform, false);

                marketProgramas.Add(progNovo);
            }
        } else {
            //TODO atualiza programas no final da semana
        }

        if (marketAds.Count == 0) {
            for (int i = 0; i < 2; i++) {
                Programa progNovo = new Programa();
                progNovo.ad = true;
                progNovo.dinheiroDiario = Random.Range(5, 10);
                progNovo.duracao = 0.25f;

                GameObject btnAds = (GameObject)Instantiate(Resources.Load("BtnAds"));
                BtnAds btnMarket = btnAds.GetComponent<BtnAds>();
                btnMarket.programa = progNovo;
                btnMarket.radio = this;
                btnAds.transform.SetParent(GameObject.FindGameObjectWithTag("AdContent").transform, false);

                marketAds.Add(progNovo);
            }
        } else {
            //TODO atualiza ads no final da semana
        }
    }

    public void AddPrograma(Programa programa) {
        float horaInicial = 0f;
        float duracao = 0f;
        if(programacao.Count > 0) {
            Programa ultimo = programacao[programacao.Count - 1];
            horaInicial = ultimo.horaInicial;
            duracao = ultimo.duracao;
        }
        
        if (horaInicial + duracao + programa.duracao <= 24f) {
            programa.horaInicial = horaInicial + duracao;

            programacao.Add(programa);
            GameObject card = (GameObject) Instantiate(Resources.Load("CardPrograma"));

            CardProgramaHandler cardHandler = card.GetComponent<CardProgramaHandler>();
            cardHandler.radio = this;
            cardHandler.programa = programa;

            card.transform.SetParent(hudProgramas.transform, false);
        }
    }

    public void RemovePrograma(GameObject gameObjPrograma) {
        Programa prog = gameObjPrograma.GetComponent<CardProgramaHandler>().programa;

        if (programacao.Contains(prog)) { 
            programacao.Remove(prog);
        }
        Destroy(gameObjPrograma);
    }
}
