using System.Collections;
using System.Collections.Generic;
using TMPro;
using UnityEngine;
using UnityEngine.UI;
using Random = UnityEngine.Random;

public class MinigameScreenController : MonoBehaviour {
    [SerializeField] private Button _raiseButton;
    [SerializeField] private Slider _currentBetSlider;
    [SerializeField] private TextMeshProUGUI _currentBetText;
    
    [SerializeField] private List<TextMeshProUGUI> _otherBidders;
    [SerializeField] private List<string> _otherBiddersNames;

    [SerializeField] private TextMeshProUGUI _currentItemLabel;
    [SerializeField] private TextMeshProUGUI _basePriceLabel;
    [SerializeField] private TextMeshProUGUI _buyInPriceLabel;

    [SerializeField] private TextMeshProUGUI _brokenLabel;

    [SerializeField] private float _buyInPrice = 5; //The price it costs to buy in to the auction
    [SerializeField] private float _raiseSpeed = 10;
    
    private bool _isRunning = false;
    private bool _didRun = false;
    private float _currentBet = 0;
    private float _maxBet = 50;

    private const float MinBet = 0;

    
    [SerializeField] private ObjectSO _currentObject;
    private bool _isBroken = false;
    
    private readonly List<float> _otherBiddersPrices = new List<float>();
    
    //This is the computer that the player is interacting with
    private ComputerBehaviour _computerBehaviour;

    
    private void Start() {
        _currentBetSlider.minValue = MinBet;
        _maxBet = _currentObject.basePrice * 2;
        _currentBetSlider.maxValue = _maxBet;
        
        _buyInPriceLabel.text = _buyInPrice.ToString() + "$";
        
        foreach (TextMeshProUGUI textMeshProUGUI in _otherBidders) {
            textMeshProUGUI.text = "0$";
        }
        
        _currentBetText.text = _currentBet.ToString() + "$";
        
    }

    private void OnEnable() {
        _raiseButton.onClick.AddListener(StartRaise);
    }
    private void OnDisable() {
        _raiseButton.onClick.RemoveListener(StartRaise);
        _computerBehaviour = null;
    }
    private void StartRaise() {
        if (_didRun == false) {
            if (_isRunning == false) {
                GameController.Instance.Money -= _buyInPrice;
                _isRunning = true;
                StartCoroutine(RaiseBet());
            }
            else { 
                _isRunning = false;
                StopCoroutine(RaiseBet());
                StopRaise();
                Debug.Log("Current bet: " + _currentBet);
            }
        }
        else {
            Debug.Log("already ran for this item");
        }
    }    
    
    private void StopRaise() {
        _isRunning = false;
        
        //Calculate the other bidders
        //check if ur the highest bidder
        //if not, check if the other bidders are higher than the current bet
        
        _didRun = true;
    
        
        foreach (var textMeshProUGUI in _otherBidders) {
            float basePrice = _currentObject.basePrice;
            if (_isBroken) {
                basePrice *= 0.5f;
            }
            float randomPrice = Random.Range(-12.0f, -2.0f);
            randomPrice = Mathf.Round(randomPrice * 100) / 100;
            float finalPrice = basePrice + randomPrice;
            
            finalPrice = Mathf.Round(finalPrice * 100) / 100;
            finalPrice = Mathf.Max(finalPrice, 0);
            
            _otherBiddersPrices.Add(finalPrice);
            
            textMeshProUGUI.text = finalPrice.ToString() + "$";
        }
        
        
        //Check if the player is the highest bidder
        bool playerIsHighest = true;
        foreach(var price in _otherBiddersPrices) {
            if (price > _currentBet) {
                playerIsHighest = false;
            }
        }
        
        if (playerIsHighest) {
            Debug.Log("Player is the highest bidder");
            _currentBetText.color = Color.green;
            GameController.Instance.Money += _buyInPrice;
            _computerBehaviour.ConfirmBuy(_currentObject, _currentBet, _isBroken);
            SoundFXController.Instance.PlayItemBoughtFX();
        }
        else {
            Debug.Log("Player is not the highest bidder");
            _currentBetText.color = Color.red;
        }
        
    }

    public void Reset() {
        _didRun = false;
        _currentBet = 0;
        _currentBetText.color = Color.white;
        _currentBetText.text = _currentBet.ToString() + "$";
        _currentBetSlider.value = _currentBet;
        foreach (var textMeshProUGUI in _otherBidders) {
            textMeshProUGUI.text = "0$";
        }
        
        _otherBiddersPrices.Clear();
    }
    
    private IEnumerator RaiseBet() {
        while (_isRunning) {
            //Round to 2 decimals
            _currentBet += _raiseSpeed * Time.deltaTime;
            _currentBet = Mathf.Round(_currentBet * 100) / 100;
            _currentBetSlider.value = _currentBet;
            _currentBetText.text = _currentBet.ToString() + "$";
            if (_currentBet >= _maxBet) {
                StopRaise();
            }
            yield return null;
        }
    }

    public void BuyItem(ComputerBehaviour computerBehaviour, ObjectSO objectSo, bool isBroken) {
        this.UpdateItem(objectSo, isBroken);
        _computerBehaviour = computerBehaviour;
    }


    public void UpdateItem(ObjectSO objectToSell, bool isBroken) {
        _currentObject = objectToSell;
        Reset();
        float actualBasePrice = objectToSell.basePrice;
        _brokenLabel.text = isBroken ? "Broken" : "Not Broken";
        _isBroken = isBroken;
        if (isBroken) {
            actualBasePrice *= 0.5f;
            _maxBet = actualBasePrice * 2;
        }
        _currentItemLabel.text = objectToSell.objectName;
        float playerMoney = GameController.Instance.Money;
        _maxBet = Mathf.Min(_maxBet, playerMoney);
        
        _maxBet = objectToSell.basePrice * 2;
        _currentBetSlider.maxValue = _maxBet;
        
        //Here we lower the price if the item is broken
      
        
        _currentBetSlider.maxValue = _maxBet;
        
        _basePriceLabel.text = actualBasePrice.ToString() + "$";
        _basePriceLabel.color = isBroken ? Color.red : Color.black;
        
    }
}
