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

namespace ImpactCFXConversion
{
    public class ImpactAudioEffectConverter : IAssetConverter
    {
        public Object Convert(Object source, ConversionContext conversionContext)
        {
            if (source is ImpactAudioInteraction a)
            {
                return convertAudioInteraction(a, conversionContext);
            }
            else
            {
                return null;
            }
        }

        private ImpactAudioEffectAuthoring convertAudioInteraction(ImpactAudioInteraction audioInteraction, ConversionContext conversionContext)
        {
            ImpactAudioEffectAuthoring convertedEffect = ScriptableObject.CreateInstance<ImpactAudioEffectAuthoring>();
            SerializedObject serializedObject = new SerializedObject(convertedEffect);

            //Collision audio clips
            SerializedProperty collisionAudioClips = serializedObject.FindProperty("collisionAudioClips");
            collisionAudioClips.arraySize = audioInteraction.CollisionAudioClips.Count;
            for (int i = 0; i < audioInteraction.CollisionAudioClips.Count; i++)
            {
                collisionAudioClips.GetArrayElementAtIndex(i).objectReferenceValue = audioInteraction.CollisionAudioClips[i];
            }

            //Collision audio clip selection mode
            serializedObject.FindProperty("collisionClipSelectionMode").enumValueIndex = (int)audioInteraction.CollisionAudioSelectionMode;

            //Slide and roll audio clips
            serializedObject.FindProperty("slideAudioClip").objectReferenceValue = audioInteraction.SlideAudioClip;
            serializedObject.FindProperty("rollAudioClip").objectReferenceValue = audioInteraction.RollAudioClip;

            //Audio source template
            if (audioInteraction.AudioSourceTemplate is Impact.Interactions.Audio.ImpactAudioSource a)
            {
                ImpactCFX.Audio.ImpactAudioSource convertedAudioSource = ConversionUtility.ConvertPrefab<Impact.Interactions.Audio.ImpactAudioSource, ImpactCFX.Audio.ImpactAudioSource>(
                    a,
                    conversionContext,
                    convertAudioSource);

                if (convertedAudioSource == null || convertedAudioSource.Equals(null))
                {
                    Debug.LogWarning($"Audio Source Template for audio interaction {audioInteraction.name} is null or missing.");
                }

                serializedObject.FindProperty("audioSourceTemplate").objectReferenceValue = convertedAudioSource;
            }
            else
            {
                Debug.LogError($"Cannot convert custom ImpactAudioSource component on '{audioInteraction.AudioSourceTemplate}'");
            }

            //Ranges
            ConversionUtility.ConvertRange(audioInteraction.VelocityRange, serializedObject.FindProperty("velocityReferenceRange"));
            ConversionUtility.ConvertRange(audioInteraction.RandomPitchRange, serializedObject.FindProperty("randomPitchRange"));
            ConversionUtility.ConvertRange(audioInteraction.RandomVolumeRange, serializedObject.FindProperty("randomVolumeRange"));

            //Other properties
            serializedObject.FindProperty("scaleVolumeWithVelocity").boolValue = audioInteraction.ScaleVolumeWithVelocity;
            serializedObject.FindProperty("collisionNormalInfluence").floatValue = audioInteraction.CollisionNormalInfluence;
            serializedObject.FindProperty("velocityPitchInfluence").floatValue = audioInteraction.SlideVelocityPitchMultiplier;

            serializedObject.ApplyModifiedProperties();
            serializedObject.Dispose();

            return convertedEffect;
        }

        private void convertAudioSource(Impact.Interactions.Audio.ImpactAudioSource src, SerializedObject srcObject, ImpactCFX.Audio.ImpactAudioSource dst, SerializedObject dstObject)
        {
            ConversionUtility.ConvertObjectPoolConfig(src.PoolSize, src.PoolFallbackMode, dstObject.FindProperty("objectPoolConfig"));

            dstObject.FindProperty("audioSource").objectReferenceValue = srcObject.FindProperty("_audioSource").objectReferenceValue;
        }
    }
}

