using UnityEngine;

public class CharacterPhysics : MonoBehaviour
{
    [Header("Movement")]
	[SerializeField] private float pushForce = 10;
	[SerializeField] private float dashForce = 10;
	[SerializeField] private float drag = 1;

    [Header("Runtime")]
    [SerializeField, ReadOnly] private CatController player;
    [SerializeField, ReadOnly] private CircleCollider2D cCollider;
    [SerializeField, ReadOnly] private Rigidbody2D rb;
    [SerializeField, ReadOnly] private bool isDashing;
    [SerializeField, ReadOnly] private bool wasBumped;
    [SerializeField, ReadOnly] private float mashTimer;
    public float CurrentMashTimer { get { return mashTimer; } }
    

    public CatController Player { get { return player; } set { player = value; } }
    //public bool IsDashing { get { return isDashing; } }
    public Vector2 Velocity { get { return rb.velocity; } }
    public bool WasBumped { get { return wasBumped; } set { wasBumped = value; } }


    private void Awake()
    {
        cCollider = GetComponent<CircleCollider2D>();
        rb = GetComponent<Rigidbody2D>();
    }

    public void ResumeSimulation()
    {
        rb.simulated = cCollider.enabled = true;
    }
    public void HaltSimulation()
    {
        rb.simulated = cCollider.enabled = false;
        rb.velocity = Vector2.zero;
    }
    public void StartDash(float timer)
    {
        SoundManager.Instance.Play(SoundManager.SoundType.Dash);
        this.mashTimer = timer;
        this.isDashing = true;
    }

    public void Tick(float delta)
    {
        mashTimer -= delta;
    }

    public void FixedTick(Vector2 movementDirection)
    {
        //player.Audio.PlayWalkingSound();

        // Dash if possible
        if (isDashing)
		{
            rb.AddForce(movementDirection * dashForce, ForceMode2D.Impulse);

            // Play sound when jumping
            //player.Audio.PlayJumpingSound();

			isDashing = false;
		}

		rb.AddForce(movementDirection * pushForce);
		rb.drag = drag;
		//rb.velocity = new Vector2(Mathf.Min(rb.velocity.x, maxVelocity), Mathf.Min(rb.velocity.y, maxVelocity));
    }

    private void OnCollisionEnter2D(Collision2D collision)
	{
        if(player.Info.PlayerColourID == 3) return;

        CharacterInfo otherInfo = collision.collider.GetComponent<CharacterInfo>();
        Vector2 relativeVelocity = collision.relativeVelocity;
        Rigidbody2D otherRB = collision.collider.GetComponent<Rigidbody2D>();

        if(player.Info.PlayerColourID == 2 && otherInfo.PlayerColourID == 3) Bump(relativeVelocity, otherRB);

        else if(player.Info.PlayerColourID == 1 && (otherInfo.PlayerColourID == 2 || otherInfo.PlayerColourID == 1)) Bump(relativeVelocity, otherRB);

        else if(player.Info.PlayerColourID == 0) Bump(relativeVelocity, otherRB);
	}

    private void Bump(Vector2 relativeVelocity, Rigidbody2D otherRB)
    {
        CheckButtonMash(otherRB.GetComponent<CharacterPhysics>().CurrentMashTimer, rb, otherRB);

        SoundManager.Instance.Play(SoundManager.SoundType.Impact);
        player.Audio.PlayBumpSound();

        //Debug.Log(relativeVelocity);

        //lower bound

        Vector2 sign = new Vector2(Mathf.Sign(relativeVelocity.x), Mathf.Sign(relativeVelocity.y));

        Vector2 bounce = new Vector2(
            Mathf.Max(Mathf.Abs(relativeVelocity.x * 0.5f), 2.5f),
            Mathf.Max(Mathf.Abs(relativeVelocity.y * 0.5f), 2.5f)
        );

        bounce = new Vector2(bounce.x * sign.x, bounce.y * sign.y);

		rb.AddForce(bounce, ForceMode2D.Impulse);
		otherRB.AddForce(-bounce, ForceMode2D.Impulse);

        wasBumped = true;

        if (GameManager.Instance.BombController.Owner == transform)
            GameManager.Instance.BombController.Transfer(otherRB.transform);
        else if (GameManager.Instance.BombController.Owner == otherRB.transform)
            GameManager.Instance.BombController.Transfer(transform);

        EZCameraShake.CameraShaker.Instance.ShakeOnce(relativeVelocity.magnitude * 0.25f, 6, 0.2f, 0.5f);
    }

    private void CheckButtonMash(float otherTimer, Rigidbody2D id1, Rigidbody2D id2)
    {
        if (GameStart.Instance.AlivePlayerCount == 2)
        {
            if (mashTimer > 0 && otherTimer > 0)
            {

                bool b;
                if (player.transform.position.x < id2.transform.position.x)
                {
                    b = GameStart.Instance.TriggerButtonMash(player.ID, id2.GetComponent<CatController>().ID);
                }
                else
                {
                    b = GameStart.Instance.TriggerButtonMash(id2.GetComponent<CatController>().ID, player.ID);                    
                }

                if (b)
                {
                    GameManager.Instance.BombController.Pause();
                    rb.simulated = id2.simulated = false;
                    player.Input.SetPermissions(false);
                    id2.GetComponent<CharacterInput>().SetPermissions(false);
                }
            }
        }
    }

    public void DisableCollider()
    {
        cCollider.enabled = false;
    }
}