using System.Collections;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using Cysharp.Threading.Tasks;
using Proyecto26;

using UnityEngine;
using UnityEngine.InputSystem.UI;
namespace XenseAR
{

    public class AnchoringManager : MonoBehaviour
    {
        [SerializeField] DataScriptableObject sessionDataObject;
        [SerializeField] AppSettingObject appSetting;
        List<AnchoringTarget> additionalTarget = new List<AnchoringTarget>();

        //[SerializeField] GameObject megaBlocks;

        DataLoader loader;
        private bool hasLoad = false;
        private bool onLoading = false;
        private string blockId;
        private void Awake()
        {
            Container.Register(this);
        }

        private void OnHandleLoadTargets(List<AnchoringTarget> targets)
        {
            additionalTarget = targets;
            if (hasLoad == false) return;

            LoadTargets();
        }

        private async void Start()
        {
            if (loader == null) loader = new DataLoader();
            loader.SetAnchoringRoot(sessionDataObject);
            await Task.Yield();
#if UNITY_WEBGL
            API.InitWebGLSender();
            await LoadBlockData(true); // in case webgl load all as soon as possible to avoid jitter
#else
            await LoadBlockData(false); // load json anchoring data
#endif

        }

        private void OnDestroy()
        {
            foreach (var label in LabelManager.Instance.Labels)
            {
                label.OnLoadAnchor -= OnloadAnchor;
            }
        }

        void LoadTargets()
        {
            if (additionalTarget.Count > 0)
                loader.SpawnAnchoringTarget(appSetting.LocationSetting.blockId, additionalTarget);
            additionalTarget.Clear();
        }

        public async Task StartLoadAsync()
        {
            if (hasLoad) return;
            if (onLoading) return;

            onLoading = true;
            await LoadBlockData(true); // load and spawn anchoring data when location found
            onLoading = false;
            hasLoad = true;
            LoadTargets();
        }

        int assetBundleNum = 0;
        int bundleLoadedCount = 0;
        public async Task<bool> LoadBlockData(bool spawnTarget = true)
        {

            await UniTask.Delay(100);
            if (sessionDataObject == null) return false;
            if (loader == null) return false;
            var BlockInfos = FindObjectsOfType<ARWorldBlockInfo>();


            bool ret = false;
            if (loader.isEdit)
            {
                if (BlockInfos.Length > 0)
                {
                    BackendServices.Instance.Post(new RequestHelper
                    {
                        SimpleForm = new Dictionary<string, string>()
                    {
                        {"type","GetWorldSpaceByBlockId" },
                        {"BlockID", BlockInfos[0].GetInfo().ID},
                    },
                        //            Uri = "",
                    }).Then(res => OnFinishGetWorldSpace(res, BlockInfos[0]));
                    ret = true;
                }
            }
            else
            {
                assetBundleNum = 0;
                bundleLoadedCount = 0;
                ret = await loader.LoadAnchoringFromEdu(
                    appSetting.LocationSetting.blockId, appSetting.WorldId, spawnTarget);
                assetBundleNum = LabelManager.Instance.Labels.Where(x => x.GetType() == AnchoringMediaType.Assetbundle).Count();
                foreach (var label in LabelManager.Instance.Labels)
                {
                    Debug.Log("add event " + label.LabelObject.name);
                    label.OnLoadAnchor -= OnloadAnchor;
                    label.OnLoadAnchor += OnloadAnchor;
                }

            }
            Debug.Log("load block anchoring target");
            return ret;
        }

        // This is for preloading asset bundles in WebGL to avoid jitter during runtime loading.
        private void OnloadAnchor(IAnchoringLabel label)
        {
            if (label.GetType() == AnchoringMediaType.Assetbundle)
            {
                bundleLoadedCount++;
                float percentage = (float)bundleLoadedCount / assetBundleNum * 100;
                API.UpdateAnchoringDownloadProgress(percentage.ToString());
            }
        }

        private void OnFinishGetWorldSpace(ResponseHelper res, ARWorldBlockInfo blockInfo)
        {
            List<WorldData> worldDatas = JsonUtility.FromJson<BlockWorldsData>(res.Text).data;

            WorldSelector worldSelector = blockInfo.gameObject.AddComponent<WorldSelector>();
            worldSelector.Init(loader, worldDatas, blockInfo.GetInfo().ID, sessionDataObject);
        }
    }
}
