using Newtonsoft.Json;
using System;
using System.IO;
using System.Text;
using UnityEngine;
using UnityEngine.Networking;

namespace Assets.Logging
{
    internal class DetectionFrameLogger : ILogger<DetectionFrame>
    {
        public void Log(DetectionFrame frame)
        {
            var pocoFrame = new Poco.DetectionFrame()
            {
                RawObjectsFrame = new Poco.ObjectsFrameSDK
                {
                    DetectionModel = frame.rawObjectsFrame.detectionModel,
                    IsNew = frame.rawObjectsFrame.isNew,
                    IsTracked = frame.rawObjectsFrame.isTracked,
                    NumObject = frame.rawObjectsFrame.numObject,
                    Timestamp = frame.rawObjectsFrame.timestamp
                }
            };

            foreach (var detectedObject in frame.detectedObjects)
            {
                pocoFrame.DetectedObjects.Add(new Poco.DetectedObject
                {
                    RawObjectData = new Poco.ObjectDataSDK()
                    {
                        actionState = detectedObject.actionState,
                        confidence = detectedObject.confidence,
                        globalRootOrientation = detectedObject.rawObjectData.globalRootOrientation,
                        headBoundingBox = detectedObject.rawObjectData.headBoundingBox,
                        headWorldPosition = detectedObject.rawObjectData.headWorldPosition,
                        id = detectedObject.rawObjectData.id,
                        imageBoundingBox = detectedObject.rawObjectData.imageBoundingBox,
                        keypointConfidence = detectedObject.rawObjectData.keypointConfidence,
                        localOrientationPerJoint = detectedObject.rawObjectData.localOrientationPerJoint,
                        localPositionPerJoint = detectedObject.rawObjectData.localPositionPerJoint,
                        mask = detectedObject.rawObjectData.mask,
                        objectClass = detectedObject.objectClass,
                        objectSubClass = detectedObject.objectSubClass,
                        objectTrackingState = detectedObject.rawObjectData.objectTrackingState,
                        positionCovariance = detectedObject.rawObjectData.positionCovariance,
                        rawLabel = detectedObject.rawObjectData.rawLabel,
                        rootWorldPosition = detectedObject.rawObjectData.rootWorldPosition,
                        rootWorldVelocity = detectedObject.rawObjectData.rootWorldVelocity,
                        skeletonJointPosition2D = detectedObject.rawObjectData.skeletonJointPosition2D,
                        skeletonJointPosition = detectedObject.rawObjectData.skeletonJointPosition,
                        uniqueObjectId = detectedObject.rawObjectData.uniqueObjectId,
                        worldBoundingBox = detectedObject.rawObjectData.worldBoundingBox
                    }
                });
            }

            string json = JsonConvert.SerializeObject(pocoFrame, new Vector2Converter(), new Vector3Converter(), new QuaternionConverter());

            File.AppendAllText(@"C:\Users\nick.steyer\SmartStreetLight\log.txt", json);
        }
    }

    public class Vector2Converter : JsonConverter
    {
        public override bool CanConvert(Type objectType)
        {
            return objectType == typeof(Vector2);
        }

        public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer)
        {
            return new Vector2();
        }

        public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer)
        {
            var vector = (Vector2)value;
            writer.WriteValue($"({vector.x}|{vector.y})");
        }
    }

    public class Vector3Converter : JsonConverter
    {
        public override bool CanConvert(Type objectType)
        {
            return objectType == typeof(Vector3);
        }

        public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer)
        {
            return new Vector3();
        }

        public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer)
        {
            var vector = (Vector3)value;
            writer.WriteValue($"({vector.x}|{vector.y}|{vector.z})");
        }
    }

    public class QuaternionConverter : JsonConverter
    {
        public override bool CanConvert(Type objectType)
        {
            return objectType == typeof(Quaternion);
        }

        public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer)
        {
            return new Quaternion();
        }

        public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer)
        {
            var vector = (Quaternion)value;
            writer.WriteValue($"({vector.x}|{vector.y}|{vector.z}|{vector.w})");
        }
    }
}