using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;
using System;
using TMPro;
using UnityEngine.Events;
using UnityEngine.SceneManagement;

namespace XenseAR
{
    public class loadingProgress_v2 : MonoBehaviour
    {
        private static loadingProgress_v2 _instance;

        [SerializeField] Image ProgressImage;
        [SerializeField] Image AppLogo;
        [SerializeField] Text ProgressText;
        [SerializeField] TextMeshProUGUI StatusText;
        [SerializeField] Text CountingText;
        [SerializeField] Button CancelLoadingBtn;

        [SerializeField] GameObject ViewPort;
        [SerializeField] GameObject LoadingBar;
        [SerializeField] GameObject ProgressTotalImage;

        public UnityEvent Oncancel;

        private ProgressBar progressBar;

        private bool allowCreateLoadingBar = true;

        private Dictionary<string, ProgressBar> progressBarDictionary = new Dictionary<string, ProgressBar>();

        public float percentage;
        private int assetIndex = 0;
        private int assetNums = 1;
        private int currentIndex = 0;
        private bool cancelLoading = false;
        private bool isShow;
        static string lastSceneName = "";
        private void Awake()
        {
            _instance = this;
        }
        void Init()
        {
            _instance.GetComponent<RectTransform>().localPosition = Vector3.zero;
            ProgressImage.fillAmount = 0;
        }
        // Start is called before the first frame update
        void Start()
        {
            Debug.Log("Start create loading progress");
            allowCreateLoadingBar = true;
            Init();
            CancelLoadingBtn.onClick.AddListener(OnCancelClick);
        }

        private void OnDestroy()
        {
            progressBarDictionary.Clear();
            CancelLoadingBtn.onClick.RemoveListener(OnCancelClick);
        }

        public void AllowCreateLoadingBar(bool allow)
        {
            allowCreateLoadingBar = allow;
        }

        // Update is called once per frame
        void Update()
        {
            int a = 0;
            if (assetNums >= 1)
            {
                if (assetNums == 1)
                {
                    ProgressImage.fillAmount = percentage;
                }
                else
                {
                    if (assetIndex != currentIndex)
                    {
                        currentIndex = assetIndex;
                        percentage = 0;
                    }
                    ProgressImage.fillAmount = (percentage + assetIndex * 1.0f) / assetNums;
                }

                a = (int)(ProgressImage.fillAmount * 100);
                ProgressText.text = a + "%";

            }
        }

        public static loadingProgress_v2 destroyInstance;

        public static loadingProgress_v2 instance
        {
            get
            {
                if (_instance != null)
                {
                    if (lastSceneName == SceneManager.GetActiveScene().name)
                        return _instance;

                    GameObject canvas = GameObject.FindGameObjectWithTag("MainCanvas");
                    _instance.transform.parent = canvas.transform;
                    _instance.transform.localScale = Vector3.one;
                    _instance.transform.localPosition = Vector3.zero;
                    //SetTransformValue(_instance.gameObject.GetComponent<RectTransform>());
                    float height = canvas.GetComponent<RectTransform>().rect.height;
                    float width = canvas.GetComponent<RectTransform>().rect.width;
                    _instance.gameObject.GetComponent<RectTransform>().SetSizeWithCurrentAnchors(RectTransform.Axis.Vertical, height);
                    _instance.gameObject.GetComponent<RectTransform>().SetSizeWithCurrentAnchors(RectTransform.Axis.Horizontal, width);
                    lastSceneName = SceneManager.GetActiveScene().name;
                    return _instance;
                }
                else
                {
                    GameObject resource = Resources.Load<GameObject>(Defines.PrefabResourceURL.LoadingPrefab);
                    GameObject canvas = GameObject.FindGameObjectWithTag("MainCanvas");
                    GameObject gameObject = Instantiate<GameObject>(resource, canvas.transform);
                    float spacing = gameObject.transform.GetChild(0).GetComponent<VerticalLayoutGroup>().spacing;
                    if (canvas.name == "Canvas Moble" && !spacing.Equals(15f))
                        gameObject.transform.GetChild(0).GetComponent<VerticalLayoutGroup>().spacing = 15f;
                    if (canvas.name != "Canvas Moble" && !spacing.Equals(30f))
                        gameObject.transform.GetChild(0).GetComponent<VerticalLayoutGroup>().spacing = 30f;
                    gameObject.transform.localPosition = Vector3.zero;
                    _instance = gameObject.GetComponent<loadingProgress_v2>();
                    lastSceneName = SceneManager.GetActiveScene().name;
                    return _instance;
                }
            }
        }


        public void CreateLoadingBar(string uniqueKey, string name)
        {
            if (allowCreateLoadingBar)
            {
                GameObject loadingbar = Instantiate(LoadingBar, ViewPort.transform);
                progressBar = loadingbar.GetComponent<ProgressBar>();
                progressBar.UpdateName(name);
                progressBarDictionary[uniqueKey] = progressBar;
            }
        }

        public void DestroyLoadingBar(string uniqueKey)
        {
            if (progressBarDictionary.TryGetValue(uniqueKey, out ProgressBar value) && progressBarDictionary[uniqueKey] != null)
                progressBarDictionary[uniqueKey].DestroyLoadBar();
        }

        public void CleanAllBar()
        {
            int childCount = ViewPort.transform.childCount;
            for (int i = childCount - 1; i >= 0; i--)
            {
                Transform child = ViewPort.transform.GetChild(i);
                Destroy(child.gameObject);
            }
        }

        public void UpdateLoadingBarProgress(string uniqueKey, float progress)
        {
            if (!progressBarDictionary.ContainsKey(uniqueKey)) return;
            if (progressBarDictionary.TryGetValue(uniqueKey, out ProgressBar value) && progressBarDictionary[uniqueKey] != null)
                progressBarDictionary[uniqueKey].UpdatePercentage(progress);
        }

        public void ShowLoading(bool withBackground = true, string statusString = "Loading Model")
        {
            if (withBackground)
            {
                AppLogo.gameObject.SetActive(true);
                ProgressTotalImage.SetActive(false);
                gameObject.GetComponent<Image>().color = new Color32(255, 255, 255, 255);
                //SetlessonName("model");
                CountingText.gameObject.SetActive(false);
            }
            else
            {
                AppLogo.gameObject.SetActive(false);
                ProgressTotalImage.SetActive(true);
                gameObject.GetComponent<Image>().color = new Color32(255, 255, 255, 0);
                CountingText.gameObject.SetActive(false);
                Debug.Log("Show loading without background");
            }
            SetStatusText(statusString);
            cancelLoading = false;
            isShow = true;
            Debug.Log("show loading");
            _instance.gameObject.SetActive(true);
        }

        public void HideLoading()
        {
            isShow = false;
            Oncancel.RemoveAllListeners();
            HideCancelButton();
            Clean();
            Debug.Log("Hide loading");
            _instance.gameObject.SetActive(false);
            CleanAllBar();
            allowCreateLoadingBar = false;
        }

        public void SetCountingText(string text)
        {
            CountingText.text = text;
        }

        public void ShowCancelButton()
        {
            cancelLoading = false;
            CancelLoadingBtn.gameObject.SetActive(true);
        }

        private void OnCancelClick()
        {
            SetCountingText("Cancelling");
            Oncancel?.Invoke();
            cancelLoading = true;
            HideCancelButton();
            //HideLoading();
        }

        public void HideCancelButton()
        {
            CancelLoadingBtn.gameObject.SetActive(false);
        }

        public void UpdatePercentage(float loaded)
        {
            // hot fix for wrong percentage
            if (loaded == 1)
                percentage = 0;
            else if (loaded >= percentage)
                percentage = loaded;
            else if (loaded == 0)
                percentage = 0;
        }

        public void UpdateAssetNums(int num)
        {
            assetIndex = 0;
            currentIndex = 0;
            assetNums = num;
        }

        public void UpdateAssetIndex(int idx)
        {
            assetIndex = idx;
        }

        public void SetStatusText(string text)
        {
            StatusText.text = text;
        }

        public void Clean()
        {
            StatusText.text = "";
            CountingText.text = "";
            assetIndex = 1;
            assetNums = 1;
            percentage = 0;
            ProgressImage.fillAmount = 0;
            ProgressText.text = "";
        }

        public bool IsCancel()
        {
            return cancelLoading;
        }

        public bool IsShow()
        {
            return isShow;
        }

        public void SetProgressTotalImage(bool isActive)
        {
            ProgressTotalImage.SetActive(isActive);
        }

        public void SetAppLogo(bool isActive)
        {
            AppLogo.gameObject.SetActive(isActive);
        }
    }
}
