using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using DG.Tweening;
using System;
using Random = UnityEngine.Random;

public class Character : MonoBehaviour
{
    public event Action OnCharacterIgnored;
    public bool isActive = false;
    public bool isAvailable = true;
    public int characterIndex;

    private int stepsNumber = 6;
    private float stepDistance;
    private float walkAngle = 6;
	private bool stopped = false;
    private int direction = 1;
    private Vector3 startPosition;
	private Sequence walkSequence;
    private CharacterColor characterColor;

    public Gesture.GestureName[] gestures;
    private int intimacy = 0;

    private void Awake()
    {
        characterColor = GetComponent<CharacterColor>();
        startPosition = transform.position;
        walkSequence = DOTween.Sequence();
        isActive = false;
    }

    public void StartMovement()
    {
        isActive = true;
        isAvailable = true;
        
        // reset start position and randomize direction
        direction = (Random.Range(0, 2) == 0) ? -1 : 1;
        startPosition.x = direction * Mathf.Abs(startPosition.x);
        transform.position = startPosition;
        characterColor.FlipCharacter(direction == 1);

        // defines walk tweening
        stepDistance = -startPosition.x / stepsNumber;
        walkSequence.Kill();
        walkSequence = DOTween.Sequence();
        for (int i = 0; i < stepsNumber * 2; i++)
        {
            walkSequence.Append(transform.DORotate(direction * Vector3.forward * walkAngle, 0.5f));
            walkSequence.Join(transform.DOMoveX(stepDistance, 0.5f).SetRelative());
            walkSequence.Join(transform.DOMoveY(0.25f, 0.25f).SetLoops(2, LoopType.Yoyo).SetRelative());
            walkSequence.AppendCallback(() => AudioMaster.PlayStepClip());
            walkSequence.Append(transform.DORotate(-direction * Vector3.forward * walkAngle, 0.4f));
            walkSequence.Join(transform.DOMoveY(0.25f, 0.2f).SetLoops(2, LoopType.Yoyo).SetRelative());
            walkSequence.AppendCallback(() => AudioMaster.PlayStepClip());
        }
		walkSequence.AppendCallback(BeIgnored);
    }

	public void StopMovement()
	{
        // ignore if stopped already
		if (stopped)
        {
            ContinueMovement();
			return;
        }
		stopped = true;
        isAvailable = false;
		
        // stop walking and do landing
		walkSequence.Kill();
        walkSequence = DOTween.Sequence();
        walkSequence.Append(transform.DORotate(Vector3.forward * 0, 0.5f));
		walkSequence.Join(transform.DOMoveX(stepDistance / 2, 0.5f).SetRelative());
        walkSequence.Join(transform.DOMoveY(startPosition.y + 0.25f, 0.25f));
		walkSequence.Join(transform.DOMoveY(startPosition.y, 0.25f).SetDelay(0.25f));

        // stop "animation"
        characterColor.TurnHead(true);
	}

    public void ContinueMovement()
    {
        Vector3 destination = startPosition;
        destination.x = -destination.x + stepDistance;
        Vector3 currentPosition = transform.position;
        
        // continue tweening
		walkSequence.Kill();
        walkSequence = DOTween.Sequence();
        for (int i = 0; i < stepsNumber * 2; i++)
        {
            if (Vector3.Distance(currentPosition, destination) < Mathf.Abs(stepDistance))
                break;
            walkSequence.Append(transform.DORotate(direction * Vector3.forward * walkAngle, 0.5f));
            walkSequence.Join(transform.DOMoveX(stepDistance, 0.5f).SetRelative());
            walkSequence.Join(transform.DOMoveY(0.25f, 0.25f).SetLoops(2, LoopType.Yoyo).SetRelative());
            walkSequence.AppendCallback(() => AudioMaster.PlayStepClip());
            walkSequence.Append(transform.DORotate(-direction * Vector3.forward * walkAngle, 0.4f));
            walkSequence.Join(transform.DOMoveY(0.25f, 0.2f).SetLoops(2, LoopType.Yoyo).SetRelative());
            walkSequence.AppendCallback(() => AudioMaster.PlayStepClip());
            currentPosition.x += stepDistance;
        }
		walkSequence.AppendCallback(FinishMovement);
        
        // continue "animation"
        characterColor.TurnHead(false);
    }

	private void BeIgnored()
	{
		if (OnCharacterIgnored != null)
			OnCharacterIgnored();
        FinishMovement();
	}

	private void FinishMovement()
	{
        stopped = false;
        isActive = false;
        isAvailable = true;
	}

    public Gesture.GestureName[] GetGestures()
    {
        int currentIntimacy = Mathf.Min(gestures.Length, intimacy + 1);
        Gesture.GestureName[] intimacyGestures = new Gesture.GestureName[currentIntimacy];
        Array.Copy(gestures, intimacyGestures, currentIntimacy);
        return intimacyGestures;
    }

    public void IncreaseIntimacy()
    {
        if (intimacy == gestures.Length)
            return;
        intimacy++;
    }

    public void DecreaseIntimacy()
    {
        if (intimacy == 0)
            return;
//        intimacy--;
    }

    public void SetIndex(int index)
    {
        characterIndex = index;
        characterColor.SetSortingOrder(characterIndex);
    }
}
