using System;
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.InputSystem;
using TMPro;

using WebSocketSharp;

using ETSI.ARF.WorldStorage;

using ETSI.ARF.WorldAnalysis;
using ETSI.ARF.WorldAnalysis.REST;
using ETSI.ARF.OpenAPI.WorldAnalysis;
using Pose = ETSI.ARF.OpenAPI.WorldAnalysis.Pose;
using static WorldAnalysisInterface;

public class ClientTest : MonoBehaviour
{
    static public string token = "ARF_Permission";
    static public string session = "HHI";

    public WorldStorageServer worldStorageServer;
    public WorldAnalysisREST waRESTServer;
    public TMP_Text console;
    public GameObject asset1;

    string consoleText = "STF client console\n";
    bool isConsoleText = false;

    // Track this trackable/anchor
    Guid myUUID = Guid.Parse("fa8bbe40-8052-11ec-a8a3-0242ac120002");
    Guid subscriptionUUID;
    int validity = int.MaxValue;

    // Start is called before the first frame update
    void Start()
    {
        if (asset1 != null) asset1.GetComponent<Renderer>().material.color = Color.red;

        AdminRequest.CheckServer(waRESTServer.waServer);

        consoleText += "World Storage server: " + worldStorageServer.URI + "\n";
        consoleText += "World Analysis server: " + waRESTServer.waServer.URI + "\n";
        isConsoleText = true;

        Capability[] caps;
        if (waRESTServer.GetCapabilities(token, out caps) == WorldAnalysisInterface.CapabilityResult.OK)
        {
            waRESTServer.PrintCapabilities(caps);
            consoleText += "\nWA Server capabilities:\n";
            if (caps.Length == 0)
            {
                consoleText += "No capabilities!\n";
            }
            else foreach (var item in caps)
                {
                    consoleText += " " + item.TrackableType.ToString() + " fps=" + item.Framerate + "\n";
                }
            isConsoleText = true;
        }

        bool isSupported = false;
        TypeWorldStorage wsType;
        Capability[] capsOfUUID;
        if (waRESTServer.GetCapability(token, myUUID, out isSupported, out wsType, out capsOfUUID) == WorldAnalysisInterface.CapabilityResult.OK)
        {
            waRESTServer.PrintCapabilities(capsOfUUID);
            consoleText += "\nCapabilities for UUID=" + myUUID.ToString() + ":\n";
            if (caps.Length == 0)
            {
                consoleText += "No capabilities!\n";
            }
            else foreach (var item in capsOfUUID)
                {
                    consoleText += " " + item.TrackableType.ToString() + " fps=" + item.Framerate + "\n";
                }
        }
        else consoleText += "No capabilities found!\n";
        isConsoleText = true;
    }

    // Update is called once per frame
    bool updateAsset1 = false;
    Color asset1Color = Color.grey;
    void Update()
    {
        if (Keyboard.current.spaceKey.wasPressedThisFrame)
        {
            //webSocket.Send("PoseStart:10");
        }

        if (isConsoleText)
        {
            isConsoleText = false;
            console.text = consoleText;
        }

        if (updateAsset1)
        {
            updateAsset1 = false;
            asset1.GetComponent<Renderer>().material.color = asset1Color;
        }
    }

    public void OnButtonTime()
    {
        waRESTServer.WebSocketClient_Send("TimeStart:3");
    }

    public void OnButtonPoseStart()
    {
        SubscribeToPose(true);
    }

    public void OnButtonPoseStop()
    {
        SubscribeToPose(false);
    }

    void SetColor(Color c)
    {
        asset1Color = c;
        updateAsset1 = true;
    }

    public void SubscribeToPose(bool yes = true)
    {
        if (yes)
        {
            InformationSubscriptionResult response = waRESTServer.SubscribeToPose(token, myUUID, Mode_WorldAnalysis.TRACKABLES_TO_DEVICE, PoseCallback, ref validity, out subscriptionUUID);
            if (response == InformationSubscriptionResult.OK)
            {
                SetColor(Color.yellow);
            }
            else SetColor(Color.red);
        }
        else
        {
            waRESTServer.UnsubscribeFromPose(subscriptionUUID);
            SetColor(Color.red);
        }
    }

    public void MessageCallback(string messageFromServer)
    {
        if (messageFromServer.StartsWith("Time="))
        {
            Debug.Log("[CLIENT] Server time is: " + messageFromServer.Split('=')[1]);

            // test the communication
            consoleText += "Server time is: " + messageFromServer.Split('=')[1] + "\n";
            isConsoleText = true;
        }
    }

    public void PoseCallback(WorldAnalysisInterface.PoseEstimationResult result, ETSI.ARF.OpenAPI.WorldAnalysis.Pose pose)
    {
        switch (result)
        {
            case PoseEstimationResult.OK:
                SetColor(Color.green);
                //asset1.transform.rotation = WorldAnalysisUnityHelper.ConvertETSIARFQuaternionToUnity(pose.Value.ro...)
                break;

            case PoseEstimationResult.NONE:
                SetColor(Color.yellow);
                break;

            default:
                SetColor(Color.red);
                break;
        }
    }
}
