using System.Collections;
using System.Collections.Generic;
using TMPro;
using UnityEngine;
using UnityEngine.Events;

public class RouletteManager : MonoBehaviour
{
    public static RouletteManager instance { get; private set;}
    private static float moneyAvailable = 1000;
    public static float MoneyAvailable {get{ return moneyAvailable;} set{OnMoneyAvailablChanged.Invoke(value); moneyAvailable = value; foreach(TMP_Text txt in instance.vcurrencyTxt){txt.text = "$ " +value.ToString();}}}
    public static UnityEvent<float> OnMoneyAvailablChanged = new UnityEvent<float>();

    public static Dictionary<float, Chip> chipsBoard {get; private set;}
    public static bool RegisterChip(Chip chip){
        if(chipsBoard == null){chipsBoard = new Dictionary<float, Chip>();}

        if(chipsBoard.ContainsKey(chip.value)){return false;}

        chipsBoard.Add(chip.value, chip);
        selectedChipChanged.AddListener(chip.OnSelectedChanged);
        chip.OnSelectedChanged(SelectedChip);
        
        return true;
    }
    public static UnityEvent<float> selectedChipChanged = new UnityEvent<float>();
    private static float m_selectedChip = 1f;
    public static float SelectedChip { get{ return m_selectedChip; } set{
        m_selectedChip = value;
        selectedChipChanged.Invoke(value);
    }}

    public static Chip SelectedChipItem{get{return chipsBoard[SelectedChip];}}
    public static int[] RouletteNumbers = {-1,27,10,25,29,12,8,19,31,18,6,21,33,16,4,23,35,14,2,0,28,9,26,30,11,7,20,32,17,5,22,34,15,3,24,36,13,1};
    public static List<int> Reds = new List<int>(){1,3,5,7,9,12,14,16,18,19,21,23,25,27,30,32,34,36};

    public static Dictionary<int, BettingSpace> bettingSpaces = new Dictionary<int, BettingSpace>();
    public static List<int> HighlightedBettingSpaces = new List<int>();
    private static List<Bet> bets = new List<Bet>();
    public static List<Bet> PlacedBets {get{return bets;}}

    public static bool spinning;
    public TMP_Text betsvalue;
    public TMP_Text[] vcurrencyTxt;
    public TMP_Text walletMoneyTxt;
    public float walletMoney;
    public Transform betsHistoryParent;


    public static void RegisterBettingSpace(BettingSpace space){
        if(bettingSpaces.ContainsKey(space.Number)){return;}
        bettingSpaces.Add(space.Number, space);
    }

    public static void HighlightBettingSpace(List<int> numbers){
        HighlightedBettingSpaces = numbers;
        UpdateHightlightedSpaces();
    }
   
    public static void ClearHighlightedBettingSpaces(){ HighlightedBettingSpaces = new List<int>(); UpdateHightlightedSpaces();}

    static void UpdateHightlightedSpaces(){
        foreach(KeyValuePair<int,BettingSpace> bettingSpace in bettingSpaces){
            if(HighlightedBettingSpaces.Contains(bettingSpace.Key)){
                bettingSpace.Value.SetHighlighted(true);
            }else{
                bettingSpace.Value.SetHighlighted(false);

            }
        }
    }


    public static void RefreshUI(){
        instance.Refresh();
    }

    public void Refresh(){
        
        betsvalue.text = "$"+ GetBetsValue();

    }

    public static float GetBetsValue(){
        float betsVal = 0;
        foreach(Bet bet in bets){
            betsVal += bet.BetAmount;
        }

        return betsVal;
    }

    public static void AddBet(float value, CombinerType type, List<int> _numbers, GameObject newChip){
        // bets += value;
        if(value > MoneyAvailable){Debug.LogError("Not enough money for this"); return;}
        Bet newBet = new Bet(){BetAmount = value, PayoutRatio = GetRatioFromType(type), Numbers = _numbers, chipObj= newChip};
        bets.Add(newBet);
        MoneyAvailable-=value;
        instance.BetsChanged();

        RefreshUI();
    }

    public static void ClearBets(){
        foreach(Bet bet in bets){
            Destroy(bet.chipObj);
        }
        bets = new List<Bet>();

        RefreshUI();
    }

    void Awake(){
        instance =this;
    }
    void Start()
    {
        MoneyAvailable = 1000;
        walletMoney = MoneyAvailable;
        walletMoneyTxt.text = "$ " +MoneyAvailable;

        Spinner.OnSpinStopped.AddListener(OnSpinStopped);
    }

    
    List<float> betsHistory = new List<float>();
    void OnSpinStopped(int landedValue){
        float prevMoney=walletMoney;
        foreach(Bet bet in bets){
            if(bet.Numbers.Contains(landedValue)){

                float addition =  (bet.BetAmount * bet.PayoutRatio) + (bet.BetAmount);
                MoneyAvailable += addition;
                // profit += addition;
            }else{
                // profit -= bet.BetAmount;
            }
        }
        Debug.Log("Bet profitted : " + (MoneyAvailable - prevMoney));
        betsHistory.Add((MoneyAvailable - prevMoney));
        walletMoneyTxt.text = "$ " +MoneyAvailable;
        walletMoney = MoneyAvailable;
        UpdateBetsHistory();
        ClearBets();
    }

    void UpdateBetsHistory(){

        int diff = betsHistory.Count - betsHistoryParent.childCount;
        for(int i=0; i < diff; i++){
            betsHistory.RemoveAt(i);
        }
        for(int i =0; i < betsHistoryParent.childCount; i++){
            if(betsHistory.Count <= i){
                betsHistoryParent.GetChild(i).GetChild(0).GetComponent<TMP_Text>().text = "-";
                betsHistoryParent.GetChild(i).GetChild(1).GetComponent<TMP_Text>().text = "-";
                betsHistoryParent.GetChild(i).GetChild(0).GetComponent<TMP_Text>().color = Color.white;
                betsHistoryParent.GetChild(i).GetChild(1).GetComponent<TMP_Text>().color =  Color.white;
            }else{
                Color txtColor = betsHistory[i] > 0 ? Color.green : Color.red;
                betsHistoryParent.GetChild(i).GetChild(0).GetComponent<TMP_Text>().text = "$ " + Mathf.Abs(betsHistory[i]).ToString();
                betsHistoryParent.GetChild(i).GetChild(1).GetComponent<TMP_Text>().text = betsHistory[i] > 0 ? "Win" : "Lose";
                betsHistoryParent.GetChild(i).GetChild(0).GetComponent<TMP_Text>().color = txtColor;
                betsHistoryParent.GetChild(i).GetChild(1).GetComponent<TMP_Text>().color = txtColor;
            }
        }


    }

    void BetsChanged(){
    }






    public static float GetRatioFromType(CombinerType type){
        switch(type){
            case CombinerType.Single:
                return 35;
                break;

            case CombinerType.Split:
                return 17;
                break;

            case CombinerType.Street:
                return 11;
                break;

            case CombinerType.Corner:
                return 8;
                break;

            case CombinerType.Five:
                return 6;
                break;

            case CombinerType.Line:
                return 5;
                break;

            case CombinerType.Dozen:
                return 2;
                break;

            case CombinerType.Row:
                return 2;
                break;

            case CombinerType.Eighteen:
                return 1;
                break;

            case CombinerType.Red:
                return 1;
                break;

            case CombinerType.Black:
                return 1;
                break;

            case CombinerType.Even:
                return 1;
                break;

            case CombinerType.Odd:
                return 1;
                break;
        }
        return 1;

    }

}

[System.Serializable]
public class Bet{
    public float BetAmount;
    public float PayoutRatio = 1;
    public List<int> Numbers;
    public GameObject chipObj;
}
