using System;
using System.Collections;
using System.Collections.Generic;
using UnityEngine;



public partial class BattleController : MonoBehaviour
{
    /// 游戏是否已开始
    /// </summary>
    public bool GameStarted => m_State != State_NotStarted;

    /// <summary>
    /// 状态
    /// </summary>
    protected int m_State;
    public int state => m_State;
    
    public const int State_NotStarted = 0;//游戏还没开始
    public const int State_Gaming = 1;//游戏中
    public const int State_End = 2;//游戏结束
    
    /// <summary>
    /// 动态物件父物体
    /// </summary>
    Transform m_DynamicWidgetsNode;
    public Transform dynamicWisgetsNode => m_DynamicWidgetsNode;

    /// <summary>
    /// 地图ID,关卡ID
    /// </summary>
    public int mapId;

    /// <summary>
    /// 玩家用户ID
    /// </summary>
    protected long m_PlayerId = 1;
    public long myPlayerId => m_PlayerId;

    private float m_GameStartTime;
    
    private int m_GameStartFrame;
    
    /// <summary>
    /// 游戏当前时间
    /// </summary>
    public float time
    {
        get
        {
            if (!GameStarted)
                return 0;
            
            return Time.time - m_GameStartTime;
        }
    }
    /// <summary>
    /// 更新间隔时间
    /// </summary>
    public float deltaTime => Time.deltaTime;
    /// <summary>
    /// 游戏当前帧
    /// </summary>
    public int frameCount => Time.frameCount - m_GameStartFrame;
    
    /// <summary>
    /// 3D场景
    /// </summary>
    private Battle3DScene m_Battle3DScene;
    public Battle3DScene battle3DScene => m_Battle3DScene;

    public const string Layer_Default = "Default";
    public const string Layer_TransparentFX = "TransparentFX";
    public const string Layer_IgnoreRaycast = "Ignore Raycast";

    public static int layerDefault => LayerMask.NameToLayer(Layer_Default);
    public static int layerTransparentFX => LayerMask.NameToLayer(Layer_TransparentFX);
    public static int layerIgnoreRaycast => LayerMask.NameToLayer(Layer_IgnoreRaycast);
    
    public static LayerMask layerIgnoreRaycastMask=>LayerMask.GetMask(Layer_IgnoreRaycast);
    public static LayerMask layerDefaultMask => LayerMask.GetMask(Layer_Default); 
    public static LayerMask layerTransparentFXMask => LayerMask.GetMask(Layer_TransparentFX);
   
    /// <summary>
    /// 战斗结束事件
    /// </summary>
    public Action<BattleResult> onBattleFinish;

    /// <summary>
    /// 数据配置
    /// </summary>
    public virtual DataConfig dataConfig { get;  }

    
    protected virtual void Awake ()
	{
        // 创建动态物件节点
        GameObject dynamicNode = new GameObject("动态物件");
        dynamicNode.transform.SetParent(this.transform, false);
        this.m_DynamicWidgetsNode = dynamicNode.transform;
    }

    
    public void Init (BattleData battleData,long myPlayerId,Battle3DScene battle3DScene)
    {
        //startCountDown = false;
        m_State = State_NotStarted;
        m_Battle3DScene = battle3DScene;
        m_PlayerId = myPlayerId;
        
        if(battleData != null &&  battleData.mapData != null)
        {
            this.mapId = battleData.mapData.mapId;
        }

        //GameDebug.LogError($"battleController init m_PlayerId:{m_PlayerId}");
        LateInit(battleData);
    }
    
    protected virtual void LateInit(BattleData battleData)
    {
        /*ViewEntity[] mapEditEntities = battle3DScene.GetComponentsInChildren<ViewEntity>();

        //玩家的编辑物品
        for (int i = 0; i < mapEditEntities.Length; i++)
        {
            ViewEntity entity = mapEditEntities[i];

            //GameDebug.Log($"LateInit entity:{entity.name}");
/*            if (entity.entityType == EntityType.npc)
            {
                NpcEntity npc = entity as NpcEntity;
                
                m_NPCs.Add(npc);
                npc.onNPCResult = this.OnNpcResult;
            }#1#
        }*/
    }


    /// <summary>
    /// 开始游戏
    /// </summary>
    public virtual void GameStart()
    {
        if (!GameStarted)
        {
            m_State = State_Gaming;
            
            this.m_GameStartTime = Time.time;
            this.m_GameStartFrame = Time.frameCount;
        }
        //battle3DScene.ui.ShowJoyStick();
        //battle3DScene.ui.HidePoinerAnim();
        
        
    }

    public static bool CheckBlockWithObj(Vector3 fromPos, Vector3 toPos,out RaycastHit hit,LayerMask layer)
    {
        Vector3 checkBeginPos = fromPos;
        Vector3 checkVec = toPos - fromPos;

        UnityEngine.Ray checkRay = new UnityEngine.Ray(checkBeginPos,checkVec);

        bool rayCast = Physics.Raycast(checkRay,out hit , checkVec.magnitude,layer);

        if (rayCast)
        {
#if UNITY_EDITOR
            GameDebug.LogShowy($"layer：{(int)layer}  检测碰撞到:{hit.collider.gameObject.name}");
#endif
            return true;
        }
#if UNITY_EDITOR
        GameDebug.LogShowy($"layer：{(int)layer}  无碰撞");
#endif
        return false;
    }

    
    protected virtual void Update ()
    {
        if (!GameStarted)
        {
            return;
        }
        
        if(Time.frameCount % 10 == 0)
        {
           
            if (m_State != State_End && battleFinished)
            {
                m_State = State_End;

                BattleFinish();
            }
            
        }
      
    }

    void BattleFinish()
    {
    
        var battleResult = GetBattleResult();
        onBattleFinish?.Invoke(battleResult);
    }
      public virtual bool battleFinished { get; }
    

    public int Round(float value)
    {
        return (int)(value + 0.5f);
    }

    public virtual BattleResult GetBattleResult()
    {
        BattleResult result = new BattleResult();
        result.level = this.mapId;
        
        /*result.score = saveCount;

        //int winMinCount = 1;//this.nPCs.Count / 2;
        

        int npcCount = this.nPCs.Count;
        
        int star1 = Round(npcCount / 3f);
        int star2 = Round(npcCount * 2 / 3f);
        int star3 = npcCount;

        star1 = star1 < 1 ? 1 : star1;
        
        result.win = true;
        
        if (saveCount >= star3)
            result.star = 3;
        else if (saveCount >= star2)
            result.star = 2;
        else if (saveCount >= star1)
            result.star = 1;
        else
            result.win = false;*/
        
        return result;
    }

    private void OnDrawGizmos()
    {
        if (Input.GetMouseButton(0))
        {
            if (this.battle3DScene && battle3DScene.mainCamera)
            {
                Gizmos.DrawRay(this.battle3DScene.mainCamera.ScreenPointToRay(Input.mousePosition));
            }
        }
    }

}