using System;
using System.Collections;
using System.Linq;
using UnityEditor.VersionControl;
using UnityEngine;
using UnityEngine.EventSystems;
using UnityEngine.UI;
using static UnityEditor.PlayerSettings;

[SelectionBase]
public class Player : MonoBehaviour {
    [Header("Movement Dependencies")]
    [SerializeField] private Rigidbody2D RigidBody;
    [SerializeField] private Animator Animator;
    [SerializeField] private SpriteRenderer Renderer;

    [Header("Character Class Dependencies")]
    [SerializeField] private ParticleSystem Aura;
    [SerializeField] private GameObject[] ClassIndicators;

    [Header("Movement Attributes")]
    [SerializeField] private float MoveSpeed = 4;
    [SerializeField] private float DashMultiplier = 30;
    [SerializeField] private float DriftSpeed = 30;
    [SerializeField] private float DriftFactorial = 0.85f;

    private Vector2 MoveDirection = Vector2.zero;
    private Directions FaceDir = Directions.Down;

    private bool isDashing;
    private Vector2 DriftDirection = Vector2.zero;
    private float Drift = 0;

    private readonly int AnimMoveRight = Animator.StringToHash("Anim_Player_MoveRight");
    private readonly int AnimIdleRight = Animator.StringToHash("Anim_Player_IdleRight");


    private enum Directions { Left, Right, Up, Down }


    private void Update() {
        GatherInput();
        KeyPressActions();
    }
    private void GatherInput() {
        MoveDirection.x = Input.GetAxisRaw("Horizontal");
        MoveDirection.y = Input.GetAxisRaw("Vertical");
    }

    private void KeyPressActions() {
        if (Input.GetKeyDown(KeyCode.LeftShift) || Input.GetKeyDown(KeyCode.RightShift)) {
            Dash(MoveDirection);
        } else if (Input.GetKeyDown(KeyCode.F1)) {
            SetClass(0);
        } else if (Input.GetKeyDown(KeyCode.F2)) {
            SetClass(1);
        } else if (Input.GetKeyDown(KeyCode.F3)) {
            SetClass(2);
        } else if (Input.GetKeyDown(KeyCode.F4)) {
            SetClass(3);
        }
    }

    private void Dash(Vector2 direction) {
        if (Drift > 0.5f) return;
        isDashing = true;

        RigidBody.linearVelocity = direction.normalized * MoveSpeed * DashMultiplier;

        DriftDirection = direction.normalized;
        Drift = DriftSpeed;
        isDashing = false;
    }

    private void SetClass(int classIdx) {
        foreach (var (indicator, i) in ClassIndicators.Select((obj, i) => (obj, i)))
            if (i != classIdx) {
                indicator.transform.localScale = Vector3.one;
                indicator.transform.rotation = Quaternion.identity;
            } else {
                indicator.transform.localScale = Vector3.one * 2;
                indicator.transform.rotation = Quaternion.AngleAxis(90, Vector3.forward);
            }

        RawImage image = ClassIndicators[classIdx].GetComponent<RawImage>();
        var main = Aura.main;
        main.startColor = image.color;
    }



    private void FixedUpdate() {
        MovementUpdate();
        CalculateFacingDirection();
        UpdateAnimation();
    }

    private void MovementUpdate() {
        if (isDashing) return;

        RigidBody.linearVelocity = MoveDirection.normalized * MoveSpeed;
        if (Drift > 0.2f) {
            RigidBody.linearVelocity += DriftDirection * Drift;
            Drift *= DriftFactorial;
            print(Drift);
        } else {
            Drift = 0f;
        }
    }


    private void CalculateFacingDirection() {
        if (MoveDirection.x != 0)
            if (MoveDirection.x < 0)
                FaceDir = Directions.Left;
            else
                FaceDir = Directions.Right;
    }

    private void UpdateAnimation() {
        Renderer.flipX = (FaceDir == Directions.Left);
        Animator.CrossFade((MoveDirection.sqrMagnitude > 0) ? AnimMoveRight : AnimIdleRight, 0);
    }
}
