using Newtonsoft.Json;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.EventSystems;

public class EquipmentManager : MonoSingleton<EquipmentManager>
{
    public Transform Addition;
    public Transform BuiltIn;

    /// <summary>
    /// 对象
    /// </summary>
    public static Dictionary<EquipmentType, Dictionary<string, GameObject>> SpawObjects = new Dictionary<EquipmentType, Dictionary<string, GameObject>>()
    {
        [EquipmentType.None] = new Dictionary<string, GameObject>(),
        [EquipmentType.NoParking] = new Dictionary<string, GameObject>(),
        [EquipmentType.FireClimbingSite] = new Dictionary<string, GameObject>(),
        [EquipmentType.HazardSource] = new Dictionary<string, GameObject>(),
        [EquipmentType.KeyArea] = new Dictionary<string, GameObject>(),
        [EquipmentType.SmokeVent] = new Dictionary<string, GameObject>(),
        [EquipmentType.SmokeExtractionFan] = new Dictionary<string, GameObject>(),
        [EquipmentType.ImageMarked] = new Dictionary<string, GameObject>(),
        [EquipmentType.ForcedDraftFan] = new Dictionary<string, GameObject>(),
        [EquipmentType.AirVent] = new Dictionary<string, GameObject>(),
        [EquipmentType.EscapeWin] = new Dictionary<string, GameObject>(),
        [EquipmentType.BreakPoint] = new Dictionary<string, GameObject>(),
        [EquipmentType.OutdoorHydrant] = new Dictionary<string, GameObject>(),
        [EquipmentType.SiameseConnection] = new Dictionary<string, GameObject>(),
    };
    /// <summary>
    /// 数据
    /// </summary>
    public static Dictionary<EquipmentType, Dictionary<string, CloneObject>> SpawObjectsData = new Dictionary<EquipmentType, Dictionary<string, CloneObject>>()
    {
        [EquipmentType.None] = new Dictionary<string, CloneObject>(),
        [EquipmentType.NoParking] = new Dictionary<string, CloneObject>(),
        [EquipmentType.FireClimbingSite] = new Dictionary<string, CloneObject>(),
        [EquipmentType.HazardSource] = new Dictionary<string, CloneObject>(),
        [EquipmentType.KeyArea] = new Dictionary<string, CloneObject>(),
        [EquipmentType.SmokeVent] = new Dictionary<string, CloneObject>(),
        [EquipmentType.SmokeExtractionFan] = new Dictionary<string, CloneObject>(),
        [EquipmentType.ImageMarked] = new Dictionary<string, CloneObject>(),
        [EquipmentType.ForcedDraftFan] = new Dictionary<string, CloneObject>(),
        [EquipmentType.AirVent] = new Dictionary<string, CloneObject>(),
        [EquipmentType.EscapeWin] = new Dictionary<string, CloneObject>(),
        [EquipmentType.BreakPoint] = new Dictionary<string, CloneObject>(),
        [EquipmentType.OutdoorHydrant] = new Dictionary<string, CloneObject>(),
        [EquipmentType.SiameseConnection] = new Dictionary<string, CloneObject>(),
    };
    public EquipmentType CreationType;

    public bool isEnabled;
    //是否创建
    public bool isCreate;
    //碰撞点
    private Vector3 pos;
    //层
    public LayerMask layerMask = -1;
    private float DistanceY = 0;
    public string Original;

    public string GetAllUrl;
    public string PostAllUrl;


    private void Start()
    {
        //室外消火栓
        GetAllUrl = HttpManager.Instance.GetAllOutdoorFireHydrants;
        CreationType = EquipmentType.OutdoorHydrant;
        LoadData(null, false);

        //水泵接合器
        GetAllUrl = HttpManager.Instance.GetAllSiameseConnections;
        CreationType = EquipmentType.SiameseConnection;
        LoadData(null, false);
    }

    public void Clone(string key, bool isOn, float distanceY)
    {
        if (isOn)
        {
            isEnabled = true;
            Original = key;
            isCreate = true;
            DistanceY = distanceY;
        }
        else
        {
            isEnabled = false;
            isCreate = false;
            Original = string.Empty;
            DistanceY = 0f;
        }
    }
    void Update()
    {
        if (isEnabled)
        {
            Ray ray = Camera.main.ScreenPointToRay(Input.mousePosition);
            if (Physics.Raycast(ray, out RaycastHit hit, Mathf.Infinity, layerMask))
            {
                if (!EventSystem.current.IsPointerOverGameObject())
                {
                    if (Input.GetMouseButtonDown(0) && !string.IsNullOrEmpty(Original))
                    {
                        if (hit.collider.GetComponent<InstantiateData>())
                        {
                            if (hit.collider.GetComponent<InstantiateData>().Equipment)
                            {
                                var id = hit.collider.GetComponent<InstantiateData>().floorId;
                                if (isCreate)
                                {
                                    CreateEquipment(hit.point, id);
                                }
                            }
                            
                        }
                    }
                }
            }
        }
    }

    private async void CreateEquipment(Vector3 position,int floorId)
    {
        var pos = new Vector3(position.x, position.y + DistanceY, position.z);
        var parent = Addition.Find("Equipments" + floorId);
        var go = await EquipmentPool.Instance.GetEquipment(Original, pos, Quaternion.identity, parent);
        go.name = $"{Original}{AX.Network.Common.GUID.NewGuid()}";
        if (go.GetComponent<UIFollowTarget>())
        {
            go.GetComponent<UIFollowTarget>().LoadIcon(true);
            go.GetComponent<UIFollowTarget>().FloorNumber = floorId;
        }
        InitData(go);
        SelectionManager.Instance.Sets.Add(go);
        
    }

    private void LateUpdate()
    {
        if(MainMenu.Instance.MenuMode!= MainMenuMode.态势标绘)
        {
            if (Input.GetKeyDown(KeyCode.Delete))
            {
                OnDeleteObject();
            }
            if (Input.GetKey(KeyCode.LeftArrow))
            {
                RotateObject(40);
            }
            if (Input.GetKey(KeyCode.RightArrow))
            {
                RotateObject(-40);
            }
        }
        
    }

    private void InitData(GameObject obj)
    {
        SpawObjects[CreationType].Add(obj.name, obj);
        CloneObject tempData;
        switch (CreationType)
        {
            case EquipmentType.None:
                tempData = new CloneObject()
                {
                    Id = obj.name,
                    Parent = obj.transform.parent.name,
                    Position = obj.transform.localPosition,
                    Rotation = obj.transform.localRotation.eulerAngles,
                    ObjectType = CreationType
                };
                SpawObjectsData[EquipmentType.None][tempData.Id] = tempData;
                break;
            case EquipmentType.NoParking:
                tempData = new CloneObject()
                {
                    Id = obj.name,
                    Parent = obj.transform.parent.name,
                    Position = obj.transform.localPosition,
                    Rotation = obj.transform.localRotation.eulerAngles,
                    ObjectType = CreationType
                };
                SpawObjectsData[EquipmentType.NoParking][tempData.Id] = tempData;
                break;
            case EquipmentType.FireClimbingSite:
                tempData = new CloneObject()
                {
                    Id = obj.name,
                    Parent = obj.transform.parent.name,
                    Position = obj.transform.localPosition,
                    Rotation = obj.transform.localRotation.eulerAngles,
                    ObjectType = CreationType
                };
                SpawObjectsData[EquipmentType.FireClimbingSite][tempData.Id] = tempData;
                break;
            case EquipmentType.HazardSource:
                tempData = new CloneObject()
                {
                    Id = obj.name,
                    Parent = obj.transform.parent.name,
                    Position = obj.transform.localPosition,
                    Rotation = obj.transform.localRotation.eulerAngles,
                    ObjectType = CreationType
                };
                SpawObjectsData[EquipmentType.HazardSource][tempData.Id] = tempData;
                break;
            case EquipmentType.KeyArea:
                tempData = new CloneObject()
                {
                    Id = obj.name,
                    Parent = obj.transform.parent.name,
                    Position = obj.transform.localPosition,
                    Rotation = obj.transform.localRotation.eulerAngles,
                    ObjectType = CreationType
                };
                SpawObjectsData[EquipmentType.KeyArea][tempData.Id] = tempData;
                break;
            case EquipmentType.SmokeVent:
                tempData = new CloneObject()
                {
                    Id = obj.name,
                    Parent = obj.transform.parent.name,
                    Position = obj.transform.localPosition,
                    Rotation = obj.transform.localRotation.eulerAngles,
                    ObjectType = CreationType
                };
                SpawObjectsData[EquipmentType.SmokeVent][tempData.Id] = tempData;
                break;
            case EquipmentType.SmokeExtractionFan:
                tempData = new CloneObject()
                {
                    Id = obj.name,
                    Parent = obj.transform.parent.name,
                    Position = obj.transform.localPosition,
                    Rotation = obj.transform.localRotation.eulerAngles,
                    ObjectType = CreationType
                };
                SpawObjectsData[EquipmentType.SmokeExtractionFan][tempData.Id] = tempData;
                break;
            case EquipmentType.ImageMarked:
                tempData = new CloneObject()
                {
                    Id = obj.name,
                    Parent = obj.transform.parent.name,
                    Position = obj.transform.localPosition,
                    Rotation = obj.transform.localRotation.eulerAngles,
                    ObjectType = CreationType
                };
                SpawObjectsData[EquipmentType.ImageMarked][tempData.Id] = tempData;
                break;
           
            case EquipmentType.ForcedDraftFan:
                tempData = new CloneObject()
                {
                    Id = obj.name,
                    Parent = obj.transform.parent.name,
                    Position = obj.transform.localPosition,
                    Rotation = obj.transform.localRotation.eulerAngles,
                    ObjectType = CreationType
                };
                SpawObjectsData[EquipmentType.ForcedDraftFan][tempData.Id] = tempData;
                break;
            case EquipmentType.AirVent:
                tempData = new CloneObject()
                {
                    Id = obj.name,
                    Parent = obj.transform.parent.name,
                    Position = obj.transform.localPosition,
                    Rotation = obj.transform.localRotation.eulerAngles,
                    ObjectType = CreationType
                };
                SpawObjectsData[EquipmentType.AirVent][tempData.Id] = tempData;
                break;
            case EquipmentType.EscapeWin:
                tempData = new CloneObject()
                {
                    Id = obj.name,
                    Parent = obj.transform.parent.name,
                    Position = obj.transform.localPosition,
                    Rotation = obj.transform.localRotation.eulerAngles,
                    ObjectType = CreationType
                };
                SpawObjectsData[EquipmentType.EscapeWin][tempData.Id] = tempData;
                break;
            case EquipmentType.BreakPoint:
                tempData = new CloneObject()
                {
                    Id = obj.name,
                    Parent = obj.transform.parent.name,
                    Position = obj.transform.localPosition,
                    Rotation = obj.transform.localRotation.eulerAngles,
                    ObjectType = CreationType
                };
                SpawObjectsData[EquipmentType.BreakPoint][tempData.Id] = tempData;
                break;
            case EquipmentType.OutdoorHydrant:
                tempData = new OutdoorHydrant()
                {
                    Id = obj.name,
                    Parent = obj.transform.parent.name,
                    Position = obj.transform.localPosition,
                    Rotation = obj.transform.localRotation.eulerAngles,
                    ObjectType = CreationType
                };
                SpawObjectsData[EquipmentType.OutdoorHydrant][tempData.Id] = tempData;
                break;
            case EquipmentType.SiameseConnection:
                tempData = new SiameseConnections()
                {
                    Id = obj.name,
                    Parent = obj.transform.parent.name,
                    Position = obj.transform.localPosition,
                    Rotation = obj.transform.localRotation.eulerAngles,
                    ObjectType = CreationType
                };
                SpawObjectsData[EquipmentType.SiameseConnection][tempData.Id] = tempData;
                break;
        }
    }

    public void LoadData(string key, bool showIcon)
    {
        GetData(key, showIcon);
    }

    private void GetData(string key, bool showIcon)
    {
        switch (CreationType)
        {
            case EquipmentType.None:
                HttpManager.Instance.Get<List<CloneObject>>(GetAllUrl, datas =>
                {
                    foreach (var item in datas)
                    {
                        SpawObjectsData[EquipmentType.None][item.Id] = item;
                    }
                    SpawnObjectWithData(EquipmentType.None, key, showIcon);
                });
                break;
            case EquipmentType.NoParking:
                HttpManager.Instance.Get<List<CloneObject>>(GetAllUrl, datas =>
                {
                    foreach (var item in datas)
                    {
                        SpawObjectsData[EquipmentType.NoParking][item.Id] = item;
                    }
                    SpawnObjectWithData(EquipmentType.NoParking, key, showIcon);
                });
                break;
            case EquipmentType.FireClimbingSite:
                HttpManager.Instance.Get<List<CloneObject>>(GetAllUrl, datas =>
                {
                    foreach (var item in datas)
                    {
                        SpawObjectsData[EquipmentType.FireClimbingSite][item.Id] = item;
                    }
                    SpawnObjectWithData(EquipmentType.FireClimbingSite, key, showIcon);
                });
                break;
            case EquipmentType.HazardSource:
                HttpManager.Instance.Get<List<CloneObject>>(GetAllUrl, datas =>
                {
                    foreach (var item in datas)
                    {
                        SpawObjectsData[EquipmentType.HazardSource][item.Id] = item;
                    }
                    SpawnObjectWithData(EquipmentType.HazardSource, key, showIcon);
                });
                break;
            case EquipmentType.KeyArea:
                HttpManager.Instance.Get<List<CloneObject>>(GetAllUrl, datas =>
                {
                    foreach (var item in datas)
                    {
                        SpawObjectsData[EquipmentType.KeyArea][item.Id] = item;
                    }
                    SpawnObjectWithData(EquipmentType.KeyArea, key, showIcon);
                });
                break;
           
            case EquipmentType.SmokeVent:
                HttpManager.Instance.Get<List<CloneObject>>(GetAllUrl, datas =>
                {
                    foreach (var item in datas)
                    {
                        SpawObjectsData[EquipmentType.SmokeVent][item.Id] = item;
                    }
                    SpawnObjectWithData(EquipmentType.SmokeVent, key, showIcon);
                });
                break;
            case EquipmentType.SmokeExtractionFan:
                HttpManager.Instance.Get<List<CloneObject>>(GetAllUrl, datas =>
                {
                    foreach (var item in datas)
                    {
                        SpawObjectsData[EquipmentType.SmokeExtractionFan][item.Id] = item;
                    }
                    SpawnObjectWithData(EquipmentType.SmokeExtractionFan, key, showIcon);
                });
                break;
            case EquipmentType.ImageMarked:
                HttpManager.Instance.Get<List<CloneObject>>(GetAllUrl, datas =>
                {
                    foreach (var item in datas)
                    {
                        SpawObjectsData[EquipmentType.ImageMarked][item.Id] = item;
                    }
                    SpawnObjectWithData(EquipmentType.ImageMarked, key, showIcon);
                });
                break;
           
           
            case EquipmentType.ForcedDraftFan:
                HttpManager.Instance.Get<List<CloneObject>>(GetAllUrl, datas =>
                {
                    foreach (var item in datas)
                    {
                        SpawObjectsData[EquipmentType.ForcedDraftFan][item.Id] = item;
                    }
                    SpawnObjectWithData(EquipmentType.ForcedDraftFan, key, showIcon);
                });
                break;
            case EquipmentType.AirVent:
                HttpManager.Instance.Get<List<CloneObject>>(GetAllUrl, datas =>
                {
                    foreach (var item in datas)
                    {
                        SpawObjectsData[EquipmentType.AirVent][item.Id] = item;
                    }
                    SpawnObjectWithData(EquipmentType.AirVent, key, showIcon);
                });
                break;
            case EquipmentType.EscapeWin:
                HttpManager.Instance.Get<List<CloneObject>>(GetAllUrl, datas =>
                {
                    foreach (var item in datas)
                    {
                        SpawObjectsData[EquipmentType.EscapeWin][item.Id] = item;
                    }
                    SpawnObjectWithData(EquipmentType.EscapeWin, key, showIcon);
                });
                break;
            case EquipmentType.BreakPoint:
                HttpManager.Instance.Get<List<CloneObject>>(GetAllUrl, datas =>
                {
                    foreach (var item in datas)
                    {
                        SpawObjectsData[EquipmentType.BreakPoint][item.Id] = item;
                    }
                    SpawnObjectWithData(EquipmentType.BreakPoint, key, showIcon);
                });
                break;
            case EquipmentType.OutdoorHydrant:
                HttpManager.Instance.Get<List<OutdoorHydrant>>(GetAllUrl, datas =>
                {
                    foreach (var item in datas)
                    {
                        SpawObjectsData[EquipmentType.OutdoorHydrant][item.Id] = item;
                    }
                    SpawnHydrantsWithData(EquipmentType.OutdoorHydrant);
                });
                break;
            case EquipmentType.SiameseConnection:
                HttpManager.Instance.Get<List<SiameseConnections>>(GetAllUrl, datas =>
                {
                    foreach (var item in datas)
                    {
                        SpawObjectsData[EquipmentType.SiameseConnection][item.Id] = item;
                    }
                    SpawnSiameseConnectionsWithData(EquipmentType.SiameseConnection);
                });
                break;
        }
    }
    /// <summary>
    /// 水泵接合器
    /// </summary>
    /// <param name="createType"></param>
    private async void SpawnSiameseConnectionsWithData(EquipmentType createType)
    {
        // 加载数据
        foreach (var item in SpawObjectsData[createType].Values)
        {
            var pos = item.Position;
            var rot = Quaternion.Euler(item.Rotation);
            var parent = transform.Find("Addition/" + item.Parent);
            GameObject tempGo;

            if (item.Id.Contains("SBJHQA"))
                tempGo = await EquipmentPool.Instance.GetEquipment("SBJHQA", pos, rot, parent);
            else if(item.Id.Contains("SBJHQB"))
                tempGo = await EquipmentPool.Instance.GetEquipment("SBJHQB", pos, rot, parent);
            else if(item.Id.Contains("SBJHQC"))
                tempGo = await EquipmentPool.Instance.GetEquipment("SBJHQC", pos, rot, parent);
            else
                tempGo = await EquipmentPool.Instance.GetEquipment("SBJHQD", pos, rot, parent);
            tempGo.name = item.Id;
            tempGo.GetComponent<UIFollowTarget>().LoadIcon(false);
            SpawObjects[createType].Add(tempGo.name, tempGo);
        }
    }
    /// <summary>
    /// 室外消火栓
    /// </summary>
    /// <param name="createType"></param>
    private async void SpawnHydrantsWithData(EquipmentType createType)
    {
        // 加载数据
        foreach (var item in SpawObjectsData[createType].Values)
        {
            var pos = item.Position;
            var rot = Quaternion.Euler(item.Rotation);
            var parent = transform.Find("Addition/" + item.Parent);
            GameObject tempGo;
            if (item.Id.Contains("DSXHS"))
                tempGo = await EquipmentPool.Instance.GetEquipment("DSXHS", pos, rot, parent);
            else
                tempGo = await EquipmentPool.Instance.GetEquipment("DXXHS", pos, rot, parent);
            tempGo.name = item.Id;
            tempGo.GetComponent<UIFollowTarget>().LoadIcon(false);
            SpawObjects[createType].Add(tempGo.name, tempGo);
        }
    }
    private async void SpawnObjectWithData(EquipmentType createType, string key, bool showIcon)
    {
        // 加载数据
        foreach (var item in SpawObjectsData[createType].Values)
        {
            var pos = item.Position;
            var rot = Quaternion.Euler(item.Rotation);
            var parent = transform.Find("Addition/" + item.Parent);

            GameObject tempGo = await EquipmentPool.Instance.GetEquipment(key, pos, rot, parent);
            tempGo.name = item.Id;
            //tempGo.transform.parent = transform.Find("Addition/"+item.Parent);
            //tempGo.transform.localPosition = item.Position;
            //tempGo.transform.localRotation = Quaternion.Euler(item.Rotation);
            tempGo.GetComponent<UIFollowTarget>().LoadIcon(showIcon);
            SelectionManager.Instance.Sets.Add(tempGo);
            SpawObjects[createType].Add(tempGo.name, tempGo);
            if (CreationType == EquipmentType.FireClimbingSite || CreationType == EquipmentType.NoParking)
            {
                tempGo.transform.Find("Scene/Plane").GetComponent<MeshFilter>().mesh.vertices = item.MeshVertices;
                tempGo.transform.Find("Scene/Plane").GetComponent<MeshFilter>().mesh.RecalculateNormals();
                tempGo.GetComponent<MeshCollider>().sharedMesh = tempGo.transform.Find("Scene/Plane").GetComponent<MeshFilter>().mesh;
            }

        }
    }
    //保存数据
    public void SaveData()
    {
        Dictionary<string, string> postData = new Dictionary<string, string>();
        foreach (var item in SpawObjectsData[CreationType].Values)
        {
            GameObject tempGo = SpawObjects[CreationType][item.Id];
            item.Position = tempGo.transform.position;
            item.Rotation = tempGo.transform.localEulerAngles;
            if (item.ObjectType == EquipmentType.FireClimbingSite || item.ObjectType == EquipmentType.NoParking)
            {
                item.MeshVertices = tempGo.transform.Find("Scene/Plane").GetComponent<MeshFilter>()?.mesh.vertices;
            }
            string json = JsonConvert.SerializeObject(item);
            postData.Add(item.Id, json);
        }
        HttpManager.Instance.Post(PostAllUrl, postData);
    }
    //卸载资源
    public void UnLoadAsset()
    {
        foreach (GameObject obj in SpawObjects[CreationType].Values)
        {
            if (obj != null)
            {
                obj.GetComponent<UIFollowTarget>().LoadIcon(false);
                Destroy(obj);
            }
        }
        SpawObjects[CreationType].Clear();
        SpawObjectsData[CreationType].Clear();
    }
    //清空
    public void OnCleraButtonClicked()
    {
        MessageBox.Show("确认清空?", Color.white, UnLoadAsset);
    }

    //删除
    public void OnDeleteObject()
    {
        foreach(var go in SelectionManager.GetSelectedObjects())
        {
            if (go != null)
            {
                go.GetComponent<UIFollowTarget>().LoadIcon(false);
                Destroy(go);
            }
            SpawObjects[CreationType].Remove(go.name);
            SpawObjectsData[CreationType].Remove(go.name);
            SelectionManager.Instance.Sets.Remove(go);
        }
    }

    void RotateObject(int speed)
    {
        foreach (var go in SelectionManager.GetSelectedObjects())
        {
            if (go != null)
            {
                go.transform.Rotate(0, Time.deltaTime * speed, 0, Space.World);
            }
           
        }
    }
}