using gay.lilyy.Common;
using gay.lilyy.MeshCompression;
using nadena.dev.ndmf;
using UnityEditor;
using UnityEngine;

[assembly: ExportsPlugin(typeof(MeshCompressionPlugin))]

namespace gay.lilyy.MeshCompression
{
    public class MeshCompressionPlugin : Plugin<MeshCompressionPlugin>
    {
        public override string DisplayName => "MeshCompression";
        public override string QualifiedName => "gay.lilyy.MeshCompression";

        public static ModelImporterMeshCompression GetCompression(RuntimeModelImporterMeshCompression compression)
        {
            return compression switch
            {
                RuntimeModelImporterMeshCompression.Off => ModelImporterMeshCompression.Off,
                RuntimeModelImporterMeshCompression.Low => ModelImporterMeshCompression.Low,
                RuntimeModelImporterMeshCompression.Medium => ModelImporterMeshCompression.Medium,
                RuntimeModelImporterMeshCompression.High => ModelImporterMeshCompression.High,
                _ => ModelImporterMeshCompression.Off
            };
        }

        protected override void Configure()
        {
            InPhase(BuildPhase.Optimizing)
                .Run("Set Mesh Compression", ctx =>
                {
                    var defaultConfig = ComponentHelper.GetComponentInChildrenWithError<MeshCompressionConfig>(ctx.AvatarRootObject);
                    var renderers = ctx.AvatarRootObject.GetComponentsInChildren<Renderer>(true);

                    foreach (var renderer in renderers)
                    {
                        Mesh mesh = null;

                        if (renderer is SkinnedMeshRenderer skinnedRenderer)
                        {
                            mesh = skinnedRenderer.sharedMesh;
                        }
                        else if (renderer is MeshRenderer meshRenderer)
                        {
                            var filter = meshRenderer.GetComponent<MeshFilter>();
                            if (filter != null)
                            {
                                mesh = filter.sharedMesh;
                            }
                        }

                        if (mesh == null) continue;

                        var localConfig = renderer.GetComponent<MeshCompressionConfig>();
                        var effectiveConfig = localConfig != null ? localConfig : defaultConfig;
                        if (effectiveConfig == null) continue;


                        var path = AssetDatabase.GetAssetPath(mesh);
                        if (string.IsNullOrEmpty(path) || !path.EndsWith(".fbx", System.StringComparison.OrdinalIgnoreCase))
                        {
                            if (localConfig != null) Debug.LogError($"[NDMF] Could not find FBX for {renderer.gameObject.name}");
                            continue;
                        }

                        var importer = AssetImporter.GetAtPath(path) as ModelImporter;
                        if (importer == null) continue;


                        var targetCompression = GetTargetCompression(effectiveConfig);
                        var unityCompression = GetCompression(targetCompression);

                        if (importer.meshCompression != unityCompression)
                        {
                            importer.meshCompression = unityCompression;
                            importer.SaveAndReimport();
                            Debug.Log($"[NDMF] Set mesh compression to {unityCompression} for {path}");
                        }
                        else
                        {
                            Debug.Log($"[NDMF] Mesh compression already set to {unityCompression} for {path}");
                        }
                    }
                });
        }

        private static RuntimeModelImporterMeshCompression GetTargetCompression(MeshCompressionConfig settings)
        {
            var target = EditorUserBuildSettings.activeBuildTarget;
            return target switch
            {
                BuildTarget.StandaloneWindows => settings.windowsCompression,
                BuildTarget.StandaloneWindows64 => settings.windowsCompression,
                BuildTarget.Android => settings.androidCompression,
                _ => RuntimeModelImporterMeshCompression.Off
            };
        }
    }
}
