using System;
using System.Collections.Generic;
using System.Linq;
using Assets.Source.Constants;
using Assets.Source.Content.UI.Canvases;
using Assets.Source.Content.UI.Topdown;
using Assets.Source.Core.Managers;
using Assets.Source.Misc;
using Assets.Source.Patterns.ObjectPool;
using DG.Tweening;
using Spine.Unity;
using UnityEngine;
using UnityEngine.UI;

namespace Assets.Source.Core.Gameplay.Topdown
{
    public class AlienInfo
    {
        public AlienCharacter Character;
        public Dictionary<PlanetPerk, bool> PerksSetup;
    }

    public class AlienTopdown : MonoBehaviour, IPoolObject
    {
        public RectTransform PerksRoot;
        public Animator UIPerksAnimator;
        public CollisionDetector PlayerDetector;
        public UIAlienPerk PerkPrefab;
        public Animator SeatProgressAnimator;
        public Image SeatProgressImage;
        public VFXEffect SeatVFX;
        public SkeletonAnimation Skeleton;

        private float _seatProgress;

        public AlienInfo AlienInfo { get; private set; }

        public event Action OnTakeSeat;

        void Awake()
        {
            InitPlayerDetection();
        }

        public void InitPerks(AlienInfo info)
        {
            if (info == null)
            {
                UIPerksAnimator.gameObject.SetActive(false);
                return;
            }
            AlienInfo = info;
            for (var i = info.PerksSetup.ToList().Count - 1; i >= 0; i--)
            {
                var p = info.PerksSetup.ToList()[i];
                var perk = PerkPrefab.Spawn();
                perk.transform.SetParent(PerksRoot, false);
                perk.Icon.sprite = p.Key.Icon;
            }
            Skeleton.skeleton.SetSkin(info.Character.SpineSkinName);
        }

        void Update()
        {
            UpdateSeatProgress();
        }

        private void UpdateSeatProgress()
        {
            var player = GameManagerTopdown.Instance.Player;
            var playerPos = player.transform.position;
            var dist = playerPos.DistTo(transform.position);
            if (dist > 2.9f || player.SeatAlienInfo != null)
            {
                _seatProgress -= Time.deltaTime;
                if (_seatProgress < 0)
                    _seatProgress = 0;
                SeatProgressAnimator.SetBool("Active", false);
                return;
            }
            else
            {
                if (GameManagerTopdown.Instance.InputEnabled)
                    _seatProgress += Time.deltaTime * (Get.DebugSettings.FastSeat ? 5 : 0.35f);
                SeatProgressAnimator.SetBool("Active", true);
                SeatProgressImage.fillAmount = _seatProgress;
            }
            if (_seatProgress >= 1)
            {
                TakeSeat(playerPos, player);
            }
        }

        private void TakeSeat(Vector3 playerPos, PlayerShipTopdown player)
        {
            gameObject.SetActive(false);
            var seatVfx = SeatVFX.Spawn(transform.position);
            seatVfx.transform.DOMove(playerPos, 0.2f);
            if (AlienInfo != null)
            {
                var panel = UITopdownCanvas.Instance.Controller.PanelLayer.Open<UICharacterAlienPanel>();
                panel.InitFrom(AlienInfo);
            }
            player.SeatAlienInfo = AlienInfo;
            player.SeatAlien = this;
            player.SetNextDestination();
            if (AlienInfo != null)
            {
                var img = Get.MainUI.DialogueLayer.Get<UITopdownInventoryDialogue>().AlienCharacterImage;
                img.sprite = AlienInfo.Character.UICharacterSprite;
                img.gameObject.SetActive(true);
            }
            AudioManager.Instance.PlayPlayerPickedUpAlien();

            OnTakeSeat?.Invoke();
        }

        private void InitPlayerDetection()
        {
            UIPerksAnimator.gameObject.SetActive(false);
            PlayerDetector.OnTEnter2D += c =>
            {
                var player = c.GetComponentInParent<PlayerShipTopdown>();
                if (player != null)
                {
                    UIPerksAnimator.gameObject.SetActive(true);
                    UIPerksAnimator.SetTrigger(GeneralConstants.ANIM_PARAM_ACTIVATE);
                }
            };
            PlayerDetector.OnTExit2D += c =>
            {
                var player = c.GetComponentInParent<PlayerShipTopdown>();
                if (player != null)
                    UIPerksAnimator.SetTrigger(GeneralConstants.ANIM_PARAM_DEACTIVATE);
            };
        }

        public void OnSpawnFromPool()
        {
        }

        public void OnReturnToPool()
        {
            _seatProgress = 0;
        }
    }
}
