using AX.MessageSystem;
using System;
using System.Collections.Generic;
using UnityEngine;

[RequireComponent(typeof(BaseGameObjInfo))]
public class ObjSelectCtrl : MonoBehaviour
{
    public bool selected;//是否被选中
    public int Layer;
    void Awake()
    {
    }
    public void AddRecordEventSelect(RecordEventType type, GameObject selectobj)
    {
        if (ReplaySetting.PlayStatus == PlayStatus.isEditor && RecordManager.Instance.recordStatus == RecordStatus.normal)
        {
            var eventData = new EventData
            {
                time = RecordManager.Instance.RecordTimer,
                cloneObjType = GetComponent<BaseGameObjInfo>().gameObjType,
                eventType = type,
                json = selectobj == null ? "null" : selectobj.name
            };

            RecordManager.Instance.jsonData.eventDataList.Add(eventData);
        }
    }
    void OnEnable()
    {
        MessageDispatcher.AddListener("RADIO_SELECTED_COMMAND", RadioSelect);//单选选中处理

        MessageDispatcher.AddListener("CANCEL_SELECTED_COMMAND", EscCancelSelected);//ESC取消选中处理

        //接收DrawRectSelectRange中框选画框处理时,处理框选是否选中逻辑发出的消息:处理框选操作之前选中对象的取消选中
        MessageDispatcher.AddListener("CANCEL_OBJ_SELECTED", CancelObjSelected);
        //接收DrawRectSelectRange中框选画框处理时,处理框选是否选中逻辑发出的消息:处理框选操作选中对象
        MessageDispatcher.AddListener("OBJ_RECT_SELECTED", ObjRectSelected);
    }

    void OnDisable()
    {
        MessageDispatcher.RemoveListener("RADIO_SELECTED_COMMAND", RadioSelect);

        MessageDispatcher.RemoveListener("CANCEL_SELECTED_COMMAND", EscCancelSelected);

        MessageDispatcher.RemoveListener("CANCEL_OBJ_SELECTED", CancelObjSelected);
        MessageDispatcher.RemoveListener("OBJ_RECT_SELECTED", ObjRectSelected);
    }

    void OnDestroy()
    {
        MessageDispatcher.RemoveListener("RADIO_SELECTED_COMMAND", RadioSelect);

        MessageDispatcher.RemoveListener("CANCEL_SELECTED_COMMAND", EscCancelSelected);

        MessageDispatcher.RemoveListener("CANCEL_OBJ_SELECTED", CancelObjSelected);
        MessageDispatcher.RemoveListener("OBJ_RECT_SELECTED", ObjRectSelected);
    }

    private void RadioSelect(IMessage obj)
    {
        var gameObjID = (long)obj.Sender;
        var hitObj = EntitiesManager.Instance.GetEntityByID(gameObjID);

        if (hitObj == gameObject)
        {
            if (SelectedObjs.selectedCharacters.Count>0) 
            {
                if (gameObject != SelectedObjs.selectedCharacters[0])
                {
                    if(FireManSkillsPanel.GetInstance.gameObject.activeInHierarchy)
                    {//目前是单选消防员状态
                        if (SelectedObjs.selectedCharacters[0].GetComponent<FireManMessage>().workType == FireManSkills.SprayWater)
                        {
                            if (!SelectedObjs.selectedCharacters[0].GetComponentInChildren<ParticleControlOfType>())
                            {//单选的是消防员但是没有出水
                                //点击出水按钮但是没有选择出水类型导致
                                SelectedObjs.selectedCharacters[0].GetComponent<FireManMessage>().workType = FireManSkills.None;
                            }
                        }
                    }
                   
                }
            }
           
            clearSelection();

            if (hitObj.tag != "Player")
            {//除消防员外其他可选中物体的单选
                SelectedObjs.selectedObj = hitObj;
            }
            else
            {//消防员单选
                if (!SelectedObjs.selectedCharacters.Contains(hitObj))
                    SelectedObjs.selectedCharacters.Add(hitObj);
            }

            DoSelect(gameObject);
            //AttributeSetting.Instance.ShowButton(hitObj);

            if (!RecordEvent.IsReplay())
                MessageDispatcher.SendMessage("SelectChange", gameObject);
        }
    }

    private void EscCancelSelected(IMessage obj)
    {
        if (SelectedObjs.selectedObj == gameObject || SelectedObjs.selectedCharacters.Contains(gameObject)) 
        {
            if (SelectedObjs.selectedCharacters.Count > 0)
            {//目前是单选消防员状态
                //if (FireManSkillsPanel.GetInstance.gameObject.activeInHierarchy) 
                {
                    if (SelectedObjs.selectedCharacters[0].GetComponent<FireManMessage>().workType == FireManSkills.SprayWater)
                    {//当前是出水技能但是没有水粒子
                        if (!SelectedObjs.selectedCharacters[0].GetComponentInChildren<ParticleControlOfType>())
                        {
                            SelectedObjs.selectedCharacters[0].GetComponent<FireManMessage>().workType = FireManSkills.None;
                        }
                    }

                }
            }
            clearSelection();
        }
            
    }

    private void CancelObjSelected(IMessage obj)
    {
        //AddRecordEventSelect(RecordEventType.CancelObjSelected);
        //如果框选之前有不能框选的物体被单选选中,框选时,需要取消它的选中
        if (SelectedObjs.selectedObj)
        {
            DoDisSelect(SelectedObjs.selectedObj);
            SelectedObjs.selectedObj = null;
        }

        var gameObj = (GameObject)obj.Sender;
        //如果框选之前有能被框选的物体选中了,且这些物体不在这次框选范围内,取消其的选中
        if (SelectedObjs.selectedCharacters.Contains(gameObj))
        {
            DoDisSelect(gameObj);
            SelectedObjs.selectedCharacters.Remove(gameObj);
        }

    }

    private void ObjRectSelected(IMessage obj)
    {
        //AddRecordEventSelect(RecordEventType.ObjRectSelected);
        var gameObj = (GameObject)obj.Sender;

        //框选范围内的物体,如果没有选中,进行选中处理,如果已经被选中,则不做处理,保持原来选中状态
        if (!SelectedObjs.selectedCharacters.Contains(gameObj))
        {
            SelectedObjs.selectedCharacters.Add(gameObj);
            DoSelect(gameObj);
        }
        if (SelectedObjs.selectedCharacters.Count>1)
        {
            if (FireManSkillsPanel.GetInstance.gameObject.activeInHierarchy)
            {
                FireManSkillsPanel.GetInstance.gameObject.SetActive(false);
            }
            if (TruckSkillSPanel.GetInstance.gameObject.activeInHierarchy)
            {
                TruckSkillSPanel.GetInstance.gameObject.SetActive(false);
            }
        }

    }

    private void DoSelect(GameObject obj)
    {
        AddRecordEventSelect(RecordEventType.RadioSelect, obj);
        if (obj&&obj.GetComponent<ObjSelectCtrl>())
        {
            obj.GetComponent<ObjSelectCtrl>().selected = true;
            SetLayerRecursively(obj, 28);
        }
    }

    private void DoDisSelect(GameObject obj)
    {
        AddRecordEventSelect(RecordEventType.EscCancelSelected, obj);
        if (obj&&obj.GetComponent<ObjSelectCtrl>())
        {
            obj.GetComponent<ObjSelectCtrl>().selected = false;
            SetLayerRecursively(obj, obj.GetComponent<CloneGameObjInfo>().Layer);
        }
    }

    private void clearSelection()
    {
        if (SelectedObjs.selectedObj)
        {
            DoDisSelect(SelectedObjs.selectedObj);
            SelectedObjs.selectedObj = null;
        }
        for (int i = SelectedObjs.selectedCharacters.Count - 1; i >= 0; i--)
        {
            DoDisSelect(SelectedObjs.selectedCharacters[i]);
            SelectedObjs.selectedCharacters.Remove(SelectedObjs.selectedCharacters[i]);
        }
    }

    private void SetLayerRecursively(GameObject obj, int newLayer)
    {
        if (!obj.GetComponent<SelectedHighLightRemoved>())
        {
            obj.layer = newLayer;
            foreach (Transform child in obj.transform)
            {
                SetLayerRecursively(child.gameObject, newLayer);
            }
        }
    }
    public void SetSelect(string json)
    {
        var jsonData = JsonUtility.FromJson<RecordObjectBase>(json);

        if (gameObject.name == jsonData.objectName)
        {
            if (jsonData.IsSelect)
            {
                if (gameObject.CompareTag("Player"))
                {//消防员

                    if (!SelectedObjs.selectedCharacters.Contains(gameObject))
                    {
                        SelectedObjs.selectedCharacters.Add(gameObject);
                    }
                }
                else
                {
                    SelectedObjs.selectedObj = gameObject;
                }
                DoSelect(gameObject);
            }
            else
            {
                DoDisSelect(gameObject);
            }

        }

    }
}