﻿using System;
using System.Collections.Generic;
using JLGames.RocketDriver.Actions.Loaderx;
using UnityEngine;

namespace JLGames.RocketDriver.Games.PanelManager
{
    public sealed class PanelLoader : IPanelLoaderAdapter
    {
        private readonly List<string> m_ListBundle = new List<string>();
        private readonly List<GameObject> m_ListDisplay = new List<GameObject>();

        public void LoadSprite(string bundleName, string assetPath, PanelLoaderDelegate.OnSpriteLoaded onSpriteLoaded)
        {
            Loader.LoadBundleAsync(bundleName, (bundleRef, suc) =>
            {
                if (!suc)
                {
                    onSpriteLoaded.Invoke(null, false);
                    return;
                }

                var sprite = Loader.LoadAssetSync<Sprite>(assetPath, bundleRef.Bundle);
                if (null == sprite)
                {
                    onSpriteLoaded.Invoke(null, false);
                    return;
                }

                onSpriteLoaded.Invoke(sprite, true);
            });
        }

        public void LoadPanelAsset(IPanelAssetSettings assetInfo, PanelLoaderDelegate.OnPanelLoaded onPanelLoaded)
        {
            Loader.LoadBundleAsync(assetInfo.BundleName, (bundleRef, suc) =>
            {
                if (!suc)
                {
                    onPanelLoaded.Invoke(null, false);
                    return;
                }

                var p = GenDisplayPanel(bundleRef, assetInfo);
                onPanelLoaded.Invoke(p, true);
            });
        }

        public void LoadPanelsAssets(IEnumerable<IPanelAssetSettings> assetInfos, PanelLoaderDelegate.OnPanelsLoaded onPanelsLoaded)
        {
            var abs = GetBundleList(assetInfos);
            if (null == abs || abs.Length == 0)
            {
                onPanelsLoaded.Invoke(null, false);
                return;
            }

            Loader.LoadMultiBundleAsync(abs, (bundleRefs, suc) =>
            {
                if (!suc)
                {
                    onPanelsLoaded.Invoke(null, false);
                    return;
                }

                var ps = GenDisplayPanels(bundleRefs, assetInfos);
                onPanelsLoaded.Invoke(ps, true);
            });
        }

        private GameObject GenDisplayPanel(BundleRef abRef, IPanelAssetSettings assetInfo)
        {
            var prefab = Loader.LoadAssetSync<GameObject>(assetInfo.AssetPath, abRef.Bundle);
            if (null == prefab) return null;
            return UnityEngine.Object.Instantiate(prefab);
        }

        private GameObject[] GenDisplayPanels(BundleRef[] abs, IEnumerable<IPanelAssetSettings> assetInfos)
        {
            if (null == assetInfos) return null;
            m_ListDisplay.Clear();
            foreach (var info in assetInfos)
            {
                var ab = FindBundleRef(abs, info.BundleName);
                var display = GenDisplayPanel(ab, info);
                m_ListDisplay.Add(display);
            }

            var rs = m_ListDisplay.ToArray();
            m_ListDisplay.Clear();
            return rs;
        }

        private static BundleRef FindBundleRef(BundleRef[] abs, string abName)
        {
            if (null == abs || string.IsNullOrEmpty(abName)) return null;
            return Array.Find(abs, bundle => bundle?.BundleName == abName);
        }

        private string[] GetBundleList(IEnumerable<IPanelAssetSettings> assetInfos)
        {
            if (null == assetInfos) return null;
            m_ListBundle.Clear();
            foreach (var info in assetInfos)
            {
                if (m_ListBundle.Contains(info.BundleName))
                {
                    continue;
                }

                m_ListBundle.Add(info.BundleName);
            }

            return m_ListBundle.ToArray();
        }
    }
}