using Unity.VisualScripting;
using UnityEngine;

public class SternBewegung : MonoBehaviour
{
    public float randomnessIntensity;

    public float randomnessBaseAngle;

    public float randomMovementDuration;

    public float wobblingAngle;

    public float wobblingDuration;

    public float angularVelocity;

    private Vector2 targetPosition;

    private Vector2 startPosition;

    private float timeOfArrival;

    private float timeOfDeparture;

    private Vector2 randomMovement;

    private Vector2 randomStrictDiff;

    private float endOfRandomMovement;

    private float strictRotationAngle;

    public void GoToPosition(Vector2 position, float duration){
        targetPosition = position;
        startPosition = (Vector2) transform.position - randomStrictDiff;
        timeOfArrival = Time.time + duration;
        timeOfDeparture = Time.time;
    }

    public void GoToPositionWithVelocity(Vector2 position, float velocity){
        float dt = ((Vector2) transform.position - randomStrictDiff - position).magnitude / velocity;
        GoToPosition(position, dt);
    }

    public void Initialize(){
        targetPosition = transform.position;
        startPosition = transform.position;
        timeOfArrival = 0f;
        timeOfDeparture = 0f;
        randomMovement = Vector2.zero;
        randomStrictDiff = Vector2.zero;
        endOfRandomMovement = 0f;
    }

    // Start is called once before the first execution of Update after the MonoBehaviour is created
    void Start()
    {
        Initialize();
    }

    // Update is called once per frame
    void Update()
    {
        Vector2 strictPos;
        if (Time.time >= timeOfDeparture && Time.time < timeOfArrival) {
            strictPos = Vector2.Lerp(startPosition, targetPosition, (Time.time - timeOfDeparture)/(timeOfArrival - timeOfDeparture));
        } else {
            strictPos = targetPosition;
        }
        if (Time.time >= endOfRandomMovement) {
            endOfRandomMovement = Time.time + randomMovementDuration;
            float angle;
            if (randomStrictDiff.magnitude > randomnessBaseAngle / 180f) {
                angle = (Random.value * 2f - 1f) * randomnessBaseAngle / randomStrictDiff.magnitude;
            } else {
                angle = Random.value * 360f;
            }
            if (randomStrictDiff.magnitude > 0){
                randomMovement = Quaternion.AngleAxis(angle, Vector3.forward) * randomStrictDiff.normalized * (-1) * randomnessIntensity;
            } else {
                randomMovement = Quaternion.AngleAxis(angle, Vector3.forward) * Vector2.up * randomnessIntensity;
            }
        }
        randomStrictDiff += randomMovement * Time.deltaTime;
        transform.position = strictPos + randomStrictDiff;

        strictRotationAngle += angularVelocity * Time.deltaTime;
        float rotationAngle = strictRotationAngle;
        float normalizedTime = (Time.time % wobblingDuration) / wobblingDuration;
        if (normalizedTime < .5f){
            rotationAngle += - wobblingAngle + 4 * wobblingAngle * normalizedTime;
        } else {
            rotationAngle += wobblingAngle - 4 * wobblingAngle * (normalizedTime - .5f);
        }
        transform.rotation = Quaternion.AngleAxis(rotationAngle, Vector3.forward);
    }
}
