using Models;
using System;
using System.Collections.Generic;
using System.Linq;
using TMPro;
using Unity.Func.Sample.Net;
using UnityEngine;
using UnityEngine.Serialization;
using UnityEngine.UI;

namespace Unity.Func.Sample.UI
{
    public class MainUIController : MonoBehaviour
    {
        [Header("面板管理")]
        public List<GameObject> panels;

        [Header("用户信息、资产信息、幸运值")] public TextMeshProUGUI userName;
        public List<TextMeshProUGUI> diamondsCount;
        public List<TextMeshProUGUI> coinsCount;
        public List<string> luckyPoints;
        public TextMeshProUGUI luckyResult;
        private bool _drew; // 已经抽过卡了

        [Header("面板控制器")] private RewardUIController _rewardUIController;
        private InventoryUIController _inventoryUIController;
        private HeroesUIController _heroesUIController;

        public CardConfig cardConfig;
        private readonly Dictionary<string, CardConfig.Card> _cardMap = new();
        private static NetworkManager NetworkManager => NetworkManager.Instance;

        // 按钮
        [FormerlySerializedAs("_allButtons")][SerializeField] private List<Button> allButtons;

        private enum UIPanel
        {
            MainUI,
            Inventory,
            Heroes,
            Draw,
            Loading,
            Reward,
            Setup,
        }

        private void Start()
        {
            // 设置变量
            _heroesUIController = panels[(int)UIPanel.Heroes].GetComponent<HeroesUIController>();
            _inventoryUIController = panels[(int)UIPanel.Inventory].GetComponent<InventoryUIController>();
            _rewardUIController = panels[(int)UIPanel.Reward].GetComponent<RewardUIController>();
            // 重置各个面板初始状态
            panels[(int)UIPanel.Inventory].SetActive(false);
            panels[(int)UIPanel.Heroes].SetActive(false);
            panels[(int)UIPanel.Draw].SetActive(false);
            panels[(int)UIPanel.Loading].SetActive(false);
            panels[(int)UIPanel.Reward].SetActive(false);
            panels[(int)UIPanel.Setup].SetActive(true);

            foreach (var card in cardConfig.cards)
            {
                _cardMap.Add(card.slugName, card);
            }
        }

        /// <summary>
        /// 根据用户填写的信息启动游戏
        /// </summary>
        public async void StartGame()
        {
            var empty = InputFieldManager.GetEmptyItems();
            if (empty != "")
            {
                MessageUI.Show("请输入" + empty);
                return;
            }

            try
            {
                ShowLoading(true);
                await NetworkManager.Login(InputFieldManager.Username, InputFieldManager.Password);
            }
            catch (Exception e)
            {
                Debug.Log(e.Message);
                ShowLoading(false);
                MessageUI.Show(e.Message);
            }
        }

        #region Panel Manager

        public async void GetHeroes()
        {
            ShowLoading(true);
            try
            {
                await NetworkManager.GetInventory(InventoryType.HeroInventory);
            }
            catch (Exception e)
            {
                Debug.Log(e.Message);
                ShowLoading(false);
                MessageUI.Show(e.Message);
            }
        }

        public async void GetInventory()
        {
            ShowLoading(true);
            try
            {
                await NetworkManager.GetInventory(InventoryType.PropInventory);
            }
            catch (Exception e)
            {
                Debug.Log(e.Message);
                ShowLoading(false);
                MessageUI.Show(e.Message);
            }
        }

        public async void DrawCard(int count = 1)
        {
            ShowLoading(true);
            try
            {
                await NetworkManager.DrawCard(count);
            }
            catch (Exception e)
            {
                Debug.Log(e.Message);
                ShowLoading(false);
                MessageUI.Show(e.Message);
            }
        }

        public void ShowInventory(bool show)
        {
            panels[(int)UIPanel.MainUI].SetActive(!show);
            panels[(int)UIPanel.Inventory].SetActive(show);
        }

        public void ShowHeroes(bool show)
        {
            panels[(int)UIPanel.MainUI].SetActive(!show);
            panels[(int)UIPanel.Heroes].SetActive(show);
        }

        public void ShowDraw(bool show)
        {
            panels[(int)UIPanel.MainUI].SetActive(!show);
            panels[(int)UIPanel.Draw].SetActive(show);
        }

        private void ShowLoading(bool show)
        {

            foreach (var button in allButtons)
            {
                button.interactable = !show;
            }

            panels[(int)UIPanel.Loading].SetActive(show);
        }

        #endregion

        #region Server Events Handlers

        public void ErrorHandler(string msg, int waitSeconds)
        {
            ShowLoading(false);
            MessageUI.Show($"{msg}", waitSeconds);
        }

        /// <summary>
        /// 处理用户信息
        /// </summary>
        public void LoginHandler(Account userInfo)
        {
            userName.text = userInfo.Nickname;

            foreach (var dc in diamondsCount)
            {
                dc.text = userInfo.Diamonds.ToString();
            }
            foreach (var dc in coinsCount)
            {
                dc.text = userInfo.Coins.ToString();
            }

            panels[(int)UIPanel.Setup].SetActive(false);
            // 重置各个面板初始状态
            panels[(int)UIPanel.MainUI].SetActive(true);
            panels[(int)UIPanel.Inventory].SetActive(false);
            panels[(int)UIPanel.Heroes].SetActive(false);
            panels[(int)UIPanel.Draw].SetActive(false);
            panels[(int)UIPanel.Loading].SetActive(false);
            panels[(int)UIPanel.Reward].SetActive(false);
            ShowLoading(false);
        }

        /// <summary>
        /// 处理资产信息
        /// </summary>
        /// <param name = "prop" ></param>
        public void PropertyHandler(Property prop)
        {
            ShowLoading(false);
            foreach (var dc in diamondsCount)
            {
                dc.text = prop.Diamonds.ToString();
            }

            foreach (var cc in coinsCount)
            {
                cc.text = prop.Coins.ToString();
            }

            if (_drew)
            {
                luckyResult.text = luckyPoints[prop.LuckLevel];
            }
        }

        /// <summary>
        /// 处理背包信息
        /// </summary>
        public void InventoryHandler(List<Item> inventory)
        {
            ShowLoading(false);
            var cards = GetCards(inventory, CardConfig.Type.Inventory);
            ShowInventory(true);
            _inventoryUIController.Init(cards);
        }

        /// <summary>
        /// 处理英雄信息
        /// </summary>
        public void HeroesHandler(List<Item> inventory)
        {
            ShowLoading(false);
            var cards = GetCards(inventory, CardConfig.Type.Heroes);
            ShowHeroes(true);
            _heroesUIController.Init(cards);
        }

        /// <summary>
        /// 处理抽卡结果
        /// </summary>
        public async void DrawCardHandler(List<Item> result)
        {
            Debug.Log(result.Count);

            ShowLoading(false);
            _drew = true;
            var cards = new List<CardConfig.Card>();
            foreach (var item in result)
            {
                if (_cardMap.TryGetValue(item.Name, out var card))
                {
                    cards.Add(new CardConfig.Card()
                    {
                        cardName = card.cardName,
                        cardSprite = card.cardSprite,
                        color = card.color,
                        count = item.Count,
                        level = item.Level,
                        type = item.Type == 0 ? CardConfig.Type.Heroes : CardConfig.Type.Inventory
                    });
                }
            }

            _rewardUIController.Init(cards);
            await NetworkManager.GetProperty();
        }

        #endregion

        private List<CardConfig.Card> GetCards(List<Item> inventory, CardConfig.Type type)
        {
            List<CardConfig.Card> cards = new();
            foreach (var item in inventory)
            {
                if (_cardMap.TryGetValue(item.Name, out var card))
                {
                    cards.Add(new CardConfig.Card()
                    {
                        cardName = card.cardName,
                        cardSprite = card.cardSprite,
                        color = card.color,
                        count = item.Count,
                        level = item.Level,
                        type = type
                    });
                }
            }

            return cards.Where(card => card.type == type).ToList();
        }
    }
}