using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.InputSystem;

public class PlayerHeightEntity : MonoBehaviour
{
    public float entityHeight;
    public Collider2D physicsCollider;
    public AnimationCurve spriteHeightCurve;
    public AnimationCurve heightCurve;
    public float spriteHeightForce;
    public float heightForce;
    public GameObject spriteRenderer;
    public GameObject shadowSpriteRenderer;
    public float startingShadowHeight;
    public float spriteHeight;
    public float currentFloorHeight;
    public bool isJumping;
    public bool onFloor;
    public float gravityScale;
    [SerializeField] private float gravity;
    public float jumpDuration;
    public float currentSpriteFloorHeight;
    public float defaultFloorHeight;
    public float defaultSpriteFloorHeight;
    public PlatformChecker platformChecker;
    public List<Collider2D> colliders;
    public float spriteToEntityRatio;
    public InputActionReference jump;
    public InputActionReference battleJump;
    public PlayerInput playerControls;



    public void Start()
    {
        startingShadowHeight = shadowSpriteRenderer.transform.localPosition.y;
        spriteHeight = spriteRenderer.transform.localPosition.y;
    }

    public void FloorChecks()
    {
        spriteHeightCurve = new AnimationCurve(new Keyframe(0, currentSpriteFloorHeight, 1, 1, 0.35f, 0), 
            new Keyframe(1, currentSpriteFloorHeight + 1, 0, 0, 0.7f, 0));
        heightCurve = new AnimationCurve(new Keyframe(0, currentFloorHeight, 1, 1, 0.35f, 0), 
            new Keyframe(1, currentFloorHeight + 5, 0, 0, 0.7f, 0));
        if(spriteHeight <= currentSpriteFloorHeight)
        {
            spriteHeight = currentSpriteFloorHeight;
            spriteRenderer.transform.localPosition -= new Vector3(0, spriteRenderer.transform.localPosition.y 
                - currentSpriteFloorHeight);
            entityHeight = currentFloorHeight;
            onFloor = true; 
        }
        else
        {
            onFloor = false;
        }
        if(!onFloor && !isJumping)
        {
            gravity = gravityScale;
        }
        else
        {
            gravity = 0;
        }
        if(!platformChecker.onPlatform)
        {
            shadowSpriteRenderer.transform.localPosition = new Vector3(0, startingShadowHeight
                 + currentSpriteFloorHeight);
        }
    }

    public void Update()
    {
        CorrectColliderList();
        spriteHeight = spriteRenderer.transform.localPosition.y;
        FloorChecks();
        if(playerControls.currentActionMap == playerControls.actions.FindActionMap("Overworld") 
            && jump.action.WasPressedThisFrame())
        {
            Jump(false, spriteHeightForce, heightForce, jump);
        }
        if(playerControls.currentActionMap == playerControls.actions.FindActionMap("Battle") 
            && battleJump.action.WasPressedThisFrame())
        {
            Jump(false, spriteHeightForce, heightForce, battleJump);
        }
    }

    public void FixedUpdate()
    {
        spriteRenderer.transform.position -= new Vector3(0, 1f, 0) * gravity; 
        entityHeight -= gravity * spriteToEntityRatio;
    }

    public void Jump(bool isExtreme, float spriteHeightForce, float heightForce, InputActionReference correctAction)
    {
        if(!isJumping && onFloor)
        {
            StartCoroutine(JumpCo(spriteHeightForce, heightForce, correctAction));
            if(isExtreme)
            {
            }
        }
    }

    public IEnumerator JumpCo(float spriteHeightForce, float heightForce, InputActionReference correctAction)
    {
        InputActionReference jumpAction = correctAction;
        isJumping = true;
        float jumpStartTime = Time.time;
        AnimationCurve startingspriteHeightCurve = spriteHeightCurve;
        AnimationCurve startingHeightCurve = heightCurve;
        while(isJumping)
        {
            float jumpCompletionPercentage = (Time.time - jumpStartTime) / jumpDuration;
            jumpCompletionPercentage = Mathf.Clamp01(jumpCompletionPercentage);

            if(jumpAction.action.IsPressed())
            {
                spriteRenderer.transform.localPosition = new Vector3
                    (0, startingspriteHeightCurve.Evaluate(jumpCompletionPercentage) * spriteHeightForce);
                entityHeight = startingHeightCurve.Evaluate(jumpCompletionPercentage) * heightForce;
            }
            if(jumpAction.action.WasReleasedThisFrame())
            {
                break;
            }

            if(jumpCompletionPercentage == 1f)
            {
                break;
            }
            yield return null;
        }
        isJumping = false;   
    }

    public void CorrectColliders()
    {
        foreach(Collider2D col in colliders)
        {
            HeightCollider colHeight = col.GetComponent<HeightCollider>();
            colHeight.dynamicColliderHeightLevel = colHeight.startingColliderHeightLevel + (int)entityHeight;
            colHeight.ChangeHeightLevel();
        }
    }

    public void CorrectColliderList()
    {
        foreach(Collider2D col in colliders)
        {
            HeightColliderList colHeightList = col.GetComponent<HeightColliderList>();
            for(int i = 0; i < colHeightList.dynamicColliderHeightLevels.Count; i++)
            {
                colHeightList.dynamicColliderHeightLevels[i] = colHeightList.startingColliderHeightLevels[i] + (int)entityHeight;
            }
            colHeightList.ChangeHeightLevels();
        }
    }
}