using FL.Battle.Actions;
using System;
using System.Collections.Generic;
using UnityEngine;
using XGame.Database;
using XGame.Framework;
using XGame.Framework.Components;
using XGame.Framework.Time;

namespace FL.Battle.Components.AI
{
    public interface ITrapAIContext
    {
        long UID { get; }
        long MasterId { get; }
        int TableId { get; }
        ITargetSelector Selector { get; }
        ITimeModule Time { get; }
        Vector3 Position { get; }
        VfxComponent Vfx { get; }
        MoveComponent Move { get; }
        GameObject ParticleRoot { get; }
    }
    /// <summary>
    /// AI组件和具体的EntityView绑定，其他Component最好不要尝试获取AI组件
    /// </summary>
    public class TrapAI : Component<ITrapAIContext>
    {
        /// <summary>
        /// 陷阱特效半径
        /// </summary>
        private const float TRAP_VFX_RAIDUS = 2.56f;
        private ITimer _alertTimer;
        private int _loopTimes;
        private EEntityType _targetType;
        private SkillTable _skill;
        private SkillVfxsTable _skillVfxs;

        protected override void OnDispose()
        {
            _skill = null;
            _skillVfxs = null;
            _alertTimer?.Cancel();
            _alertTimer = null;
        }
        public void Start(Vector3 targetPosition, EEntityType targetType)
        {
            _skill = SkillTableRepo.Get(Context.TableId);
            _skillVfxs = SkillVfxsTableRepo.Get(Context.TableId);
            _targetType = targetType;
            Context.ParticleRoot.SetActive(true);
            //Context.AlertTr.localScale = new Vector3(0.5f, 0.5f, 0.1f);
            //Context.BombTr.localScale = new Vector3(0.5f, 0.5f, 0.1f);
            // 飞到目标位置
            var moveArgs = new MoveArgs()
            {
                target = targetPosition,
                speed = _skillVfxs.SkillVfxSpeed,
                timeScale = 1,
                moveType = (EMoveType)(_skillVfxs.SkillVfxMoveType - 1),
                onComplete = OnMoveCompleted
            };
            if (Enum.TryParse<DG.Tweening.Ease>(_skillVfxs.SkillVfxMoveEase, true, out var ease))
            {
                moveArgs.ease = ease;
            }
            Context.Move.MoveTo(moveArgs);
        }
        private void OnMoveCompleted()
        {
            Context.ParticleRoot.SetActive(false);
            var scaleAct = ObjectPool.Acquire<ScaleAction>();
            scaleAct.localScale = Vector3.one * (_skill.Ranges[0] / TRAP_VFX_RAIDUS);
            //陷阱特效包含了陷阱展开的表现，特效时长直接加500毫秒给展开表现
            var vfxArgs = ObjectPool.Acquire<VfxArgs>();
            vfxArgs.vfxName = _skillVfxs.CustomArgs[0];
            vfxArgs.duration = _skillVfxs.SkillVfxTime + 500;
            vfxArgs.action = scaleAct;
            Context.Vfx.Play(vfxArgs);
            {
                var interval = _skillVfxs.SkillVfxInterval;
                _loopTimes = _skillVfxs.SkillVfxTime == -1 ? -1 : _skillVfxs.SkillVfxTime / interval;
                _alertTimer = Context.Time.AddDelayLooperTimer(500, interval, OnAlert, _loopTimes);
            };
        }
        /// <summary>
        /// 警戒事件的定时回调
        /// </summary>
        /// <param name="times"></param>
        private void OnAlert(int times)
        {
            if (times != _loopTimes)
            {
                var target = Context.Selector.FindSync(new FinderInfo()
                {
                    uid = Context.UID,
                    position = Context.Position,
                    radius = _skill.Ranges[0]
                }, _targetType, ETargetFindType.InRangeAlive);
                if (target == null)
                    return;
            }
            _alertTimer.Cancel();
            _alertTimer = null;
            // 达到时间上限直接爆炸，或者有目标触发爆炸
            //TODO 爆炸动作
            var vfxArgs = ObjectPool.Acquire<VfxArgs>();
            vfxArgs.vfxName = _skillVfxs.CustomArgs[1];
            vfxArgs.duration = 500;
            vfxArgs.onFinish = () =>
            //var explodeRange = _skill.Ranges[1] * 2;
            //// 缩放倍数是查询范围的两倍
            //var tween = Context.BombTr.DOScale(new Vector3(explodeRange, explodeRange, 0.1f), 0.5f);
            //tween.onComplete += () =>
            {
                var finder = new FinderInfo()
                {
                    uid = Context.UID,
                    position = Context.Position,
                    radius = _skill.Ranges[1]
                };
                var targets = new List<ITarget>();
                if (Context.Selector.FindTargets(finder, _targetType, ETargetFindType.InRangeAlive, null, ref targets))
                {
                    // 计算受击伤害
                    foreach (var target in targets)
                    {
                        target.Calculation.Damage(-_skill.Damage, Context.MasterId, _skill);
                    }
                }
                EventSingle.Instance.Notify(EventDefine.GameMainMapRemoveSimpleEntity, Context.UID);
            };
            Context.Vfx.Play(vfxArgs);
        }
    }
}
