using Thousandto.Code.Center;
using Thousandto.Code.Global;
using Thousandto.Code.Logic.LocalPlayerBT;
using Thousandto.Core.Asset;
using Thousandto.Plugins.Common.UniScene;
using System;
using System.Collections.Generic;

using System.Text;
using UnityEngine;

namespace Thousandto.Code.Logic
{
    /// <summary>
    /// 点击操作的处理器
    /// </summary>
    public class HitHandler
    {
        #region//常量处理
        //有效射线距离
        private const float PickRaycastDistance = 60;
        //有效射线的半径
        private const float PickRayRadius = 0.4f;
        #endregion

        #region//私有变量
        //是否点击了地面
        private bool _touchGround = false;
        //点击了地面的时间
        private float _touchTime = 0;
        //当前场景的主摄像机
        private Camera _curCamera = null;
        //点击地面的特效
        private FGameObjectVFX _hitGroundVfx = null;
        #endregion

        #region//公共接口方法

        //刷新信息
        public void Refresh( Camera camera)
        {
            _curCamera = camera;
        }

        public void Reset()
        {
            _curCamera = null;
            if (_hitGroundVfx != null)
            {
                _hitGroundVfx.Destroy();
                _hitGroundVfx = null;
            }
        }

        //点击操作
        public void OnHit(Vector2 fingerPos)
        {
            if (IsValid())
            {
                Ray ray = _curCamera.ScreenPointToRay(fingerPos);
                Vector3 hitStart = ray.origin;
                Vector3 hitEnd = hitStart + ray.direction * PickRaycastDistance;
                //以点击点为圆心的区域,查找所有的Collider
                var hitAllObjs = Physics.SphereCastAll(ray, PickRayRadius, PickRaycastDistance, LayerUtils.SceneObject_Mask);
                var isHitChar = false;
                if (hitAllObjs != null && hitAllObjs.Length > 0)
                {
                    //当点击了角色目标后的处理
                    var charList = ConvertToCharacterList(hitAllObjs);
                    if (charList.Count > 0)
                    {
                        LocalPlayer lp = GameCenter.GameSceneSystem.GetLocalPlayer();
                        Character hitChar = null;
                        //针对所有目标对象,进行处理,优先检查是否点击了NPC(处理一大堆角色围着NPC的问题)
                        for (int i = 0; i < charList.Count; i++)
                        {
                            if (charList[i] is Npc)
                            {
                                hitChar = charList[i];
                                var npc = charList[i] as Npc;
                                if (lp != null) lp.SetCurSelectedTargetId(npc.ID, false);
                                PlayerBT.Talk.Write(npc);
                                isHitChar = true;
                                break;
                            }
                            else if (charList[i] is Collection)
                            {
                                hitChar = charList[i];
                                if (lp != null) lp.SetCurSelectedTargetId(hitChar.ID, false);
                                PlayerBT.Collect.Write();
                                isHitChar = true;
                                break;
                            }
                        }
                        
                        //如果没有特殊的处理,那么就直接找到可以被选择的角色
                        if (hitChar == null)
                        {
                            for (int i = 0; i < charList.Count; i++)
                            {
                                if (charList[i].CanBeSelect)
                                {
                                    if (lp != null) lp.SetCurSelectedTargetId(charList[i].ID, false);
                                    isHitChar = true;
                                    break;
                                }
                            }
                        }
                    }
                }
#if USE_PC_MODEL
                if(!isHitChar)
                {
                    RaycastHit hit;
                    //如果没有点击到物体,那么就检测是否点击地面
                    bool rePicked = Physics.Raycast(ray, out hit, PickRaycastDistance, LayerUtils.LayerToMask(LayerUtils.Trigger));
                    if (rePicked)
                    {
                        OnHitGround(hit);
                    }
                }
#endif
            }
        }

#endregion

#region//私有方法

        //临时存储被点击的物体
        private List<Character> _tempHitCharacterList = new List<Character>();
        //获取可被点击的物体
        private List<Character> ConvertToCharacterList(RaycastHit[] hits)
        {
            _tempHitCharacterList.Clear();
            for (int i = 0; i < hits.Length; i++)
            {
                var go = hits[i].collider.gameObject;
                if (go != null)
                {
                    if (go.layer == LayerUtils.RemotePlayer || go.layer == LayerUtils.Monster)
                    {
                        var ea = go.GetComponent<FRealObjectScript>();
                        if (ea != null)
                        {
                            var skin = ea.GetSkin();
                            if (skin != null && skin.LogicObject != null && skin.LogicObject is Character)
                            {
                                _tempHitCharacterList.Add(skin.LogicObject as Character);
                            }
                        }
                    }
                }
            }
            return _tempHitCharacterList;
        }


        //点击了地面
        private void OnHitGround(RaycastHit hit)
        {
            _touchGround = true;
            _touchTime = Time.time;
            var lp = GameCenter.GameSceneSystem.GetLocalPlayer();
            if (lp == null)
            {
                return;
            }
            //如果已经关闭了点击地面移动
            if (GameCenter.GameSetting.GetSetting(GameSettingKeyCode.CheckGroundMove) == 0)
                return;
            float h = 0.2f;
            PlayerBT.Owner.GetHeightOnTerrain(hit.point.x, hit.point.z, out h);
            var pos = hit.point;
            var height = 0f;
            if(!lp.Scene.GetHeightOnTerrain(pos.x, pos.z, out height))
            {
                //无法到达的位置
                return;
            }
            pos.y = height;
            if (lp.Scene.navigator.IsBlocked(pos))
            {
                //无法到达的位置
                return;
            }
            //点击地面播放特效
            if (_hitGroundVfx == null || _hitGroundVfx.IsFreeze)
            {
                _hitGroundVfx = new FGameObjectVFX(ModelTypeCode.OtherVFX, 10295, true, false);
                _hitGroundVfx.SetLayer(LayerUtils.Default, true);
                _hitGroundVfx.SetPosition(pos);
                _hitGroundVfx.IsFinishDestroy = false;
                _hitGroundVfx.StopIsDeactive = true;
                _hitGroundVfx.Play(1);
            }
            else
            {
                _hitGroundVfx.SetPosition(pos);
                _hitGroundVfx.Stop();
                _hitGroundVfx.Play(1);
            }
            PlayerBT.MapMove.Write(-1, pos, 0.1f, true, false);
        }

        //是否有效
        private bool IsValid()
        {
            return _curCamera != null && PlayerBT.IsInitPlayerBD;
        }
#endregion

    }
}