﻿using System;
using JLGames.RocketDriver.CSharp.Utils;
using UnityEngine;

namespace JLGames.RocketDriver.Actions.Loaderx
{
    [CreateAssetMenu(fileName = "LoaderSettings", menuName = "RocketDriver/Loader Settings", order = 0)]
    public class LoaderSettings : ScriptableObject
    {
        [Serializable]
        public enum LoaderRunMode
        {
            Debug,
            Release
        }

        [Serializable]
        public enum LoaderAssetMode
        {
            Editor,
            Resources,
            Bundle,
        }

        [SerializeField] private LoaderRunMode m_RunMode = LoaderRunMode.Debug;
        [SerializeField] private LoaderAssetMode[] m_AssetMode = {LoaderAssetMode.Editor, LoaderAssetMode.Bundle};
        [SerializeField] private ScriptableObject m_EditorSettings;
        [SerializeField] private ScriptableObject[] m_DebugSettings;
        [SerializeField] private ScriptableObject[] m_ReleaseSettings;

        /// <summary>
        /// Running mode
        /// 运行模式
        /// </summary>
        public LoaderRunMode RunMode => m_RunMode;

#if UNITY_EDITOR
        public void SetRunMode(LoaderRunMode runMode)
        {
            m_RunMode = runMode;
        }
#endif

        /// <summary>
        /// Loading mode
        /// 资源加载模式
        /// </summary>
        public LoaderAssetMode DefaultLoadMode => m_AssetMode[(int) m_RunMode];

        // Debug or Editor 调试级资源配置 ------------------
        
        public EditorSettings EditorSettingDebug =>
            GetSettings<EditorSettings>(LoaderRunMode.Debug, LoaderAssetMode.Editor);

        public ResourceSettings ResourceSettingDebug =>
            GetSettings<ResourceSettings>(LoaderRunMode.Debug, LoaderAssetMode.Resources);

        public BundleSettings BundleSettingDebug =>
            GetSettings<BundleSettings>(LoaderRunMode.Debug, LoaderAssetMode.Bundle);

        // Release 正式级资源配置 ------------------
        
        public ResourceSettings ResourceSettingRelease =>
            GetSettings<ResourceSettings>(LoaderRunMode.Release, LoaderAssetMode.Resources);

        public BundleSettings BundleSettingRelease =>
            GetSettings<BundleSettings>(LoaderRunMode.Release, LoaderAssetMode.Bundle);

        // The following is the configuration after judgment
        // 以下为经过判断后的配置

        public EditorSettings DefaultEditorSetting =>
            GetSettings<EditorSettings>(LoaderRunMode.Debug, LoaderAssetMode.Editor);

        public ResourceSettings DefaultResourceSetting =>
            GetSettings<ResourceSettings>(m_RunMode, LoaderAssetMode.Resources);

        public BundleSettings DefaultBundleSetting => GetSettings<BundleSettings>(m_RunMode, LoaderAssetMode.Bundle);

        public ScriptableObject[] Settings =>
            ArrayUtil.ConcatArray(ArrayUtil.MergeArray(m_DebugSettings, m_ReleaseSettings), m_EditorSettings);

        private T GetSettings<T>(LoaderRunMode runMode, LoaderAssetMode assetMode) where T : ScriptableObject
        {
            if (assetMode == LoaderAssetMode.Editor) return m_EditorSettings as T;
            var rs = runMode == LoaderRunMode.Debug
                ? m_DebugSettings[(int) assetMode - 1]
                : m_ReleaseSettings[(int) assetMode - 1];
            return rs as T;
        }

        public void InitSettings()
        {
            InitEditorSettings();
            InitDebugSettings();
            InitReleaseSettings();
        }

        private void InitEditorSettings()
        {
            m_EditorSettings = CreateInstance<EditorSettings>();
            m_EditorSettings.name = "EditorSettings";
        }

        private void InitDebugSettings()
        {
            m_DebugSettings = new ScriptableObject[]
                {CreateInstance<ResourceSettings>(), CreateInstance<BundleSettings>()};
            m_DebugSettings[0].name = "ResourceSettings_Debug";
            m_DebugSettings[1].name = "BundleSettings_Debug";
        }

        private void InitReleaseSettings()
        {
            m_ReleaseSettings = new ScriptableObject[]
                {CreateInstance<ResourceSettings>(), CreateInstance<BundleSettings>()};
            m_ReleaseSettings[0].name = "ResourceSettings_Release";
            m_ReleaseSettings[1].name = "BundleSettings_Release";
        }
    }
}