using Impact.Interactions;
using Impact.Materials;
using ImpactCFX;
using UnityEditor;
using UnityEngine;

namespace ImpactCFXConversion
{
    public class ImpactMaterialConverter : IAssetConverter
    {
        public Object Convert(Object source, ConversionContext conversionContext)
        {
            if (source is ImpactMaterial material)
            {
                ImpactMaterialAuthoring converted = convertMaterial(material, conversionContext);
                conversionContext.AddConvertedMaterial(converted);

                return converted;
            }
            else
            {
                return null;
            }
        }

        private ImpactMaterialAuthoring convertMaterial(ImpactMaterial source, ConversionContext conversionContext)
        {
            ImpactMaterialAuthoring materialAuthoring = ScriptableObject.CreateInstance<ImpactMaterialAuthoring>();
            SerializedObject serializedObject = new SerializedObject(materialAuthoring);

            //Effect sets
            SerializedProperty effectSetsListProperty = serializedObject.FindProperty("effectSets");
            effectSetsListProperty.arraySize = source.InteractionSetCount;

            for (int i = 0; i < source.InteractionSetCount; i++)
            {
                ImpactMaterialInteractionSet interactionSet = source[i];
                SerializedProperty effectSetProperty = effectSetsListProperty.GetArrayElementAtIndex(i);

                convertInteractionSet(interactionSet, effectSetProperty, conversionContext);
            }

            //Tags
            ConversionUtility.ConvertImpactTagMask(source.MaterialTagsMask, serializedObject.FindProperty("materialTags"));
            ConversionUtility.ConvertImpactTagMask(source.FallbackTagMask, serializedObject.FindProperty("fallbackTags"));

            serializedObject.ApplyModifiedProperties();
            serializedObject.Dispose();
            return materialAuthoring;
        }

        private void convertInteractionSet(ImpactMaterialInteractionSet interactionSet, SerializedProperty effectSetProperty, ConversionContext conversionContext)
        {
            effectSetProperty.FindPropertyRelative("Name").stringValue = interactionSet.Name;

            convertTagMaskFilter(interactionSet.IncludeTagsFilter, effectSetProperty.FindPropertyRelative("IncludeTags"));
            convertTagMaskFilter(interactionSet.ExcludeTagsFilter, effectSetProperty.FindPropertyRelative("ExcludeTags"));

            SerializedProperty effectListProperty = effectSetProperty.FindPropertyRelative("Effects");
            effectListProperty.arraySize = interactionSet.InteractionCount;

            for (int i = 0; i < interactionSet.InteractionCount; i++)
            {
                ImpactInteractionBase interaction = interactionSet[i];

                if (conversionContext.TryGetConvertedObject(interaction.GetInstanceID(), out Object convertedAsset))
                {
                    effectListProperty.GetArrayElementAtIndex(i).objectReferenceValue = convertedAsset as ImpactEffectAuthoringBase;
                }
                else
                {
                    Debug.LogError($"Could not find converted asset for interaction '{interaction.name}'");
                }
            }
        }


        private void convertTagMaskFilter(ImpactMaterialInteractionSet.TagMaskFilter src, SerializedProperty dst)
        {
            ConversionUtility.ConvertImpactTagMask(src.TagMask, dst.FindPropertyRelative("TagMask"));
            dst.FindPropertyRelative("Exact").boolValue = src.ExactMatch;
        }
    }
}