using Impact;
using ImpactCFX;
using ImpactCFX.EditorScripts;
using UnityEditor;
using UnityEngine;

namespace ImpactCFXConversion
{
    public class ImpactManagerConverter : IAssetConverter
    {
        public Object Convert(Object source, ConversionContext conversionContext)
        {
            if (source is GameObject g)
            {
                ImpactManager[] impactManagers = g.GetComponentsInChildren<ImpactManager>();

                foreach (var item in impactManagers)
                {
                    convertImpactManager(item, conversionContext);
                }
            }

            return source;
        }

        private void convertImpactManager(ImpactManager src, ConversionContext conversionContext)
        {
            ImpactCFXManager impactCFXManager = CreateImpactCFXManager.Create();

            SerializedObject srcSerializedObject = new SerializedObject(src);
            SerializedObject dstSerializedObject = new SerializedObject(impactCFXManager);

            dstSerializedObject.FindProperty("dontDestroyOnLoad").boolValue = srcSerializedObject.FindProperty("_dontDestroyOnLoad").boolValue;
            dstSerializedObject.FindProperty("setAsActiveInstance").boolValue = srcSerializedObject.FindProperty("_setAsActiveInstance").boolValue;
            dstSerializedObject.FindProperty("materialRegistry").objectReferenceValue = conversionContext.GetImpactMaterialRegistry();

            //Material mapping
            ImpactMaterialMappingProcessor materialMappingProcessor = impactCFXManager.gameObject.GetComponentInChildren<ImpactMaterialMappingProcessor>();
            SerializedObject materialMappingSerializedObject = new SerializedObject(materialMappingProcessor);

            //3D
            SerializedProperty srcMaterialMapping3D = srcSerializedObject.FindProperty("_physicMaterialMap");
            SerializedProperty dstMaterialMapping3D = materialMappingSerializedObject.FindProperty("physicMaterialMap");

            dstMaterialMapping3D.arraySize = srcMaterialMapping3D.arraySize;
            for (int i = 0; i < srcMaterialMapping3D.arraySize; i++)
            {
                SerializedProperty srcArrayElement = srcMaterialMapping3D.GetArrayElementAtIndex(i);
                SerializedProperty dstArrayElement = dstMaterialMapping3D.GetArrayElementAtIndex(i);

                dstArrayElement.FindPropertyRelative("PhysicMaterial").objectReferenceValue = srcArrayElement.FindPropertyRelative("PhysicMaterial").objectReferenceValue;

                if (conversionContext.TryGetConvertedObject(srcArrayElement.FindPropertyRelative("ImpactMaterial").objectReferenceValue.GetInstanceID(), out Object converted))
                {
                    dstArrayElement.FindPropertyRelative("ImpactMaterial").objectReferenceValue = converted;
                }
                else
                {
                    Debug.LogError($"Unable to find converted material '{srcArrayElement.FindPropertyRelative("ImpactMaterial").objectReferenceValue.name}' for object '{src.gameObject.name}'");
                }
            }

            dstSerializedObject.ApplyModifiedProperties();
            materialMappingSerializedObject.ApplyModifiedProperties();

            srcSerializedObject.Dispose();
            dstSerializedObject.Dispose();
            materialMappingSerializedObject.Dispose();

            conversionContext.AddObjectToDestroy(ConversionContextDestroyGroupType.Components, src);
            conversionContext.AddConvertedObject(src.GetInstanceID(), impactCFXManager);
        }
    }
}