using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using System;
namespace BuildSystem
{
    [DefaultExecutionOrder(-10)]
    public class BuildSystemManager : MonoSingleton<BuildSystemManager>
    {
        [NonSerialized]
        public MouseClick mouseClick;
        public BuildTip buildTip;
        public SetPanel setPanel;
        [Header("地图大小")]
        public Vector2Int mapSize;
        [Header("grid大小")]
        public int gridSize;
        [Header("起始位置")]
        public Vector3 startPos;
        [Header("是否可以放置")]
        public bool isCanPlace;
        [Header("拆除")]
        public bool isRemove = false;
        public Grid[][] gridMap;
        [Header("转换后的数据")]
        public List<GridInfo> grid = new List<GridInfo>();
        private PlaceObject_SO placeObject_SO;//当前选中的道路
        [Header("鼠标是否检测到ui")]
        public bool isUI = false;
        [NonSerialized]
        public PlaceObject placeObj;

        [Header("放置标识")]
        public GameObject flag;

        [Header("部署阶段状态")]
        public bool oneStageEnd = false;
        [Header("红绿灯放置阶段状态")]
        public bool redGreenLightEnd = false;

        [Header("用于初始化地图")]
        public PlaceObject_SO t2up;
        public PlaceObject_SO t2down;
        public PlaceObject_SO h2;

        public PlaceObject_SO t2left;
        public PlaceObject_SO t2right;
        public PlaceObject_SO v2;

        public PlaceObject_SO[] w;

        protected override void Awake()
        {
            base.Awake();
            mouseClick = GetComponent<MouseClick>();
            CreateTerrain();
            DontDestroyOnLoad(gameObject);
            //地图初始化
            MapInit();
        }

        /// <summary>
        /// 创建地形
        /// </summary>
        void CreateTerrain()
        {
            //创建地图
            gridMap = new Grid[mapSize.x][];
            for (int i = 0; i < mapSize.x; i++)
            {
                gridMap[i] = new Grid[mapSize.y];
                for (int j = 0; j < mapSize.y; j++)
                {
                    Grid grid = new Grid(i, 0, j);
                    gridMap[i][j] = grid;
                    if (i > 0)
                    {
                        grid.BindLeftAndThis(gridMap[i - 1][j]);
                    }
                    if (j > 0)
                    {
                        grid.BindDownAndThis(gridMap[i][j - 1]);
                    }
                }
            }
        }

        /// <summary>
        /// 地图初始化
        /// </summary>
        void MapInit() {
            CreatePlaceSpecial(w[0], 0, 0);
            CreatePlaceSpecial(h2, 1, 0);
            CreatePlaceSpecial(h2, 2, 0);
            CreatePlaceSpecial(h2, 3, 0);
            CreatePlaceSpecial(t2up, 4, 0);
            CreatePlaceSpecial(h2, 5, 0);
            CreatePlaceSpecial(h2, 6, 0);
            CreatePlaceSpecial(h2, 7, 0);
            CreatePlaceSpecial(h2, 8, 0);
            CreatePlaceSpecial(t2up, 9, 0);
            CreatePlaceSpecial(h2, 10, 0);
            CreatePlaceSpecial(h2, 11, 0);
            CreatePlaceSpecial(h2, 12, 0);
            CreatePlaceSpecial(w[3], 13, 0);

            CreatePlaceSpecial(w[1], 0, 7);
            CreatePlaceSpecial(h2, 1, 7);
            CreatePlaceSpecial(h2, 2, 7);
            CreatePlaceSpecial(h2, 3, 7);
            CreatePlaceSpecial(t2down, 4, 7);
            CreatePlaceSpecial(h2, 5, 7);
            CreatePlaceSpecial(h2, 6, 7);
            CreatePlaceSpecial(h2, 7, 7);
            CreatePlaceSpecial(h2, 8, 7);
            CreatePlaceSpecial(t2down, 9, 7);
            CreatePlaceSpecial(h2, 10, 7);
            CreatePlaceSpecial(h2, 11, 7);
            CreatePlaceSpecial(h2, 12, 7);
            CreatePlaceSpecial(w[2], 13, 7);


            CreatePlaceSpecial(v2, 0, 1);
            CreatePlaceSpecial(v2, 0, 2);
            CreatePlaceSpecial(t2right, 0, 3);
            CreatePlaceSpecial(v2, 0, 4);
            CreatePlaceSpecial(v2, 0, 5);
            CreatePlaceSpecial(v2, 0, 6);


            CreatePlaceSpecial(v2, 13, 1);
            CreatePlaceSpecial(v2, 13, 2);
            CreatePlaceSpecial(v2, 13, 3);
            CreatePlaceSpecial(t2left, 13, 4);
            CreatePlaceSpecial(v2, 13, 5);
            CreatePlaceSpecial(v2, 13, 6);
            
            //特殊建筑

            gridMap[2][4].isPlace = true;
            gridMap[7][6].isPlace = true;
            gridMap[5][3].isPlace = true;
            gridMap[8][2].isPlace = true;
            gridMap[11][3].isPlace = true;

            gridMap[2][4].gridType = GridType.Special;
            gridMap[7][6].gridType = GridType.Special;
            gridMap[5][3].gridType = GridType.Special;
            gridMap[8][2].gridType = GridType.Special;
            gridMap[11][3].gridType = GridType.Special;

           

            AddGridInfo(4, 0);
            AddGridInfo(9, 0);
            AddGridInfo(4, 7);
            AddGridInfo(9, 7);
            AddGridInfo(0, 3);
            AddGridInfo(13, 4);
        }

        void AddGridInfo(int x, int y)
        {
            var gridinfo = gridMap[x][y].placeObject.gameObject.AddComponent<GridInfo>();
            grid.Add(gridinfo);
            gridinfo.TransData(gridMap[x][y]);
        }

        /// <summary>
        /// 创建一个当前选择的物体,用于指示器的更换
        /// </summary>
        /// <returns></returns>
        PlaceObject CreatePlaceObject() {
            Transform trans = Instantiate(placeObject_SO.prefab, transform);
            PlaceObject obj = trans.gameObject.AddComponent<PlaceObject>();
            obj.Init(placeObject_SO.nameString,
                placeObject_SO.width, placeObject_SO.height, placeObject_SO.roadNumberType,placeObject_SO.isHaveRoad,placeObject_SO.roadType, placeObject_SO.roadGoInfo);
            obj.SetPosition(GetGridPos(mouseClick.MouseInGrid()));
            return obj;
        }

        /// <summary>
        /// 创建一个物体
        /// </summary>
        /// <param name="place"></param>
        /// <param name="x"></param>
        /// <param name="y"></param>
        void CreatePlace(PlaceObject_SO place, int x, int y) {
            Transform trans = Instantiate(place.prefab, transform);
            PlaceObject obj = trans.gameObject.AddComponent<PlaceObject>();
            obj.Init(place.nameString, place.width, place.height, place.roadNumberType, place.isHaveRoad, place.roadType,place.roadGoInfo);
            obj.SetPosition(GetGridPos(new Vector3Int(x, 0, y)));

            gridMap[x][y].isPlace = true;
            gridMap[x][y].type = place.roadNumberType;
            gridMap[x][y].isHaves = place.isHaveRoad;
            gridMap[x][y].roadType = place.roadType;
            gridMap[x][y].placeObject = obj;

            //转换红绿灯需要的信息
            if (gridMap[x][y].roadType != RoadType.T && gridMap[x][y].roadType != RoadType.Ten) return;
            
            var gridinfo = trans.gameObject.AddComponent<GridInfo>();
            grid.Add(gridinfo);
            gridinfo.TransData(gridMap[x][y]);
        }

        /// <summary>
        /// 移除格子的时候移除信号灯数据
        /// </summary>
        /// <param name="info"></param>
        public void RemoveGrid(GridInfo info)
        {
            if (grid.Contains(info))
            {
                grid.Remove(info);
            }
        }

        /// <summary>
        /// 创建一个gridtype为初始化类型的数组
        /// </summary>
        /// <param name="place"></param>
        /// <param name="x"></param>
        /// <param name="y"></param>
        void CreatePlaceSpecial(PlaceObject_SO place, int x, int y)
        {
            Transform trans = Instantiate(place.prefab, transform);
            PlaceObject obj = trans.gameObject.AddComponent<PlaceObject>();
            obj.Init(place.nameString, place.width, place.height, place.roadNumberType, place.isHaveRoad, place.roadType,Instantiate(place).roadGoInfo);
            obj.SetPosition(GetGridPos(new Vector3Int(x, 0, y)));

            gridMap[x][y].isPlace = true;
            gridMap[x][y].gridType = GridType.Initial;
            gridMap[x][y].type = place.roadNumberType;
            gridMap[x][y].isHaves = place.isHaveRoad;
            gridMap[x][y].roadType = place.roadType;
            gridMap[x][y].placeObject = obj;
        }

        /// <summary>
        /// 移除某个物体
        /// </summary>
        /// <param name="x"></param>
        /// <param name="y"></param>
        void RemovePlace(int x, int y) {
            RemoveGrid(gridMap[x][y].placeObject.gameObject.GetComponent<GridInfo>());
            Destroy(gridMap[x][y].placeObject.gameObject);
            gridMap[x][y].RemoveInit();
        }

        /// <summary>
        /// 改变当前的选择的指示器
        /// </summary>
        public void ChangeChoose(PlaceObject_SO placeObject_SO) {
            this.placeObject_SO = placeObject_SO;
            if (placeObj)
            {
                Destroy(placeObj.gameObject);
            }
            placeObj = CreatePlaceObject();
        }

        /// <summary>
        /// 是否可以创建
        /// </summary>
        public bool isCanCreate()
        {
            //将自身大小记录
            bool isCreateSuccess = true;
            Vector3Int start = mouseClick.MouseInGrid();

            if (start == new Vector3Int(-1, -1, -1) || gridMap[start.x][start.z].isPlace)
            {
                isCreateSuccess = false;
            }
            if (!isCreateSuccess)
            {
                if (!isUI) {
                    buildTip.ShowTip("当前位置不可创建");
                }
                return false;
            }

            //判断类型是否可以放置
            if (isCreateSuccess)
            {
                if (!gridMap[start.x][start.z].IsCanPlace(placeObj))
                {
                    buildTip.ShowTip("当前位置存在放置存在风险");
                    return false;
                }
            }
            return true;
        }

        /// <summary>
        /// 判断是否可以创建,用于提示
        /// </summary>
        /// <returns></returns>
        public bool isCanCreateToTip()
        {
            //将自身大小记录
            bool isCreateSuccess = true;
            Vector3Int start = mouseClick.MouseInGrid();
            if (start == new Vector3Int(-1, -1, -1) || gridMap[start.x][start.z].isPlace)
            {
                isCreateSuccess = false;
            }
            if (!isCreateSuccess)
            {
                return false;
            }

            //判断类型是否可以放置
            if (isCreateSuccess)
            {
                if (!gridMap[start.x][start.z].IsCanPlace(placeObj))
                {
                    return false;
                }
            }
            return true;
        }

        /// <summary>
        /// 获取grid的世界坐标
        /// </summary>
        /// <param name="pos"></param>
        /// <returns></returns>
        public Vector3 GetGridPos(Vector3Int pos) {
            if (pos == new Vector3Int(-1, -1, -1)) {
                return Vector3Int.zero;
            }
            return gridMap[pos.x][pos.z].pos;
        }

        /// <summary>
        /// 判断是否通关
        /// </summary>
        /// <returns></returns>
        public bool IsGameEnd() {
            //判断是否闭环
            for (int i = 0; i < mapSize.x; i++)
            {
                for (int j = 0; j < mapSize.y; j++)
                {
                    if (!gridMap[i][j].isClosedLoop()) {
                        return false;
                    }
                }
            }
            //判断是否有两个十字
            int number = 0;
            for (int i = 0; i < mapSize.x; i++)
            {
                for (int j = 0; j < mapSize.y; j++)
                {
                    if (gridMap[i][j].isPlace && gridMap[i][j].roadType == RoadType.Ten) {
                        number++;
                    }
                }
            }
            if (number < 2) {
                return false;
            }
            return true;
        }

        private void Update()
        {
            //更新格子的相邻道路
            for (int i = 0; i < mapSize.x; i++)
            {
                for (int j = 0; j < mapSize.y; j++)
                {
                    gridMap[i][j].InitGround();
                }
            }

            if (!oneStageEnd)
            {
                //物体跟随鼠标  
                if (placeObj && isCanPlace)
                {
                    if (mouseClick.MouseInGrid() != new Vector3Int(-1, -1, -1))
                    {
                        placeObj.SetPosition(GetGridPos(mouseClick.MouseInGrid()));
                    }
                }

                ////创建物体
                if (Input.GetMouseButtonDown(0) && placeObj && isCanPlace && isCanCreate())
                {
                    CreatePlace(placeObject_SO, mouseClick.MouseInGrid().x, mouseClick.MouseInGrid().z);
                }
                else if (Input.GetMouseButtonDown(1) && mouseClick.MouseInGrid() != new Vector3Int(-1, -1, -1))
                {
                    if (gridMap[mouseClick.MouseInGrid().x][mouseClick.MouseInGrid().z].placeObject)
                    {
                        if (gridMap[mouseClick.MouseInGrid().x][mouseClick.MouseInGrid().z].gridType == GridType.General)
                        {
                            RemovePlace(mouseClick.MouseInGrid().x, mouseClick.MouseInGrid().z);
                            buildTip.ShowTip("拆除提示");

                        }
                    }
                }

                //变色提示
                if (placeObj)
                {
                    flag.transform.position = placeObj.transform.position - new Vector3(0, 0.5f, 0);
                    if (isCanCreateToTip())
                    {
                        flag.GetComponent<MeshRenderer>().material.SetColor("_Color", new Color32(48, 255, 30, 128));
                    }
                    else
                    {
                        flag.GetComponent<MeshRenderer>().material.SetColor("_Color", new Color32(255, 41, 0, 128));
                    }
                }

                //判断通关
                if (IsGameEnd() && !oneStageEnd)
                {
                    oneStageEnd = true;
                    flag.SetActive(false);
                    UIManager.Instance.OneStageEnd();
                    Debug.Log("部署阶段结束");

                    //更新格子的相邻道路
                    for (int i = 0; i < mapSize.x; i++)
                    {
                        for (int j = 0; j < mapSize.y; j++)
                        {
                            gridMap[i][j].InitGround();
                        }
                    }
                    Debug.Log(grid.Count);
                }
            }

            if (!redGreenLightEnd && oneStageEnd) {
                bool flag = true;
                foreach (GridInfo info in grid) {
                    if (!info.isPlaceLight) {
                        flag = false;
                        break;
                    }
                }

                //红绿灯放置阶段结束
                if (flag) {
                    redGreenLightEnd = true;
                    Debug.Log("红绿灯放置阶段结束");
                    UIManager.Instance.TwoStageEnd();
                }
            }
        }

        IEnumerator Wait(Action action,float t)
        {
            yield return new WaitForSeconds(t);
            action();
        }

    }
}