using System;
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.EventSystems;
using UnityEngine.UI;

public class WallCreate : MonoBehaviour
{    
    public static float WallHeight = 1f;
    public float WallThickness = 0.05f;
    public int Rounding = 1;
    public bool move = false;
    public bool BoxColliderEnabled = true;
    public GameObject Dialog;
    public GameObject ZonesScroll;
    public GameObject Player;
    public enum Mode { Wall, Room, Zone, Pole, Cursor };
    public static Mode mode = Mode.Cursor;
    GameObject wall;
    Wall currentWall;
    public static List<GameObject> Walls = new List<GameObject>();
    public static List<Wall> WallObjects = new List<Wall>();
    public static List<Wall> Rooms = new List<Wall>();
    public static List<Zone> Zones = new List<Zone>();

    private Vector3 screenPoint;
    private Vector3 offset;
    private Vector3 curScreenPoint;
    private Vector3 curPosition;

    private Vector3 start_pos;
    Vector3 Point;

    GameObject canvas;
    Text text;

    // Start is called before the first frame update
    void Start()
    {
       // gameObject.GetComponent<BoxCollider>().enabled = BoxColliderEnabled;
        //cursor_end = transform.GetChild(6).gameObject; 
        Point = Camera.main.WorldToScreenPoint(gameObject.transform.position);
        canvas = transform.GetChild(0).gameObject;
        text = transform.GetChild(0).GetChild(0).GetChild(0).GetComponent<Text>();
    }
   
    // Update is called once per frame
    void Update()
    {
        // if (gameObject.GetComponent<BoxCollider>().enabled != BoxColliderEnabled) gameObject.GetComponent<BoxCollider>().enabled = BoxColliderEnabled;
        if (!Input.GetMouseButtonDown(0))
        {           
            transform.position = Camera.main.ScreenToWorldPoint(new Vector3(Input.mousePosition.x, Input.mousePosition.y, Point.z));
        }
    }

    void OnMouseDown()
    {
        if (!EventSystem.current.IsPointerOverGameObject())
        {
            //Debug.Log(StagesEditorController.indexCursor);

            screenPoint = Camera.main.WorldToScreenPoint(gameObject.transform.position);
            //s_point = Camera.main.WorldToScreenPoint(gameObject.transform.position);
            start_pos = Camera.main.ScreenToWorldPoint(new Vector3(Input.mousePosition.x, Input.mousePosition.y, screenPoint.z));
            offset = gameObject.transform.position - Camera.main.ScreenToWorldPoint(new Vector3(Input.mousePosition.x, Input.mousePosition.y, screenPoint.z));

            switch (mode)
            {
                case Mode.Wall:
                    wall = AddWall(Vector3.zero);                    
                    break;
                case Mode.Room:
                    wall = AddRoom();
                    break;
                case Mode.Zone:
                    wall = AddZone(Dialog, Player, ZonesScroll);
                    break;
            }
        }

        canvas.SetActive(true);       
    }

    float scale_x;
    float scale_z;
    void OnMouseDrag()
    {
        if (!EventSystem.current.IsPointerOverGameObject())
        {
            curScreenPoint = new Vector3(Input.mousePosition.x, Input.mousePosition.y, screenPoint.z);
            // e_point = Camera.main.WorldToScreenPoint(gameObject.transform.position);
            curPosition = Camera.main.ScreenToWorldPoint(curScreenPoint) + offset;

            var end_pos = Camera.main.ScreenToWorldPoint(new Vector3(Input.mousePosition.x, Input.mousePosition.y, screenPoint.z));
            Debug.Log("start_pos.x "+start_pos.x);
            scale_x = (float)Math.Round(end_pos.x - start_pos.x, Rounding);
            scale_z = (float)Math.Round(end_pos.z - start_pos.z, Rounding);
            text.text = $"x={scale_x} y={scale_z}";           
           
            switch (mode)
            {
                case Mode.Wall:
                    if (Math.Abs(scale_x) > Math.Abs(scale_z)/* && x_mod >= 0.4f*/)
                    {
                        wall.transform.localScale = new Vector3(scale_x, WallHeight, WallThickness);
                        wall.transform.position = new Vector3(scale_x / 2 + start_pos.x, WallHeight / 2, start_pos.z);
                    }
                    if (Math.Abs(scale_z) > Math.Abs(scale_x)/* && z_mod >= 0.4f*/)
                    {

                        wall.transform.localScale = new Vector3(WallThickness, WallHeight, scale_z);
                        wall.transform.position = new Vector3(start_pos.x, WallHeight / 2, scale_z / 2 + start_pos.z);
                    }

                    break;
                case Mode.Room:
                    /*if (scale_x > 0 && scale_z > 0) */
                    LocationController.Cube(wall, new Vector3(scale_x, scale_z, WallHeight),
                                                            new Vector2((float)Math.Round(start_pos.x, Rounding), (float)Math.Round(start_pos.z, Rounding)), WallThickness);
                    break;
                //case Mode.Pole:
                //    AddWall(pos);
                //    break;
                case Mode.Zone:
                    wall.transform.localScale = new Vector3(scale_x/10, 1, scale_z/10);
                    wall.transform.position = new Vector3(scale_x / 2 + start_pos.x, 0.05f, scale_z / 2 + start_pos.z);
                    break;
            }

            float offsetPosY = transform.position.y + 1.5f;

            // Final position of marker above GO in world space
            canvas.transform.GetChild(0).transform.position = new Vector3(Input.mousePosition.x, Input.mousePosition.y+20, screenPoint.z);
        }
    }

    private void OnMouseUp()
    {
        //var end_pos = Camera.main.ScreenToWorldPoint(new Vector3(Input.mousePosition.x, Input.mousePosition.y, screenPoint.z));
        //Debug.Log($"end_pos = {end_pos}");
        currentWall = new Wall { start_width = start_pos.x, start_height = start_pos.z, end_width = scale_x, end_height = scale_z, go=wall };
        
        if (mode == Mode.Room) Rooms.Add(currentWall);
        else if (mode == Mode.Wall) WallObjects.Add(currentWall);

        canvas.SetActive(false);

        if (mode == Mode.Zone && !EventSystem.current.IsPointerOverGameObject())
        {
            Dialog.SetActive(true);
            Dialog.GetComponent<Dialog>().Text.gameObject.SetActive(false);
            Dialog.GetComponent<Dialog>().InputField.gameObject.SetActive(true);
            Dialog.GetComponent<Dialog>().Button.onClick.AddListener(() =>
            {
                wall.GetComponent<ZoneController>().TextMesh.text=Dialog.GetComponent<Dialog>().InputField.text;
            });
        }                
    }

    public static GameObject AddWall(Vector3 pos, Vector3 scale = default)
    {
        var wall = Instantiate(Resources.Load("GameObjects/Pole", typeof(GameObject))) as GameObject;
        wall.transform.position = pos;
        if(scale != null) wall.transform.localScale = scale;
        wall.transform.SetParent(GameObject.Find("Walls").transform);
        Walls.Add(wall);
        return wall;
    }

    GameObject AddRoom()
    {
        var room = Instantiate(Resources.Load("GameObjects/Cube", typeof(GameObject))) as GameObject;
        room.transform.SetParent(GameObject.Find("Walls").transform);
        LocationController.Cube(room, new Vector3(0.1f, 0.1f, 1));
        for (var i = 0; i < room.transform.childCount; i++)
            if (room.transform.GetChild(i).gameObject.activeSelf == true)            
                Walls.Add(room.transform.GetChild(i).gameObject);
            
        return room;
    }

    public static GameObject AddZone(GameObject Dialog, GameObject Player, GameObject ZonesScroll)
    {
        var zone = Instantiate(Resources.Load("GameObjects/Zone", typeof(GameObject))) as GameObject;
        //zone.transform.position = pos;
        zone.transform.SetParent(GameObject.Find("Zones").transform);

        var panel_button = Instantiate(Resources.Load("GameObjects/Panel_Beacon", typeof(GameObject))) as GameObject;
        panel_button.transform.SetParent(ZonesScroll.transform);
        panel_button.name = $"Zone_{Zones.Count}";
        var button = panel_button.transform.GetChild(0).GetComponent<Button>();
        button.transform.GetChild(0).GetComponent<Text>().text = $"Зона {Zones.Count + 1}";
        zone.GetComponent<ZoneController>().TextMesh.text = $"Зона {Zones.Count+1}";
        var active_zone = Zones.Count;

        var location_id = PlayerController.locations[Player.GetComponent<PlayerController>().DropdownLocation.value].id;
        var z = new Zone { id=0, go=zone, buttons = panel_button, location_id=(uint) location_id };       
        
        var button_ok = Dialog.transform.GetChild(2).GetComponent<Button>();
        
        button.onClick.AddListener(() =>
        {
            Dialog.SetActive(true);
            active_zone = Zones.Count;
            button_ok.onClick.RemoveAllListeners();

            Dialog.GetComponent<Dialog>().Text.gameObject.SetActive(false);
            Dialog.GetComponent<Dialog>().InputField.gameObject.SetActive(true);

            button_ok.onClick.AddListener(() =>
            {                                
                button.transform.GetChild(0).GetComponent<Text>().text = !Dialog.GetComponent<Dialog>().InputField.text.Equals("") ? Dialog.GetComponent<Dialog>().InputField.text : $"Зона {active_zone + 1}";
                zone.GetComponent<ZoneController>().TextMesh.text = !Dialog.GetComponent<Dialog>().InputField.text.Equals("") ? Dialog.GetComponent<Dialog>().InputField.text : $"Зона {active_zone + 1}";
                Dialog.SetActive(false);
            });           
        });

        var button_del = panel_button.transform.GetChild(2).GetComponent<Button>();
        button_del.onClick.AddListener(() =>
        {
            Destroy(zone);
            Destroy(panel_button);
            Zones.Remove(z);
        });

        Zones.Add(z);
        return zone;
    }

    public void SaveZones()
    {
        foreach(var z in Zones)
        {
            z.Save();
        }
    }
}
