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

using static Chibi.Free.Dialog;

namespace XenseAR
{
    public class PopupDialog : MonoBehaviour
    {

        public static PopupDialog destroyInstance;
        static string lastSceneName = "";

        private static PopupDialog _instance;
        public Chibi.Free.Dialog dialog;

        [SerializeField] RawImage questionIcon;
        [SerializeField] GameObject notificationIcon;
        public RectTransform scaleBG;
        Image backGround;
        public DialogType dialogType;
        public DialogInfo dialogInfo;
        Texture defaultQuestionIcon;
        Color defaultBackgroundColor;
        public enum DialogType
        {
            NOTIFICATION,
            QUESTION,
        }

        public enum DialogTemplate
        {
            Notification,
            Question,
        }

        public struct DialogInfo
        {
            public string title;
            public string message;
            public Sprite icon;
            public string rewardScore;
            public DialogType type;
        }

        public static PopupDialog 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;
                    lastSceneName = SceneManager.GetActiveScene().name;
                    return _instance;
                }
                else
                {
                    GameObject resource = Resources.Load<GameObject>(Defines.PrefabResourceURL.PopupDialog);
                    GameObject gameObject = Instantiate<GameObject>(resource, GameObject.FindGameObjectWithTag("MainCanvas").transform);
                    gameObject.transform.localPosition = Vector3.zero;
                    _instance = gameObject.GetComponent<PopupDialog>();
                    lastSceneName = SceneManager.GetActiveScene().name;
                    return _instance;
                }
            }
        }

        private void Start()
        {
            Init();
        }

        void Init()
        {
            Debug.Log("scale factor:" + GameObject.FindGameObjectWithTag("MainCanvas").GetComponent<RectTransform>().localScale.x);
            _instance.GetComponent<RectTransform>().localPosition = Vector3.zero;
            _instance.transform.GetComponent<RectTransform>().localScale = Vector3.one;
        }


        private void Awake()
        {
            defaultQuestionIcon = questionIcon.texture;
            backGround = scaleBG.GetComponent<Image>();
            defaultBackgroundColor = backGround.color;
            _instance = this;
            //DontDestroyOnLoad(this);
        }

        private void GoOnTop()
        {
            int totalUI = _instance.gameObject.transform.parent.childCount;
            _instance.gameObject.transform.SetSiblingIndex(totalUI - 1);
        }

        public void showDialog(DialogTemplate template, string message, float delayHide)
        {
            showButtonDialog(template, message, null, null, null, null, null, delayHide);
        }

        public void showButtonDialog(DialogTemplate template, string message, string buttonText,
            Action buttonCallback = null, Color? backgroundColors = null, Color? textColors = null, Color? outlineColors = null, float delayHide = 0f)
        {
            if (string.IsNullOrEmpty(message) && delayHide == 0f)
            {
                Debug.LogError("Popup block error");
                return;
            }

            if (string.IsNullOrEmpty(message)) showButtonsDialog(template, message, null, null, null, null, null, null, null, delayHide);
            else showButtonsDialog(template, message, new List<string> { buttonText }, new List<Action> { buttonCallback }, new List<Color?> { backgroundColors },
                new List<Color?> { textColors }, new List<Color?> { outlineColors }, null, null, delayHide);
        }

        public void showButtonsDialog(DialogTemplate template, string message, List<string> messages,
            List<Action> actions = null, List<Color?> buttonBackgroundColors = null, List<Color?> textColors = null,
            List<Color?> outlineColors = null, Texture questionIconTexture = null, Color? backgroundColor = null, float delayHide = 0f)
        {
            GoOnTop();

            dialogInfo = new DialogInfo();
            switch (template)
            {
                case DialogTemplate.Notification:
                    notificationIcon.SetActive(true);
                    questionIcon.gameObject.SetActive(false);
                    dialogInfo.rewardScore = "";
                    dialogInfo.message = message;
                    dialogInfo.type = DialogType.NOTIFICATION;
                    break;
                case DialogTemplate.Question:
                    notificationIcon.SetActive(false);
                    questionIcon.gameObject.SetActive(true);
                    dialogInfo.rewardScore = "";
                    dialogInfo.message = message;
                    dialogInfo.type = DialogType.QUESTION;
                    break;
            }

            List<ActionButton> actionButtons = new List<ActionButton>();

            if (actions == null) actions = new List<Action>();
            if (buttonBackgroundColors == null) buttonBackgroundColors = new List<Color?>();
            if (textColors == null) textColors = new List<Color?>();
            if (outlineColors == null) outlineColors = new List<Color?>();
            if (questionIconTexture == null) questionIcon.texture = defaultQuestionIcon;
            else
            {
                questionIcon.texture = questionIconTexture;
            }

            RectTransform questionRect = questionIcon.GetComponent<RectTransform>();
            questionRect.sizeDelta = new Vector2(questionRect.sizeDelta.x, questionRect.sizeDelta.x * questionIcon.texture.height / questionIcon.texture.width);

            if (backgroundColor == null) backGround.color = defaultBackgroundColor;
            else
            {
                backGround.color = backgroundColor ?? defaultBackgroundColor;
            }

            while (messages.Count > actions.Count)
            {
                actions.Add(null);
            }

            while (messages.Count > buttonBackgroundColors.Count)
            {
                buttonBackgroundColors.Add(new Color32(181, 16, 0, 255));
            }

            while (messages.Count > textColors.Count)
            {
                textColors.Add(null);
            }

            while (messages.Count > outlineColors.Count)
            {
                outlineColors.Add(null);
            }

            for (int i = 0; i < messages.Count; i++)
            {
                actionButtons.Add(new ActionButton
                    (messages[i],
                    actions[i],
                    buttonBackgroundColors[i],
                    textColors[i],
                    outlineColors[i]
                ));
            }

            showDialog(actionButtons, delayHide);
        }

        void showDialog(List<ActionButton> actionButtons = null, float delayHide = 0f)
        {
            DeactivateDialog();
            CancelInvoke("DeactivateDialog");
            dialog.Init();

            if (actionButtons == null || actionButtons.Count == 0) ActivateDialog();
            else ActivateDialog(actionButtons.ToArray());
            if (delayHide > 0f)
            {
                Invoke("DeactivateDialog", delayHide);
            }

        }

        public void DeactivateDialog()
        {
            dialog.HideDialog();
        }

        public void ActivateDialog(ActionButton[] actionButtons = null)
        {
            dialog.ShowDialog(dialogInfo.title, dialogInfo.message, dialogInfo.icon, dialogInfo.rewardScore, actionButtons);
            UpdateLayout();
        }

        private void UpdateLayout()
        {
            var vLayout = scaleBG.transform.Find("imgFrame/VLayout").GetComponent<VerticalLayoutGroup>();
            var Vchildren = vLayout.GetComponentsInChildren<LayoutGroup>();
            foreach (var item in Vchildren)
            {
                LayoutRebuilder.ForceRebuildLayoutImmediate(item.GetComponent<RectTransform>());
            }
            var parent = vLayout.GetComponentInParent<LayoutGroup>(true);
            if (parent != null) LayoutRebuilder.ForceRebuildLayoutImmediate(parent.GetComponent<RectTransform>());
            LayoutRebuilder.ForceRebuildLayoutImmediate(scaleBG);
        }
    }
}