using UnityEngine;
using System.Collections;
using System.Collections.Generic;
using System;
using UnityEngine.AI;
using AX.MessageSystem;
using AX.InputSystem;
using AX.NetworkSystem;

public class AdjustRotationWhileEndPathfindData
{
    public long SenderId;
    public long GameObjId;
    public Vector3 EndRotation;
    public Vector3 Hitpoint;
}

[RequireComponent(typeof(NavMeshAgent))]
public class AgentController : MonoBehaviour
{
    private GameObject pointer;
    private static GameObject pointerObj;
    private NavMeshAgent agent;
    private NavMeshPath NavMeshPath;
    private NavMeshQueryFilter filter;
    private Vector3 pointhit;//瀵昏矾鐐? 
    private GameObject hitObj;//鐐瑰嚮鐨勫璞?
    public List<Vector3> corners = new List<Vector3>();
    private Vector3 lastPosition;
    public bool pathFindEnable;
    private bool begionmove = false;
    private BaseGameObjInfo gameobjinfo;
   // public bool FixedArmFlag;
    private void Awake()
    {

    }
    void Start()
    {
        pathFindEnable = true;
        if (!pointerObj)
        {
            pointer = Resources.Load<GameObject>("Particle");
            pointerObj = Instantiate(pointer, transform.position, Quaternion.identity);
            pointhit = transform.position;
        }
        NavMeshPath = new NavMeshPath();
        agent = GetComponent<NavMeshAgent>();
        filter = new NavMeshQueryFilter();
        filter.agentTypeID = agent.agentTypeID;
        filter.areaMask = agent.areaMask;
        gameobjinfo = GetComponent<BaseGameObjInfo>();
    }


    //check for mouse input
    void Update()
    {
        if (begionmove==true)
        {
            if (gameobjinfo.gameObjType == CloneObjType.fireman)
            {
                if (Vector3.Distance(transform.position, pointhit) < 0.5f)
                {
                    AdjustRotationWhileEndPathfindData arg = new AdjustRotationWhileEndPathfindData
                    {
                        SenderId = CurrentUserInfo.mySelf.Id,
                        GameObjId = gameobjinfo.gameObjID,
                        Hitpoint=pointhit,
                        EndRotation = new Vector3(transform.rotation.eulerAngles.x,
                        transform.rotation.eulerAngles.y, transform.rotation.eulerAngles.z)
                    };
                    NetworkManager.Default.SendAsync("ABJUST_ROTATION_SYNC",arg);
                    begionmove = false;
                }
            }
            else if (GetComponent<TruckMessage>())
            {
                if (Vector3.Distance(transform.position, pointhit) < 5f)
                {
                    AdjustRotationWhileEndPathfindData arg = new AdjustRotationWhileEndPathfindData
                    {
                        SenderId = CurrentUserInfo.mySelf.Id,
                        GameObjId = gameobjinfo.gameObjID,
                        Hitpoint = pointhit,
                        EndRotation = new Vector3(transform.rotation.eulerAngles.x,
                       transform.rotation.eulerAngles.y, transform.rotation.eulerAngles.z)
                    };
                    NetworkManager.Default.SendAsync("ABJUST_ROTATION_SYNC", arg);
                    begionmove = false;
                }
            }
           
        }
    }
    void OnEnable()
    {
        MessageDispatcher.AddListener("PATH_FINDING_COMMAND", PathFinding);
    }

    void OnDisable()
    {
        MessageDispatcher.RemoveListener("PATH_FINDING_COMMAND", PathFinding);
    }

    void OnDestroy()
    {
        MessageDispatcher.RemoveListener("PATH_FINDING_COMMAND", PathFinding);
    }
    private void PathFinding(IMessage obj)
    {
        if (SelectedObjs.selectedCharacters.Contains(gameObject) 
            || SelectedObjs.selectedObj == gameObject
            || SelectedObjs.selectedRolePlay == gameObject //瑙掕壊
            )
        {
            if (pathFindEnable /*&& !FixedArmFlag*/)
            {
                if (GetComponent<FireRobotController>()) 
                {
                    if (GetComponent<FireRobotController>().WorkType== FireRobotSkill.出水||
                        GetComponent<FireRobotController>().WorkType == FireRobotSkill.出泡沫) 
                    {
                        if (GetComponent<FireRobotLayWaterHose>().remainlenght < 0.5f)
                        {
                            return;
                        }
                    }
                }
                begionmove = true;
                var data = (PathFindingCmdArgs)obj.Data;
                pointhit = data.hitPoint;
                pointerObj.transform.position = pointhit;
                StopAllCoroutines();
                corners.Clear();
                bool flag = setPathCorners(transform.position, pointhit, corners);
                if (flag)
                {
                    hitObj = EntitiesManager.Instance.GetEntityByID(data.gameObjID);
                    //setFloorMessage(hitObj.transform);
                    removeNoMainCorners(corners);
                    StartCoroutine(GoToDestination());
                    var objinfo = GetComponent<BaseGameObjInfo>();
                    if (objinfo.gameObjType != CloneObjType.fireman && objinfo.gameObjType != CloneObjType.ObligationFireman)
                    {
                        MessageDispatcher.SendMessage(GetComponent<BaseGameObjInfo>().GameObjID, "SetpathIndex");
                    }
                    //瀵昏矾鍚屾
                    PathFindSyncData pathsync = new PathFindSyncData();
                    pathsync.SendUserID = CurrentUserInfo.mySelf.Id;
                    pathsync.TargetPoint = data.hitPoint;
                    pathsync.gameObjID = GetComponent<BaseGameObjInfo>().gameObjID;
                    pathsync.gameObjType = GetComponent<BaseGameObjInfo>().gameObjType;
                    pathsync.UserID = GetComponent<BaseGameObjInfo>().UserID;
                    NetworkManager.Default.SendAsync(/*CurrentUserInfo.mySelf.Id,*/ "PATHFIND_SYNC", pathsync);
                }
            }
            else
            {
                LoadPromptWin.Instance.LoadTextPromptWindow("不能移动", 1f);
            }
        }
    }

    //loops over path positions, sets the 
    //current target destination of this agent
    IEnumerator GoToDestination()
    {
        int i = 1;
        while (i < corners.Count)
        {
            NavMeshPath NavMeshPath = new NavMeshPath();
            NavMesh.CalculatePath(transform.position, corners[i], filter, NavMeshPath);
            agent.SetDestination(corners[i]);
            while (agent.pathPending)
                yield return null;

            //wait until we reached this position
            float remain = Vector3.Distance(transform.position, corners[i]);
            while (remain == Mathf.Infinity || remain - agent.stoppingDistance > float.Epsilon)
            {
                remain = Vector3.Distance(transform.position, corners[i]);
                yield return null;
            }
            var objinfo = GetComponent<BaseGameObjInfo>();
            if (objinfo.gameObjType == CloneObjType.fireman || objinfo.gameObjType == CloneObjType.ObligationFireman)
            {
                //setFloorMessage();
            }
            i++;
        }
    }
    private void setFloorMessage()
    {
        //璁剧疆瀵昏矾瀵硅薄妤煎眰灞炴€?
        Vector3 adPos2 = transform.position;
        Ray ray = new Ray(adPos2, -Vector3.up);
        RaycastHit hit = new RaycastHit();
        if (Physics.Raycast(ray, out hit, LayerMask.NameToLayer("PathFinding")))
        {
            if (hit.transform.gameObject.GetComponent<CloneGameObjInfo>())
            {
                CloneGameObjInfo msg = GetComponent<CloneGameObjInfo>();
                CloneGameObjInfo hitinfo = hit.transform.gameObject.GetComponent<CloneGameObjInfo>();
                msg.buildNum = hitinfo.buildNum;
                msg.floorNum = hitinfo.floorNum;
                msg.interlayerNum = hitinfo.interlayerNum;

                if (!SelectedObjs.selectedCharacters.Contains(gameObject))
                {
                    // msg.UpdateFloorEnabled(GlobalVariable.CurrentFloor);
                }
                return;
            }
        }
    }
    bool setPathCorners(Vector3 sourcePosition, Vector3 targetPosition, List<Vector3> corners)
    {
        NavMeshPath NavMeshPath = new NavMeshPath();
        NavMesh.CalculatePath(sourcePosition, targetPosition, filter, NavMeshPath);
        Vector3[] b = NavMeshPath.corners;
        if (b.Length == 1)
        {
            //Debug.Log("鏂");         
            return false;
        }
        if (NavMeshPath.status == NavMeshPathStatus.PathComplete)
        {
            //Debug.Log("PathComplete");
            foreach (Vector3 corner in b)
            {
                if (!corners.Contains(corner))
                {
                    corners.Add(corner);
                }
            }
            return true;
        }
        else if (NavMeshPath.status == NavMeshPathStatus.PathPartial)
        {
            if (Vector3.Distance(b[b.Length - 1], lastPosition) == 0)
            {
                //Debug.Log("(" + sourcePosition.x + "," + sourcePosition.y + "," + sourcePosition.z + ")銆侊紙" + lastPosition.x + "," + lastPosition.y + "," + lastPosition.z + ")");
                //Debug.Log("杩涘叆姝诲惊鐜?);

                return false;
            }
            foreach (Vector3 corner in b)
            {
                if (!corners.Contains(corner))
                {
                    corners.Add(corner);
                }
            }
            lastPosition = sourcePosition;
            return setPathCorners(b[b.Length - 1], targetPosition, corners);
        }
        else if (NavMeshPath.status == NavMeshPathStatus.PathInvalid)
        {
            return false;
        }
        else
        {
            return false;
        }
    }
    void removeNoMainCorners(List<Vector3> corners)
    {
        for (int i = 0; i < corners.Count - 1; i++)
        {
            for (int k = corners.Count - 2; k > i; k--)
            {
                float distance = Vector3.Distance(corners[i], corners[k]);//璁$畻涓ょ偣鐨勮窛绂?
                if (distance < 5)
                {
                    for (int j = k; j > i; j--)
                    {
                        corners.RemoveAt(j);
                    }
                    break;
                }
            }
        }
    }
}