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

#if USING_TMP
using TMPro;
#endif

namespace SimplifyXR
{
    /// <summary>
    /// For use when externally loading the content of a Basic Step
    /// </summary>
    [DirectiveCategory(DirectiveCategories.Action, DirectiveSubCategory.StepByStep, 
        prettyName ="Load Basic Step Content",
        directiveInfo ="This action will load <b>Basic Step</b> content into specified <b>Text</b>" +
        " or <b>Text Mesh Pro</b> components.")]
    public class LoadBasicStepContent : Actions
    {

        //#if USING_TMP
        /// <summary>
        /// Text field type to use 
        /// </summary>
#if UNITY_EDITOR
        [Tooltip("Type of text object")]
        //#endif
#endif

        public TextType textType;



        /// <summary>
        /// Text field for title of the step
        /// </summary>
#if UNITY_EDITOR
        [Tooltip("Text field for title of the step"),
            Conditional("textType", TextType.Standard, ComparisonType.Equals), Required]
#endif
        public Text StepTitle;
        /// <summary>
        /// Text field for title of the step instruction
        /// </summary>


#if UNITY_EDITOR
        [Tooltip("Text field for title of the step instruction"),
            Conditional("textType", TextType.Standard, ComparisonType.Equals), Required]
#endif
        public Text TitleOfInstruction;
        /// <summary>
        /// Text field for instruction
        /// </summary>

#if UNITY_EDITOR
        [Tooltip("Text field for instruction"),
            Conditional("textType", TextType.Standard, ComparisonType.Equals), Required]
#endif
        public Text Instruction;
        /// <summary>
        /// The step to load
        /// </summary>
        /// 
#if USING_TMP

#if UNITY_EDITOR
        [Tooltip("Text Mesh Pro field for title of the step instruction"),
            Conditional("textType", TextType.TextMeshProUGUI, ComparisonType.Equals), Required]
#endif
        public TextMeshProUGUI TMPStepTitleUGUI;
        /// <summary>
        /// Text field for instruction
        /// </summary>

#if UNITY_EDITOR
        [Tooltip("Text Mesh Pro field for title of the step instruction"),
            Conditional("textType", TextType.TextMeshProUGUI, ComparisonType.Equals), Required]
#endif
        public TextMeshProUGUI TMPTitleOfInstructionUGUI;
        /// <summary>
        /// Text field for instruction
        /// </summary>

#if UNITY_EDITOR
        [Tooltip("Text field for instruction"),
            Conditional("textType", TextType.TextMeshProUGUI, ComparisonType.Equals), Required]
#endif
        public TextMeshProUGUI TMPInstructionUGUI;

#if UNITY_EDITOR
        [Tooltip("Text Mesh Pro field for title of the step instruction"),
            Conditional("textType", TextType.TextMeshPro, ComparisonType.Equals), Required]
#endif
        public TextMeshPro TMPStepTitle;
        /// <summary>
        /// Text field for instruction
        /// </summary>

#if UNITY_EDITOR
        [Tooltip("Text Mesh Pro field for title of the step instruction"),
            Conditional("textType", TextType.TextMeshPro, ComparisonType.Equals), Required]
#endif
        public TextMeshPro TMPTitleOfInstruction;
        /// <summary>
        /// Text field for instruction
        /// </summary>

#if UNITY_EDITOR
        [Tooltip("Text field for instruction"),
            Conditional("textType", TextType.TextMeshPro, ComparisonType.Equals), Required]
#endif
        public TextMeshPro TMPInstruction;
        /// <summary>
        /// The step to load
        /// </summary>
#endif
        protected string step;
        /// <summary>
        /// Base Step Loader
        /// </summary>
        protected ILoadStepContent stepLoader;

        public override List<KnobKeywords> ReceiveKeywords()
        {
            return new List<KnobKeywords> { new KnobKeywords("StepLabel", typeof(string)) };
        }

        public override List<KnobKeywords> SendKeywords()
        {
            return new List<KnobKeywords> { new KnobKeywords("StepLabel", typeof(string)) };
        }

        public override void Execute()
        {
            GetPassedStepName();
            LoadContent();
            SendStepName();
            step = null;
            ThisActionCompleted();
        }

        /// <summary>
        /// Get the step to be loaded if sent.
        /// </summary>
        protected void GetPassedStepName()
        {
            var objectPassed = GetPassableData();
            if (objectPassed == null) return;

            if (KeywordInUse == "StepLabel")
            {
                var _name = objectPassed as string;
                if (!string.IsNullOrEmpty(_name))
                    step = _name;
            }
        }

        /// <summary>
        /// Get the Step Loader and load it's content
        /// </summary>
        protected void LoadContent()
        {
            stepLoader = new BasicStepLoader();
            if (stepLoader.StepTypeCheck())
            {
                if (!string.IsNullOrEmpty(step))
                {
                    if (stepLoader.LoadStepContent(step))
                        SimplifyXRDebug.SimplifyXRLog(SimplifyXRDebug.Type.DeveloperDeepDebug,
                            "Loading content from Step Loader for step: {0}", SimplifyXRDebug.Args(step));
                    else
                    {
                        SimplifyXRDebug.SimplifyXRLog(SimplifyXRDebug.Type.Warning, 
                            "Could not load content from Step Loader for step: {0}", SimplifyXRDebug.Args(step));
                        return;
                    }
                }
                else
                {
                    if (stepLoader.LoadStepContent())
                        SimplifyXRDebug.SimplifyXRLog(SimplifyXRDebug.Type.DeveloperDeepDebug,
                            "Loading content from Step Loader for the current step in the Step Manager.");
                    else
                    {
                        SimplifyXRDebug.SimplifyXRLog(SimplifyXRDebug.Type.Warning, 
                            "Could not load content from Step Loader for the current step in the Step Manager.");
                        return;
                    }
                }
                DisplayContent();
            }
            else
                SimplifyXRDebug.SimplifyXRLog(SimplifyXRDebug.Type.DeveloperDeepDebug,
                    "Not using this Step Content Loader Action. No step content will be loaded with {0}.", SimplifyXRDebug.Args(this));
        }

        /// <summary>
        /// Display the content in the fields
        /// </summary>
        protected void DisplayContent()
        {
            DisplayContentAbstract<BasicStepLoader>();
        }

        public void DisplayContentAbstract<T>() where T : ILoadBasicContent

        {
            step = stepLoader.StepLabel;

            switch (textType)
            {
                case TextType.Standard:
                    DisplayStandardContent<T>();
                    break;
#if USING_TMP
                case TextType.TextMeshPro:
                    DisplayTMPContent<T>();
                    break;
                case TextType.TextMeshProUGUI:
                    DisplayTMPUGUIContent<T>();
                    break;
#endif
            }
        }

#if USING_TMP
        protected void DisplayTMPContent<T>() where T : ILoadBasicContent
        {
            // Cast the new step loader to the correct type
            var newLoader = (T)stepLoader;

            if (TMPStepTitle != null)
            {
                if (!string.IsNullOrEmpty(newLoader.StepTitle))
                    TMPStepTitle.text = newLoader.StepTitle;
                else
                    TMPStepTitle.text = "";
            }

            if (TMPTitleOfInstruction != null)
            {
                if (!string.IsNullOrEmpty(newLoader.Title))
                    TMPTitleOfInstruction.text = newLoader.Title;
                else
                    TMPTitleOfInstruction.text = "";
            }

            if (TMPInstruction != null)
            {
                if (!string.IsNullOrEmpty(newLoader.Instruction))
                    TMPInstruction.text = newLoader.Instruction;
                else
                    TMPInstruction.text = "";
            }
        }

        protected void DisplayTMPUGUIContent<T>() where T : ILoadBasicContent
        {
            // Cast the new step loader to the correct type
            var newLoader = (T)stepLoader;

            if (TMPStepTitleUGUI != null)
            {
                if (!string.IsNullOrEmpty(newLoader.StepTitle))
                    TMPStepTitleUGUI.text = newLoader.StepTitle;
                else
                    TMPStepTitleUGUI.text = "";
            }

            if (TMPTitleOfInstructionUGUI != null)
            {
                if (!string.IsNullOrEmpty(newLoader.Title))
                    TMPTitleOfInstructionUGUI.text = newLoader.Title;
                else
                    TMPTitleOfInstructionUGUI.text = "";
            }

            if (TMPInstructionUGUI != null)
            {
                if (!string.IsNullOrEmpty(newLoader.Instruction))
                    TMPInstructionUGUI.text = newLoader.Instruction;
                else
                    TMPInstructionUGUI.text = "";
            }
        }

#endif


        protected void DisplayStandardContent<T>() where T : ILoadBasicContent
        {
            // Cast the new step loader to the correct type
            var newLoader = (T)stepLoader;

            if (StepTitle != null)
            {
                if (!string.IsNullOrEmpty(newLoader.StepTitle))
                    StepTitle.text = newLoader.StepTitle;
                else
                    StepTitle.text = "";
            }

            if (TitleOfInstruction != null)
            {
                if (!string.IsNullOrEmpty(newLoader.Title))
                    TitleOfInstruction.text = newLoader.Title;
                else
                    TitleOfInstruction.text = "";
            }

            if (Instruction != null)
            {
                if (!string.IsNullOrEmpty(newLoader.Instruction))
                    Instruction.text = newLoader.Instruction;
                else
                    Instruction.text = "";
            }
        }



        /// <summary>
        /// Pass along the loaded step name
        /// </summary>
        protected void SendStepName()
        {
            if (!string.IsNullOrEmpty(step))
            {
                AddPassableData(new List<string> { "StepLabel" }, new List<object> { step });
            }
        }
    }
}