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

namespace KF3.UI.Panels
{
    public class SpawnPanel : MonoBehaviour
    {
        public void Open() { }
        public void Close() { }

        public Button FriendSelectButton;
        public ScrollRect FriendSelection;

        public Button CeruleanSelectButton;
        public ScrollRect CeruleanSelection;

        public Button FurnitureSelectButton;
        public ScrollRect FurnitureSelection;

        public Button MiscSelectButton;
        public ScrollRect MiscSelection;

        public Button MiracleSelectButton;
        public ScrollRect MiracleSelection;

        public List<GameObject> LoadedIcons = new List<GameObject>();

        private KF3ModelViewerMain _main;

        public void SwitchSpawnerTab(Button button)
        {
            var buttons = new List<Button>() { FriendSelectButton, CeruleanSelectButton, FurnitureSelectButton, MiscSelectButton, MiracleSelectButton };
            var contents = new List<ScrollRect>() { FriendSelection, CeruleanSelection, FurnitureSelection, MiscSelection, MiracleSelection };

            for(int i = 0; i < buttons.Count; i++)
            {
                var value = buttons[i] == button;
                buttons[i].interactable = !value;
                contents[i].gameObject.SetActive(value);
            }
        }

        public IEnumerator LoadAll(KF3ModelViewerMain main)
        {
            _main = main;
            LoadCeruleanIcons();
            _main.StartCoroutine(LoadCharacterIcons());
            _main.StartCoroutine(LoadFurnitureIcons());
            LoadMiscIcons(_main.Assets.GetMisc(), MiscSelection.content);
            LoadMiscIcons(_main.Assets.GetMiracles(), MiracleSelection.content);
            yield break;
        }

        public void FilterIcons(string value)
        {
            if (String.IsNullOrEmpty(value))
            {
                foreach (var icon in LoadedIcons)
                {
                    icon.SetActive(true);
                }
            }
            else foreach (var icon in LoadedIcons)
                {
                    icon.SetActive(icon.GetComponentInChildren<Text>().text.ToUpper().Contains(value.ToUpper()));
                }
        }

        private IEnumerator LoadCharacterIcons()
        {
            var abIcons = _main.Assets.Icons.ToList();
            var abChara = _main.Assets.Characters.ToList();
            int total = abChara.Count;
            var tex2D = Resources.Load(Strings.CharaErrorPrefab) as Texture2D;
            Dictionary<GameObject, KF3AssetBundle> icons = new Dictionary<GameObject, KF3AssetBundle>();

            foreach (var bundle in abChara)
            {
                KF3AssetBundle b = bundle as KF3AssetBundle;
                string id = b.IdStr;
                int idNum = b.IdNum;
                string displayName = id + "_" + KF3Names.GetCharaName(idNum);

                var icon = abIcons.FirstOrDefault(ab => ab.FileName == $"icon_chara_{id}.png");
                if (icon == null)
                {
                    icon = abIcons.FirstOrDefault(ab => ab.FileName == $"icon_chara_mini_{id}.png");
                }

                GameObject go = Instantiate(_main.Resources.ModelIcon, FriendSelection.content.transform);
                go.name = bundle.FileName;
                go.GetComponentInChildren<Text>().text = displayName;
                go.GetComponentInChildren<Button>().onClick.AddListener(() =>
                {
                    _main.StartCoroutine(_main.Builder.BuildCharacter(bundle.FileName, bundle.FileName));
                    Close();
                });

                if (icon != null)
                {
                    icons.Add(go, icon);
                }
                else
                {
                    go.GetComponentInChildren<RawImage>().texture = tex2D;
                }
                LoadedIcons.Add(go);
            }

            foreach (var i in icons)
            {
                var go = i.Key;
                var icon = i.Value;
                yield return _main.Assets.LoadAsset(icon, (ab) => {
                    if (ab != null)
                    {
                        go.GetComponentInChildren<RawImage>().texture = ab.LoadAsset(ab.GetAllAssetNames()[0]) as Texture2D;
                        ab.Unload(false);
                    }
                    else
                    {
                        go.GetComponentInChildren<RawImage>().texture = tex2D;
                    }
                });
            }

            //Error.Log(Color.green, $"Loaded {loaded}/{total} Character Icons");
        }

        private void LoadCeruleanIcons()
        {
            var abCell = _main.Assets.CeruleansD.Select(c => c.Value[0]).ToList();
            var tex2D = Resources.Load(Strings.CharaErrorPrefab) as Texture2D;
            foreach (var bundle in abCell)
            {
                KF3AssetBundle b = bundle;

                GameObject go = Instantiate(_main.Resources.ModelIcon, CeruleanSelection.content.transform);
                go.name = bundle.FileName;
                go.GetComponentInChildren<Text>().text = bundle.DisplayName;
                go.GetComponentInChildren<Button>().onClick.AddListener(() =>
                {
                    _main.StartCoroutine(_main.Builder.BuildCerulean(bundle.FileName, bundle.FileName, null));
                    Close();
                });
                go.GetComponentInChildren<RawImage>().texture = tex2D;
                LoadedIcons.Add(go);
            }
        }

        private void LoadMiscIcons(List<KF3AssetBundle> icons, Transform panel)
        {
            var tex2D = Resources.Load(Strings.CharaErrorPrefab) as Texture2D;
            foreach (var bundle in icons)
            {
                KF3AssetBundle b = bundle;

                GameObject go = Instantiate(_main.Resources.ModelIcon, panel);
                go.name = bundle.FileName;
                go.GetComponentInChildren<Text>().text = bundle.DisplayName;
                go.GetComponentInChildren<Button>().onClick.AddListener(() =>
                {
                    _main.StartCoroutine(_main.Builder.Spawn(bundle));
                    Close();
                });
                go.GetComponentInChildren<RawImage>().texture = tex2D;
                LoadedIcons.Add(go);
            }
        }

        private IEnumerator LoadFurnitureIcons()
        {
            var abIcons = _main.Assets.Icons.ToList();
            var abFurniture = _main.Assets.Furniture.ToList();
            var tex2D = Resources.Load(Strings.CharaErrorPrefab) as Texture2D;
            Dictionary<GameObject, KF3AssetBundle> icons = new Dictionary<GameObject, KF3AssetBundle>();

            foreach (var bundle in abFurniture)
            {
                string name = bundle.FileName;
                string[] split = name.Split(new char[] { '.', '_' });
                string id = "";
                int idNum = -1;
                for (int i = split.Length; i >= 0; i--)
                {
                    id = split[split.Length - 3];
                    if (int.TryParse(id, out idNum))
                    {
                        break;
                    }
                }
                if (idNum == -1)
                {
                    continue;
                }

                var icon = abIcons.FirstOrDefault(ab => ab.FileName == $"icon_item_{id}.png");

                GameObject go = Instantiate(_main.Resources.ModelIcon, FurnitureSelection.content.transform);
                go.name = bundle.FileName;
                go.GetComponentInChildren<Text>().text = bundle.DisplayName;
                go.GetComponentInChildren<Button>().onClick.AddListener(() =>
                {
                    _main.StartCoroutine(_main.Builder.SpawnFurniture(bundle.FileName));
                    Close();
                });
                if (icon != null)
                {
                    icons.Add(go, icon);
                }
                else
                {
                    go.GetComponentInChildren<RawImage>().texture = tex2D;
                }
                LoadedIcons.Add(go);
            }

            foreach (var i in icons)
            {
                var go = i.Key;
                var icon = i.Value;
                yield return _main.Assets.LoadAsset(icon, (ab) => {
                    if (ab == null)
                    {
                        go.GetComponentInChildren<RawImage>().texture = tex2D;
                        return;
                    }
                    go.GetComponentInChildren<RawImage>().texture = ab.LoadAsset(ab.GetAllAssetNames()[0]) as Texture2D;
                    ab.Unload(false);
                });
            }
        }

    }
}
