using System;
using UnityEngine;
using RKOKO.Config.Free;

#if UNITY_EDITOR
using UnityEditor;
#endif

namespace RKOKO.Config
{
    /// <summary>
    /// Default runtime config tables entry.
    /// JSON_LOAD_PATH should be replaced with the actual Resources.Load path (without file extension).
    /// JSON_ASSET_PATH should be replaced with the actual Unity asset path.
    /// JSON_AES_KEY should be replaced with the actual json aes key.
    /// ENABLE_RUNTIME_RESOURCES_LOAD should be replaced with true or false.
    /// ERROR_RUNTIME_LOAD_DISABLED should be replaced with the localized error message.
    /// </summary>
    public static class ConfigTables
    {
        private static AllTables _data;

        private const bool ENABLE_RUNTIME_RESOURCES_LOAD = $ENABLE_RUNTIME_RESOURCES_LOAD$;

        public static AllTables Data
        {
            get
            {
                if (_data == null)
                {
                    string json = LoadJsonText();
                    _data = ParseJson(json);
                }

                return _data;
            }
        }

        public static void Reload()
        {
            _data = null;
        }

        /// <summary>
        /// Build config tables from raw json string.
        /// Useful when loading json from a custom path instead of the default Resources path.
        /// </summary>
        public static void Build(string json)
        {
            if (string.IsNullOrWhiteSpace(json))
            {
                throw new Exception("Build failed: json is null or empty.");
            }

            _data = ParseJson(json);
        }

        /// <summary>
        /// Build config tables from a TextAsset.
        /// Useful when using a custom TextAsset instead of the default Resources path.
        /// </summary>
        public static void Build(TextAsset textAsset)
        {
            if (textAsset == null)
            {
                throw new Exception("Build failed: textAsset is null.");
            }

            _data = ParseJson(textAsset.text);
        }

        private static string LoadJsonText()
        {
#if UNITY_EDITOR
            if (!EditorApplication.isPlaying)
            {
                var editorTextAsset = AssetDatabase.LoadAssetAtPath<TextAsset>("$JSON_ASSET_PATH$");
                if (editorTextAsset == null)
                {
                    throw new Exception(
                        "Config json not found in editor.\n" +
                        "Please check the asset path:\n$JSON_ASSET_PATH$");
                }

                return editorTextAsset.text;
            }
#endif

            if (!ENABLE_RUNTIME_RESOURCES_LOAD)
            {
                throw new Exception("$ERROR_RUNTIME_LOAD_DISABLED$");
            }

            var runtimeTextAsset = Resources.Load<TextAsset>("$JSON_LOAD_PATH$");
            if (runtimeTextAsset == null)
            {
                throw new Exception(
                    "Config json not found at runtime.\n" +
                    "Please check the Resources path:\n$JSON_LOAD_PATH$");
            }

            return runtimeTextAsset.text;
        }

        private static AllTables ParseJson(string json)
        {
            if (string.IsNullOrWhiteSpace(json))
            {
                throw new Exception("Config json is null or empty.");
            }

            if (RkokoAesUtility.IsEncryptedText(json))
            {
                json = RkokoAesUtility.DecryptString(json, "$JSON_AES_KEY$");
            }

            return AllTables.FromJson(json);
        }
    }
}