
using Mapbox.Unity.Map;
using Project;
using System;
using Unity.Netcode;
using GeoJSON.Net.Geometry;
using Newtonsoft.Json;

namespace Virgis {

    public class MapBoxLayer : MapBoxLayerPrototype
	{

        private readonly NetworkVariable<MapboxData> data = new();
        private MapboxData tmpdata = new();

        new protected void Awake() {
            base.Awake();
            featureType = FeatureType.MAP;
        }

        public override void OnNetworkSpawn() {
            base.OnNetworkSpawn();
            data.OnValueChanged += SetData;
			if (IsServer)
			{
				data.Value = tmpdata;
			} else
			{
				SetData(data.Value, data.Value);
			}
        }

        public override void OnNetworkDespawn()
        {
            base.OnNetworkDespawn();
            data.OnValueChanged -= SetData;
        }

        public override void Initialize(GeogData props)
        {
            
            Enum.TryParse<ImagerySourceType>(props.imagerySourceType, true, out tmpdata.st);
            Enum.TryParse<ElevationLayerType>(props.elevationLayerType, true, out tmpdata.lt);
            Enum.TryParse<ElevationSourceType>(props.elevationSourceType, true, out tmpdata.et);
            tmpdata.origin = GeoAppState.instance.project.Origin;
            tmpdata.MapSize = props.MapSize;
            tmpdata.MapScale = props.MapScale;
        }

        private void SetData(MapboxData olddata, MapboxData newdata) {
            VirgisAbstractMap mbLayer = GetComponent<VirgisAbstractMap>();
            mbLayer.UseWorldScale();
            mbLayer.SetProperties(newdata.st, newdata.lt, newdata.et, newdata.MapSize);
            mbLayer.Initialize(newdata.origin.Coordinates.Vector2d(), newdata.MapScale);
        }
    }

    /// <summary>
    /// Serializeable struct that defines all data needed to instantiate the Mapbox Map
    /// </summary>
    struct MapboxData : INetworkSerializable
    {
        public ImagerySourceType st;
        public ElevationLayerType lt;
        public ElevationSourceType et;
        public Point origin;
        public int MapSize;
        public int MapScale;

        public void NetworkSerialize<T>(BufferSerializer<T> serializer) where T : IReaderWriter
        {
            if (serializer.IsReader)
            {
                var reader = serializer.GetFastBufferReader();
                reader.ReadValueSafe(out st);
                reader.ReadValueSafe(out lt);
                reader.ReadValueSafe(out et);
                reader.ReadValueSafe(out string json);
                origin = JsonConvert.DeserializeObject<Point>(json);
                reader.ReadValueSafe(out MapSize);
                reader.ReadValueSafe(out MapScale);
            }
            else
            {
                var writer = serializer.GetFastBufferWriter();
                writer.WriteValueSafe(st);
                writer.WriteValueSafe(lt);
                writer.WriteValueSafe(et);
                writer.WriteValueSafe(JsonConvert.SerializeObject(origin));
                writer.WriteValueSafe(MapSize);
                writer.WriteValueSafe(MapScale);
            }
        }
    }
}


