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


public static class ViewEntityType
{
    public const int player = 0;
    public const int box = 1;
    public const int ball = 2;
    public const int result = 3;
    public const int police = 4;
    public const int plate = 5;
    public const int giantKiller = 6;
    public const int cameraTrigger = 7;
    public const int camerasManager = 8;
}


public partial class HoppingBattleController : BattleController
{
    public HoppingBattle3DScene HoppingBattle3DScene => this.battle3DScene as HoppingBattle3DScene;
    
    private HoppingDataConfig m_DataConfig;
    private HoppingDataConfig hoppingDataConfig => dataConfig as HoppingDataConfig;
    
    public override DataConfig dataConfig
    {
        get { return m_DataConfig; }
    }
    
    public PlayerEntity Me { get => m_Me; }
    private PlayerEntity m_Me;
    
    public static LayerMask layerPlayerMask => LayerMask.GetMask("Player");
    public static int layerPlayer => LayerMask.NameToLayer("Player");
    public static LayerMask layerWallMask => LayerMask.GetMask("Wall");
    public static int layerWall => LayerMask.NameToLayer("Wall");
    public static LayerMask layerTriggerMask => LayerMask.GetMask("Trigger");
    public static int layerTrigger => LayerMask.NameToLayer("Trigger");
    public static LayerMask layerHeadMask => LayerMask.GetMask("Head");
    public static int layerHead => LayerMask.NameToLayer("Head");
    
    public static LayerMask layerStickMask => LayerMask.GetMask("Stick");
    public static int layerStick => LayerMask.NameToLayer("Stick");
    
    public float minX => HoppingBattle3DScene.minX;
    public float minZ => HoppingBattle3DScene.minZ;
    public float maxX => HoppingBattle3DScene.maxX;
    public float maxZ => HoppingBattle3DScene.maxZ;
    
    List<MatchEntity> m_Matches = new List<MatchEntity>();
    public List<MatchEntity> matches => m_Matches;

    protected override void LateInit(BattleData battleData)
    {
        this.m_DataConfig = battleData.dataConfig as HoppingDataConfig;
   
        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.GetType() == typeof(MatchEntity))
            {
                m_Matches.Add(entity as MatchEntity);
            }
        }
    }

    public override void GameStart()
    {
        base.GameStart();

    }

    public Vector3 ClampPos(Vector3 pos, float bargin)
    {
        pos.x = Mathf.Clamp(pos.x, HoppingBattle3DScene.minX+bargin, HoppingBattle3DScene.maxX-bargin);
        pos.z = Mathf.Clamp(pos.z, HoppingBattle3DScene.minZ+bargin, HoppingBattle3DScene.maxZ-bargin);

        return pos;
    }
    protected override void Update()
    {
        base.Update();

        if (m_Fired && !m_BattleFinished)
        {
            bool allMatchFireEnd = true;
            foreach (var mMatch in m_Matches)
            {
                if (mMatch.inFire)
                {
                    allMatchFireEnd = false;
                }
            }

            if (allMatchFireEnd)
            {
                m_BattleFinished = true;
            }
        }
    }

  
}

public partial class HoppingBattleController
{
    /// <summary>
    /// 是否已点火
    /// </summary>
    private bool m_Fired;
    
    
    public void OnPointerDown(Vector3 position)
    {
        if (GameStarted && !battleFinished && !m_Fired)
        {
            var ray = HoppingBattle3DScene.mainCamera.ScreenPointToRay(Input.mousePosition);

            bool raycast = Physics.Raycast(ray, out RaycastHit hit, 10000, HoppingBattleController.layerHeadMask);
            if (raycast)
            {
                GameDebug.Log($"hit head ");
                var match = hit.collider.GetComponentInParent<MatchEntity>();
                if (match)
                {
                    match.Fire();
                    m_Fired = true;
                }
            }
            else
            {
                GameDebug.Log($"not hit head ");
                bool raycast2 = Physics.Raycast(ray, out RaycastHit hit2, 10000, HoppingBattleController.layerStickMask);
                if (raycast2)
                {               
                    var match = hit2.collider.GetComponentInParent<MatchEntity>();
                    match.Rotate();
                    
                }
            }
        }

    }

    public void OnPointerMove(Vector3 dir)
    {
        if (!GameStarted) return;
        
        //GameDebug.Log($"move:{dir}");
        //this.Me.OptMove(dir);
    }

    public void OnPointerUp(Vector3 position)
    {
       
    }

    public bool CheckBlockWithWall(Vector3 fromPos, Vector3 toPos)
    {
        return CheckBlockWithWall(fromPos, toPos, out Vector3 blockPos);
    }
        
    public  bool CheckBlockWithWall(Vector3 fromPos, Vector3 toPos,out Vector3 blockPos)
    {
        var res = CheckBlockWithObj(fromPos,toPos,out RaycastHit hit,layerWallMask );
        blockPos = hit.point;
        return res;
    }
    public  bool CheckBlockWithObj(Vector3 fromPos, Vector3 toPos,out RaycastHit hit,LayerMask layer)
    {
        Vector3 checkBeginPos = fromPos;
        Vector3 checkVec = toPos - fromPos;

        checkBeginPos.y = 1;
        checkVec.y = 0;
        
        Ray checkRay = new Ray(checkBeginPos,checkVec);

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

        if (rayCast)
        {
//          GameDebug.LogShowy($"检测碰撞到墙壁:{hit.collider.gameObject.name}");
            return true;
        }
        return false;
    }
}


public partial class HoppingBattleController
{
    private bool m_BattleFinished;
    /// <summary>
    /// 是否结束
    /// </summary>
    public override bool battleFinished
    {
        get
        {
            return m_BattleFinished;
        }
    }
    
    /// <summary>
    /// 获取结果数据
    /// </summary>
    /// <returns></returns>
    public override BattleResult GetBattleResult()
    {
        BattleResult result = new BattleResult();
        
        result.level = this.mapId;

        int score = 0;

        result.score = score;
        result.star = 3;

        bool win = true;
        foreach (var match in matches)
        {
            if (!match.fired)
            {
                win = false;
            }   
        }

        result.win = win;
        
        //result.win =  this.Me.state == PlayerState.State_Win;
        
        GameDebug.Log($"战斗关卡{result.level} 结果：{result.win}  score:{score}");
        return result;
    }

}