using System;
using Intrepid.Utilities;
using Sirenix.OdinInspector;
using UnityEngine;

namespace Intrepid.Gameplay.Entities.Player.Sentinel
{
    [Serializable, HideLabel, GroupConfigurations("Walk")]
    public class WalkConfig
    {
        [SerializeField, Range(0, 100)] private float speed = 5;

        public float Speed => speed;
    }

    [Serializable, HideLabel, GroupConfigurations("Run")]
    public class RunConfig
    {
        [SerializeField, Range(0, 100)] private float speed = 10;

        public float Speed => speed;
    }
    
    [Serializable, HideLabel, GroupConfigurations("Dash Impulse")]
    public class DashImpulseConfig
    {
        [SerializeField, Range(0, 50)] private float speed = 35f;
        [SerializeField, Range(0, 5000)] private float durationMS = 150f;

        public float Speed => speed;
        public float Duration => durationMS * 0.001f;
    }

    [Serializable, HideLabel, GroupConfigurations("Dash Recovery")]
    public class DashRecoveryConfig
    {
        [SerializeField, Range(0, 30)] private float speed = 10;
        [SerializeField, Range(0, 5000)] private float durationMS = 200f;
        [SerializeField, Range(15, 90)] private float dashMaxAngleFromForward = 90f;
        [SerializeField] private AnimationCurve speedCurve;
        
        public float Speed => speed;
        public float Duration => durationMS * 0.001f;
        public float DashMaxAngleFromForward => dashMaxAngleFromForward;
        public AnimationCurve SpeedCurve => speedCurve;
    }

    [Serializable, HideLabel, GroupConfigurations("Dash Landing")]
    public class DashLandingConfig
    {
        [SerializeField, Range(0, 500)] private float durationMS = 100f;
        
        public float Duration => durationMS * 0.001f;
    }

    [Serializable, HideLabel, GroupConfigurations("Dash Breaking")]
    public class DashBreakingConfig
    {
        [SerializeField, Range(5, 30)] private float speed = 10;
        [SerializeField, Range(0, 500)] private float durationMS = 300f;
        [SerializeField] private AnimationCurve speedCurve;

        public float Speed => speed;
        public float Duration => durationMS * 0.001f;
        public AnimationCurve SpeedCurve => speedCurve;
    }

    [Serializable, HideLabel, GroupConfigurations("Fall Landing")]
    public class FallLandingConfig
    {
        [SerializeField, Range(0, 5000)] private float durationMS = 2000f;
        
        public float Duration => durationMS * 0.001f;
    }

    [Serializable, HideLabel, GroupConfigurations("Knockdown")]
    public class KnockdownConfig
    {
        [SerializeField] private float knockoutTimeMultiplier = 0.1f;
        [SerializeField, Range(0, 3000)] private float knockdownDurationMS = 100f;
        [SerializeField, Range(0, 3000)] private float recoverDurationMS = 500f;
        [SerializeField] private float maxKnockdownStrength = 15f;

        public float KnockoutTimeMultiplier => knockoutTimeMultiplier;
        public float KnockdownDuration => knockdownDurationMS * 0.001f;
        public float RecoverDuration => recoverDurationMS * 0.001f;
        public float MaxKnockdownStrength => maxKnockdownStrength;
    }
    
    [CreateAssetMenu(fileName = "Sentinel Config", menuName = "GON/Services/Sentinel/Config")]
    public class SentinelConfig : ScriptableObject
    {
        [SerializeField] private WalkConfig walk;
        [SerializeField] private RunConfig run;
        
        [SerializeField] private DashImpulseConfig dashImpulse;
        [SerializeField] private DashRecoveryConfig dashRecovery;
        [SerializeField] private DashLandingConfig dashLanding;
        [SerializeField] private DashBreakingConfig dashBreaking;
        
        [SerializeField] private FallLandingConfig fallLanding;
        
        [SerializeField] private KnockdownConfig knockdown;

        public WalkConfig Walk => walk;
        public RunConfig Run => run;

        public DashImpulseConfig DashImpulse => dashImpulse;
        public DashRecoveryConfig DashRecovery => dashRecovery;
        public DashLandingConfig DashLanding => dashLanding;
        public DashBreakingConfig DashBreaking => dashBreaking;
        
        public FallLandingConfig FallLanding => fallLanding;

        public KnockdownConfig Knockdown => knockdown;
    }
}