using System.Collections.Generic;
using System.IO;
using UnityEditor;
using UnityEngine;

namespace AssetBank.Settings
{
    public enum UnityAssetType
    {
        Animation,
        AnimatorController,
        AnimatorOverrideController,
        AudioClip,
        AudioMixer,
        ComputeShader,
        Font,
        GUISkin,
        Material,
        Mesh,
        Model,
        PhysicMaterial,
        Prefab,
        Scene,
        Script,
        Shader,
        Sprite,
        Texture,
        VideoClip,
        RenderTexture,
        LightmapParameters,
        Custom
    }

    [System.Serializable]
    public class IgnoredUnityType
    {
        public UnityAssetType assetType = UnityAssetType.Texture;
        public string customType = "";
    }
    
    [System.Serializable]
    public class SafeExposedComponents
    {
        public string Component;
        public List<string> ExposedFields;
    }

    public class ProjectExporterSettings : ScriptableObject
    {
        private const string k_SettingsPath = "Assets/AssetBank/Assets/ProjectExporterSettings.asset";

        [SerializeField] 
        private bool m_ConvertToNewSchema;
        public bool ConvertToNewSchema => m_ConvertToNewSchema;

        [SerializeField] 
        private bool m_OptimiseExport;
        public bool OptimiseExport => m_OptimiseExport;

        [SerializeField] 
        private List<string> m_CategoriesToOptimise = new();
        public List<string> CategoriesToOptimise => m_CategoriesToOptimise;
        
        [SerializeField] 
        private List<SafeExposedComponents> m_SafeComponents = new();
        public List<SafeExposedComponents> SafeComponents => m_SafeComponents;
        
        [SerializeField] 
        private List<SafeExposedComponents> m_HardcodedComponents = new();
        public List<SafeExposedComponents> HardcodedComponents => m_HardcodedComponents;

        [SerializeField] 
        private bool m_OverrideHardcodedDefaults;
        public bool OverrideHardcodedDefaults => m_OverrideHardcodedDefaults;

        [SerializeField]
        private List<string> m_FoldersToIgnore = new();
        public List<string> FoldersToIgnore => m_FoldersToIgnore;

        [SerializeField]
        private List<string> m_FileExtensionsToIgnore = new();
        public List<string> FileExtensionsToIgnore => m_FileExtensionsToIgnore;

        [SerializeField]
        private List<IgnoredUnityType> m_UnityTypesToIgnore = new();
        public List<IgnoredUnityType> UnityTypesToIgnore => m_UnityTypesToIgnore;


        public static ProjectExporterSettings GetOrCreateSettings()
        {
            var settings = AssetDatabase.LoadAssetAtPath<ProjectExporterSettings>(k_SettingsPath);
            if (settings == null)
            {
                settings = CreateInstance<ProjectExporterSettings>();
                settings.m_OptimiseExport = true;
                settings.m_CategoriesToOptimise = new List<string> { "Scenes", "Prefabs" };
                settings.m_OverrideHardcodedDefaults = false;

                settings.m_HardcodedComponents = new List<SafeExposedComponents>
                {
                    new() { Component = "GameObject", ExposedFields = new List<string> { "m_Component", "m_Name", "m_Layer", "m_TagString", "m_IsActive" } },
                    new() { Component = "Transform", ExposedFields = new List<string> { "m_Father", "m_Children", "m_PrefabInstance" } },
                    new() { Component = "PrefabInstance", ExposedFields = new List<string> { "m_SourcePrefab", "m_TransformParent" } },
                    new() { Component = "MonoBehaviour", ExposedFields = new List<string> { "m_Enabled", "m_Script" } }
                };

                settings.m_SafeComponents = new List<SafeExposedComponents>
                {
                    new()
                    {
                        Component = "GameObject",
                        ExposedFields = new List<string> { "m_Layer", "m_Name", "m_TagString", "m_IsActive", "m_Component" }
                    },
                    new()
                    {
                        Component = "Transform",
                        ExposedFields = new List<string> { "m_Father", "m_Children" }
                    },
                    new()
                    {
                        Component = "MonoBehaviour",
                        ExposedFields = new List<string> { "*" }
                    },
                    new()
                    {
                        Component = "PrefabInstance",
                        ExposedFields = new List<string> { "*" }
                    }
                };
                
                var directory = Path.GetDirectoryName(k_SettingsPath);
                if (!Directory.Exists(directory))
                {
                    Directory.CreateDirectory(directory);
                }
                AssetDatabase.CreateAsset(settings, k_SettingsPath);
                AssetDatabase.SaveAssets();
            }
            return settings;
        }

        internal static SerializedObject GetSerializedSettings()
        {
            return new SerializedObject(GetOrCreateSettings());
        }
    }
}
