using ExtraTools;
using UnityEngine;

[RequireComponent(typeof(PhysicsObject))]
public class Player : MonoBehaviour
{
    [SerializeField]
    private float moveSpeed = 10;
    [SerializeField]
    private float jumpSpeed = 10;
    [SerializeField]
    private PhysicsObject phys;
    [SerializeField]
    private Glue leftGlue;
    [SerializeField]
    private Glue rightGlue;
    [SerializeField]
    private Glue topGlue;
    [SerializeField]
    private Glue bottomGlue;
    [SerializeField]
    private Transform visual;

    private bool canMove = true;

    private GameState state;

    public PickupTile tile;

    private bool isJumping = false;

    private void GetInput()
    {
        if (ObjectHolder.Instance.gameState.currentGameState != GameStateEnum.level) return;

        //if (Input.GetKeyDown(KeyCode.Space))
        //{
        //    topGlue.SetState(false);
        //    bottomGlue.SetState(false);
        //    leftGlue.SetState(false);
        //    rightGlue.SetState(false);

        //    SoundManager.Instance.Play(SoundManager.soundId.playerUnglued);
        //}
        //else if (Input.GetKeyUp(KeyCode.Space))
        //{
        //    topGlue.SetState(true);
        //    bottomGlue.SetState(true);
        //    leftGlue.SetState(true);
        //    rightGlue.SetState(true);
        //}

        if (Application.isEditor && Input.GetKeyDown(KeyCode.K))
        {
            Die();
        }

        float vSpeed = Input.GetAxisRaw("Vertical");
        float hSpeed = Input.GetAxisRaw("Horizontal");
        if (vSpeed * LevelController.Instance.Gravity.y != 0)
        {
            if (!leftGlue.Sticking && !rightGlue.Sticking
                && ((!bottomGlue.Sticking && vSpeed < 0 && LevelController.Instance.Gravity.y > 0)
                || (!topGlue.Sticking && vSpeed > 0 && LevelController.Instance.Gravity.y < 0)))
                vSpeed = 0;
        }
        if (hSpeed * LevelController.Instance.Gravity.x != 0)
        {
            if (!topGlue.Sticking && !bottomGlue.Sticking
                && ((!leftGlue.Sticking && hSpeed < 0 && LevelController.Instance.Gravity.x > 0)
                || (!rightGlue.Sticking && hSpeed > 0 && LevelController.Instance.Gravity.x < 0)))
                hSpeed = 0;
        }

        if (hSpeed != 0)
            phys.targetVelocity.x = hSpeed * moveSpeed;
        if (vSpeed != 0)
            phys.targetVelocity.y = vSpeed * moveSpeed;
        //if (vGlue.Sticking || Mathf.Approximately(0, Vector2.Dot(Vector2.right, LevelController.Instance.Gravity)))
        //    phys.targetVelocity.x = hSpeed * moveSpeed;
        //if (hGlue.Sticking || Mathf.Approximately(0, Vector2.Dot(Vector2.up, LevelController.Instance.Gravity)))
        //    phys.targetVelocity.y = vSpeed * moveSpeed;
    }

    public void Jump(Vector2 force)
    {
        isJumping = true;
        phys.useGravity = true;
        phys.targetVelocity = force;
    }

    public void Teleport(Vector2 pos)
    {
        phys.Teleport(pos);
    }

    public void Die()
    {
        canMove = phys.enabled = false;
        SoundManager.Instance.Play(SoundManager.soundId.playerDead);
        visual.gameObject.SetActive(false);
        ResourceManager.Instance.playerExplosion.Get().transform.position = transform.position - Vector3.forward * 0.025f;
        state.PlayerState = PlayerState.Dead;
    }

    public void Resurrect()
    {
        canMove = phys.enabled = true;
        visual.gameObject.SetActive(true);
        state.PlayerState = PlayerState.Alive;
    }

    public void Freeze()
    {
        canMove = phys.enabled = false;
    }

    public void Unfreeze()
    {
        canMove = phys.enabled = true;
    }

    private void Awake()
    {
        state = ObjectHolder.Instance.gameState;
    }

    private void Update()
    {
        if (ObjectHolder.Instance.gameState.currentGameState == GameStateEnum.world)
            visual.localScale = Vector3.one * 2;
        else
            visual.localScale = Vector3.one;


        if (!canMove) return;

        if (!isJumping)
            phys.useGravity = (LevelController.Instance.Gravity.y != 0
                && (!leftGlue.Sticking && !rightGlue.Sticking)
                && (!topGlue.Sticking && !bottomGlue.Sticking))
                || (LevelController.Instance.Gravity.x != 0 
                && (!topGlue.Sticking && !bottomGlue.Sticking)
                && (!leftGlue.Sticking && !rightGlue.Sticking));

        GetInput();
    }

    private void FixedUpdate()
    {
        if (isJumping && !topGlue.Sticking)
            isJumping = false;
    }

    private void Reset()
    {
        transform.SetComponent(out phys);
    }
}