using System;
using System.Collections;
using Intrepid.Utilities;
using Sirenix.OdinInspector;
using UnityEngine;

namespace Intrepid.Gameplay.Entities.Player.PDA.UI
{
    public class PDABlockageUI : MonoBehaviour
    {
        [SerializeField] private LinearAnimation linearAnimation;
        [SerializeField] private PDABlockageAnimationType animationType = PDABlockageAnimationType.VerticalSlide;
        [SerializeField] private RectTransform blockageElement;
        [SerializeField] private RectTransform surfaceElement;
        
        private CanvasGroup CanvasGroup { get; set; }
        public bool AnimationRunning { get; private set; }
        public Timer Timer { get; } = new();
        
        private void Awake()
        {
            CanvasGroup = surfaceElement.GetComponent<CanvasGroup>();
        }

        public void Bump()
        {
        }

        private IEnumerator AnimateBlock(Action whenOver)
        {
            blockageElement.pivot = animationType switch
            {
                PDABlockageAnimationType.VerticalSlide => new Vector2(0, 0.5f),
                PDABlockageAnimationType.HorizontalSquish => new Vector2(0.5f, 0.5f),
                _ => throw new ArgumentOutOfRangeException()
            };
            return linearAnimation.Animate(0, 1,
                di => di,
                v => blockageElement.localScale = animationType switch
                {
                    PDABlockageAnimationType.VerticalSlide => new Vector2(v, 1),
                    PDABlockageAnimationType.HorizontalSquish => new Vector2(1, v),
                    _ => throw new ArgumentOutOfRangeException()
                },
                ar =>
                {
                    AnimationRunning = ar;
                    if (ar) return;
                    Timer.Start();
                    if (CanvasGroup is not null) CanvasGroup.alpha = 1;
                    whenOver?.Invoke();
                });
        }

        private IEnumerator AnimateUnblock(Action whenOver)
        {
            blockageElement.pivot = animationType switch
            {
                PDABlockageAnimationType.VerticalSlide => new Vector2(1, 0.5f),
                PDABlockageAnimationType.HorizontalSquish => new Vector2(0.5f, 0.5f),
                _ => throw new ArgumentOutOfRangeException()
            };
            return linearAnimation.Animate(1, 0,
                di => -di,
                v => blockageElement.localScale = animationType switch
                {
                    PDABlockageAnimationType.VerticalSlide => new Vector2(v, 1),
                    PDABlockageAnimationType.HorizontalSquish => new Vector2(1, v),
                    _ => throw new ArgumentOutOfRangeException()
                }, 
                ar =>
                {
                    AnimationRunning = ar;
                    if (ar) return;
                    whenOver?.Invoke();
                });
        }
        
        [Button(ButtonStyle.FoldoutButton)]
        public void Block(Action whenOver = null)
        {
            if (AnimationRunning) return;
            StartCoroutine(AnimateBlock(whenOver));
        }

        public void StraightBlock()
        {
            Bump();
            Timer.Start();
            if (CanvasGroup is not null) CanvasGroup.alpha = 1;
            blockageElement.pivot = new Vector2(0.5f, 0.5f);
            blockageElement.localScale = Vector2.one;
        }

        [Button(ButtonStyle.FoldoutButton)]
        public void Unblock(Action whenOver = null, bool forceUnblock = false)
        {
            if (!forceUnblock && AnimationRunning) return;
            Timer.Stop();
            if (CanvasGroup is not null) CanvasGroup.alpha = 0;
            StartCoroutine(AnimateUnblock(whenOver));
        }
        
        public void StraightUnblock()
        {
            Timer.Stop();
            if (CanvasGroup is not null) CanvasGroup.alpha = 0;
            blockageElement.pivot = new Vector2(0.5f, 0.5f);
            blockageElement.localScale = Vector3.zero;
        }
    }

    public enum PDABlockageAnimationType
    {
        VerticalSlide,
        HorizontalSquish,
    }
}