using System;
using System.Collections;
using System.Collections.Generic;
using System.Linq;
using System.Net.Mime;
using System.Text;
using Assets.Scripts.Player;
using UnityEngine;
using UnityEngine.UI;
using Object = UnityEngine.Object;

namespace Assets.Scripts.UI.Placeholder
{
    public class EventUI : IEventUI {
        [SerializeField] private Text _actTitle;
        [SerializeField] private Text _text;
        [SerializeField] private Text _coinText;
        [SerializeField] private Button _button;
        [SerializeField] private GameObject _buttonHolder;

        [SerializeField] private GameObject _favoAvatar;
        [SerializeField] private GameObject _luaAvatar;
        [SerializeField] private GameObject _couroAvatar;
        [SerializeField] private GameObject _rosaAvatar;
        [SerializeField] private GameObject _avatarHolder;

        [SerializeField] private GameObject _avatarDetails;
        [SerializeField] private Text _health;
        [SerializeField] private Text _sanity;
        [SerializeField] private Text _cooldown;
        [SerializeField] private Text _range;
        [SerializeField] private Text _damage;
        [SerializeField] private Text _accuracy;

        private Button[] _buttons;
        private readonly List<GameObject> _avatars = new List<GameObject>();
        private Mob _showingMob;

        protected void Start () {
            GameCore.Instance.EventUI = this;

            var buttons = new List<Button>();
            buttons.Add(_button);
            for (int i = 0; i < 3; i++) {
                var go = (GameObject) Instantiate(_button.gameObject);
                go.transform.SetParent(_buttonHolder.transform, true);
                buttons.Add(go.GetComponent<Button>());
            }
            _buttons = buttons.ToArray();
            {
                int i = 0;
                foreach (var b in _buttons) {
                    var pos = _button.transform.localPosition;
                    pos.y += i++ * -75;
                    b.transform.localPosition = pos;
                    b.transform.localScale = _button.transform.localScale;
                }
            }

            Clear();
        }

        public void OnDisable() {
            SetupAvatars(new Mob[] {});
        }

        public override void Clear () {
            _actTitle.gameObject.SetActive(false);
            _text.gameObject.SetActive(false);
            HideOptions();
        }

        private void HideOptions() {
            ShowOptions(new string[] {}, null);
        }

        public override void ShowActTitle(params string[] text) {
            StartCoroutine(ActTitleCoroutine(text));
        }

        private IEnumerator ActTitleCoroutine(string[] texts) {
            _actTitle.gameObject.SetActive(true);
            int i = 0;

            foreach (var text in texts) {
                _actTitle.fontSize = i == 0 ? 150 : 100;

                _actTitle.text = text;
                for (float t = 0; t < 1; t += Time.deltaTime) {
                    _actTitle.color = new Color(1, 1, 1, t);
                    yield return null;
                }
                _actTitle.color = new Color(1, 1, 1, 1);
                yield return new WaitForSeconds(2.0f);
                for (float t = 0; t < 1; t += Time.deltaTime) {
                    _actTitle.color = new Color(1, 1, 1, 1 - t);
                    yield return null;
                }
                _actTitle.color = new Color(1, 1, 1, 0);
                i++;
            }

            _actTitle.gameObject.SetActive(false);
        }

        public override void ShowText(string text) {
            _text.text = text;
            _text.gameObject.SetActive(true);
        }

        public override void ShowOptions(string[] options, GameCore.OptionPicked callback) {
            for (int i = 0; i < _buttons.Length; i++) {
                var button = _buttons[i];
                button.onClick.RemoveAllListeners();
                if (i < options.Length) {
                    button.gameObject.SetActive(true);
                    button.interactable = !options[i].StartsWith("N/A: ");
                    button.GetComponentInChildren<Text>().text = options[i];
                    int buttonN = i;
                    button.onClick.AddListener(() => {
                        HideOptions();
                        callback(buttonN);
                    });

                    float posX = ((i % 2) - 0.5f) * 850.0f;
                    if ((i == 0 && options.Length == 1) || (i == 2 && options.Length == 3)) {
                        posX = 0;
                    }
                    float posY = (i / 2) * -130 - 45.0f;
                    button.transform.localPosition = new Vector3(posX, posY, 0);
                } else {
                    button.gameObject.SetActive(false);
                }
            }
        }

        public override void SetupAvatars(Mob[] characters) {
            _avatarDetails.SetActive(false);
            foreach (var c in _avatars) {
                Destroy(c);
            }
            _avatars.Clear();

            int i = 0;
            foreach (var c in characters) {
                float relPos = i - (characters.Length - 1) * 0.5f;
                var go = (GameObject) Instantiate(GetAvatarPrefab(c));
                go.transform.SetParent(_avatarHolder.transform);
                go.transform.localPosition = new Vector3(relPos*400, -590.0f, 0);
                go.transform.localScale = new Vector3(0.9f, 0.9f, 0.6f);
                go.GetComponent<EventAvatar>().SetCharacter(this, c);
                _avatars.Add(go);
                i++;
            }
        }

        private Object GetAvatarPrefab(Mob mob) {
            switch (mob.Name) {
                case "Couro":
                    return _couroAvatar;
                case "Lua":
                    return _luaAvatar;
                case "Rosa":
                    return _rosaAvatar;
                case "Favo":
                    return _favoAvatar;
            }
            return null;
        }

        public void ShowDetails(Mob mob, float xPos) {
            if (_showingMob != null) {
                HideDetails(_showingMob);
            }
            _showingMob = mob;
            _avatarDetails.SetActive(true);

            var pos = _avatarDetails.transform.position;
            pos.x = xPos;
            _avatarDetails.transform.position = pos;

            _health.text = Mathf.Max(0, mob.GetAttribute(MobAttribute.Health)) + "/" + mob.GetAttribute(MobAttribute.MaxHealth);
            _sanity.text = Mathf.Max(0, mob.GetAttribute(MobAttribute.Sanity)) + "/" + mob.GetAttribute(MobAttribute.MaxSanity);
            _cooldown.text = mob.GetAttributeFloat(MobAttribute.Cooldown).ToString("0.0");
            _range.text = mob.GetAttribute(MobAttribute.Range).ToString();
            _damage.text = mob.GetAttribute(MobAttribute.Damage).ToString();
            _accuracy.text = Mathf.RoundToInt((mob.GetAttributeFloat(MobAttribute.Accuracy) * 100)) + "%";
        }

        public void HideDetails(Mob mob) {
            if (mob != null && mob == _showingMob) {
                _avatarDetails.SetActive(false);
            }
        }

        protected void Update() {
            _coinText.text = GameCore.Instance.PlayerStats.Gold.ToString();
        }
    }
}
