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

public class CompanyController : MonoBehaviour
{
    public static CompanyController instance;
    public Button ButtonStatus;
    public GameObject Player;
    public GameObject Editor;
    public Dropdown DropdownCompany;
    public Dropdown DropdownLocation;
    public GameObject Dialog;
    public GameObject ZonesScroll;
    public Toggle ToggleBeacons;
    public Toggle ToggleZones;
    public int active_company = -1;
    public int active_location = -1;
    public GameObject Locations;
    public Dictionary<uint, Load> load_location_elements = new Dictionary<uint, Load>(); // флаги загрузки элементов локации
    public bool load_location = false;
    public Dictionary<uint, Location> locations; // список локаций
    public List<uint> locations_index; // сопоставление id с dropdown
    //public List<Marker> markers;

    PlayerController player;
    EditorController editor;
    Client client;

    private void Awake()
    {
        instance = this;
    }

    // Start is called before the first frame update
    void Start()
    {
        player = Player.GetComponent<PlayerController>();
        editor = Editor.GetComponent<EditorController>();
        client = Client.instance;
        DropdownCompany.options.Add(new Dropdown.OptionData("Тайшет"));
        DropdownCompany.options.Add(new Dropdown.OptionData("Тестовая"));
        DropdownCompany.options.Add(new Dropdown.OptionData("Братское"));

        locations = new Dictionary<uint, Location>();
        locations_index = new List<uint>();
    }

    // Update is called once per frame
    void Update()
    {
        if (active_company != DropdownCompany.value && AuthorizationController.success)
            ChangeCompany();

        if (active_location != DropdownLocation.value && AuthorizationController.success && locations.Any())
            ChangeLocation();

        if (active_location >= 0 && locations_index.Any())
            if (AuthorizationController.success && load_location_elements.ContainsKey(locations_index[active_location]))
            {
                if (load_location_elements[locations_index[active_location]].location)
                {
                    var l = locations[locations_index[active_location]];
                    LocationContents(l);
                }

                BeaconsOnOff();
                ZonesOnOff();
            }

        

        if (load_location)
        {
            load_location = false;
            DropdownLocation.options.Clear();
            DropdownLocation.options = new List<Dropdown.OptionData>();

            foreach (var l in locations)
            {
                l.Value.location.transform.SetParent(Locations.transform);
                l.Value.location.SetActive(false);
                DropdownLocation.options.Add(new Dropdown.OptionData($"{l.Key} {l.Value.name}"));

                load_location_elements[l.Key] = new Load();
                load_location_elements[l.Key].location = true;
                l.Value.Load();
            }

            if (ModeController.editor && editor.newLocation != null)
            {
                var l = editor.newLocation;
                //l.location.transform.SetParent(Locations.transform);
                l.location.transform.SetSiblingIndex(Locations.transform.childCount - 1);
                l.location.SetActive(false);
                DropdownLocation.options.Add(new Dropdown.OptionData($"Новая локация"));
                locations_index.Add(l.id);
                locations[l.id] = l;
            }
            DropdownLocation.value = 0;
            DropdownLocation.RefreshShownValue();
            active_location = DropdownLocation.value;

            //active_location = -1;
            ChangeLocation();
        }

        if(client.connected)
            ButtonStatus.GetComponent<Image>().color = Color.green;
        else
            ButtonStatus.GetComponent<Image>().color = Color.red;
    }

    /// <summary>
    /// Удаление сотрудников из-за смены компании
    /// Отчистка Locations
    /// 
    /// </summary>
    public void ChangeCompany()
    {
        foreach (var l in locations)
        {
            if (l.Value.id < (uint)int.MaxValue)
            {
                Destroy(l.Value.location);
                foreach (var b in l.Value.beacons)
                    Destroy(b.panel_button);
                foreach (var z in l.Value.zones)
                    Destroy(z.buttons); 
                load_location_elements.Remove(l.Value.id);
            }
        }

       

active_company = DropdownCompany.value;
        Client.instance.company_id = (uint)(active_company + 1);       
        if (player.markers != null)
            foreach (var m in player.markers)
            {
                Destroy(m.marker.gameObject);
                Destroy(m.marker_line.gameObject);
                Destroy(m.toggle_user);
            } 
        Client.instance.SendGetUsers();
        player.markers = new List<Marker>();
        Location.LocationsRequest(0);
    }

    float sizex = 0;
    float sizey = 0;
    public void ChangeLocation()
    {
        Debug.Log("PlayerController locations count " + locations.Count + " active " + active_location);
        if (active_location >= 0)
            locations[locations_index[active_location]].LocationActive(false);   

        active_location = DropdownLocation.value;
        var l = locations[locations_index[active_location]];
        l.LocationActive(true);

        if (!l.texture_url.Equals("")) StartCoroutine(SendingFormController.LoadImage(l.texture_url, l.plane, l.plane.transform.position, l.plane.transform.localScale));

        editor.Name.text = l.name;
        editor.Image.text = l.texture_url;
        editor.EditLocation = l; 
        
        if (l.plane.transform.localScale.x != sizex)
        {
            editor.SizeX.text = $"{l.plane.transform.localScale.x}";
            sizex = l.plane.transform.localScale.x;
        }
        if (l.plane.transform.localScale.z != sizey)
        {
            editor.SizeY.text = $"{l.plane.transform.localScale.z}";
            sizey = l.plane.transform.localScale.z;
        }              
    }  

    public void LocationContents(Location location)
    {
        if (load_location_elements.ContainsKey(location.id))
        {
            if (load_location_elements[location.id].walls)
            {
                load_location_elements[location.id].walls = false;
                //var walls = location.Walls ?? new GameObject();
                //walls.name = "Walls";
                //walls.transform.SetParent(location.location.transform);

                var walls = location.location.transform.GetChild(1);
                foreach (var w in location.walls)
                {
                    var wall = WallCreate.AddWall(this, 
                        new Vector3(w.start_width, WallCreate.WallHeight / 2, w.start_height), 
                        new Vector3(Mathf.Abs(w.end_width), WallCreate.WallHeight, Mathf.Abs(w.end_height)));
                    wall.transform.SetParent(walls.transform);
                }
            }

            if (!editor.Beacons.ContainsKey(location.id))
                editor.Beacons[location.id] = new List<Beacon>();
            if (load_location_elements[location.id].beacons)
            {
                load_location_elements[location.id].beacons = false;
                //var beacons = location.Beacons ?? new GameObject();
                //beacons.name = "Beacons";
                //beacons.transform.SetParent(location.location.transform);

                foreach (var b in location.beacons)
                {
                    editor.AddBeacon(this, b);
                    if (ModeController.editor == true) b.beacon.GetComponent<BeaconController>().mode = BeaconController.Mode.Editor;
                }

            }
            if (load_location_elements[location.id].zones)
            {
                load_location_elements[location.id].zones = false;
                //var zones = location.Zones ?? new GameObject();               
                //zones.name = "Zones";
                //zones.transform.SetParent(location.location.transform);                

               
                foreach (var z in location.zones)
                    z.go = WallCreate.AddZone(Dialog, this, ZonesScroll, z);
            }
        }
    }

    public Location GetActiveLocation()
    {
        //if (locations.Count > 0 && locations_index.Count > 0 && locations_index.Contains((uint)active_location))
        //    if (locations.ContainsKey(locations_index[active_location]))
        return locations[locations_index[active_location]];
        //return null;
    }

    public Location GetLocation(uint id)
    {
        if (locations.Count > 0)
            if (locations.ContainsKey(id))
                return locations[id];
        return null;
    }

    public void ErrorDialogClose()
    {
        Dialog.SetActive(false);
    }

    bool beacons_view;
    public void BeaconsOnOff()
    {
        if (beacons_view != ToggleBeacons.isOn)
        {
            foreach (var b in locations[locations_index[active_location]].beacons)
                b.beacon.SetActive(ToggleBeacons.isOn);
            beacons_view = ToggleBeacons.isOn;
        }
    }

    bool zones_view;
    public void ZonesOnOff()
    {
        if (zones_view != ToggleZones.isOn)
        {
            foreach (var z in locations[locations_index[active_location]].zones)
                z.go.SetActive(ToggleZones.isOn);
            zones_view = ToggleZones.isOn;
        }
    }
}
