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

using ETSI.ARF.OpenAPI;
using ETSI.ARF.OpenAPI.WorldStorage;
using ETSI.ARF.WorldStorage;
using ETSI.ARF.WorldStorage.REST;

public class OpenAPITest : MonoBehaviour
{
    public WorldStorageServer server;
    public TMP_Text servername;
    public TMP_Text output;

    private string msg = null;
    private Queue handleResponseQ = new Queue();

    private Guid lastUUID = Guid.Empty;

    // Start is called before the first frame update
    void Start()
    {
        if (servername) servername.text = "ARF Server: <color=yellow>" + server.basePath + "</color>";
    }

    // Update is called once per frame
    void Update()
    {
        if (msg != null)
        {
            output.text = msg;
            msg = null;
        }

        if (handleResponseQ.Count > 0)
        {
            object o = handleResponseQ.Dequeue();
            if (o is ResponseObject<string>)
            {
                ResponseObject<string> response = o as ResponseObject<string>;
                output.text = $"Request Time: { response.requestTime.ToLongTimeString() } / Total Time: { response.DeltaTime.TotalMilliseconds }ms\n\n<b>Content:</b>\n{ response.result }";
            }
            else if (o is ResponseObject<Trackable>)
            {
                ResponseObject<Trackable> response = o as ResponseObject<Trackable>;
                output.text = $"Request Time: { response.requestTime.ToLongTimeString() } / Total Time: { response.DeltaTime.TotalMilliseconds }ms\n\n<b>Content:</b>\nUUID={ response.result.UUID}\nName={ response.result.Name }\nType={ response.result.TrackableType }";
            }
            else if (o is ResponseObject<List<Trackable>>)
            {
                ResponseObject<List<Trackable>> response = o as ResponseObject<List<Trackable>>;
                output.text = $"Request Time: { response.requestTime.ToLongTimeString() } / Total Time: { response.DeltaTime.TotalMilliseconds }ms\n\n<b>Content:</b>\nNum of trackable objects={ response.result.Count }";
                int i = 0;
                foreach (var t in response.result)
                {
                    output.text += $"\n{ i++ }:  UUID={ t.UUID }";
                    lastUUID = t.UUID;
                }
            }
        }
    }

    public void OnButtonClick_TestPing()
    {
        if (server == null)
        {
            output.text = "Error: No server defined!";
            return;
        }

        ResponseObject<string> token = AdminRequest.PingAsync(server, (response) =>
        {
            handleResponseQ.Enqueue(response);
        });
        output.text = "Starting request @ time: " + token.requestTime.ToLongTimeString() + "...";
    }

    public void OnButtonClick_GetLastTrackable()
    {
        if (server == null)
        {
            output.text = "Error: No server defined!";
            return;
        }

        if (lastUUID == Guid.Empty)
        {
            output.text = "Error: Please, load first a list!";
            return;
        }

        ResponseObject<Trackable> token = TrackableRequest.GetTrackableAsync(server, lastUUID, (response) =>
        {
            handleResponseQ.Enqueue(response);
        });
        output.text = "Starting request @ time: " + token.requestTime.ToLongTimeString() + "...";
    }

    public void OnButtonClick_GetAllTrackables()
    {
        if (server == null)
        {
            output.text = "Error: No server defined!";
            return;
        }

        ResponseObject<List<Trackable>> token = TrackableRequest.GetTrackablesAsync(server, (response) =>
        {
            handleResponseQ.Enqueue(response);
        });
        output.text = "Starting request @ time: " + token.requestTime.ToLongTimeString() + "...";
    }

    public void OnButtonClick_CreateTrackable()
    {
        if (server == null)
        {
            output.text = "Error: No server defined!";
            return;
        }

        Trackable tr = new Trackable(DateTime.Now.ToFileTime().ToString());
        tr.TrackableType = TrackableType.OTHER;
        ResponseObject<string> token = TrackableRequest.CreateTrackableAsync(server, tr, (response) =>
        {
            lastUUID = Guid.Parse(response.result);
            handleResponseQ.Enqueue(response);
        });
        lastUUID = Guid.Empty;
    }

    public void OnButtonClick_UpdateLastTrackable()
    {
        if (server == null)
        {
            output.text = "Error: No server defined!";
            return;
        }

        if (lastUUID == Guid.Empty)
        {
            output.text = "Error: Please, load first a list!";
            return;
        }

        ResponseObject<Trackable> token = TrackableRequest.GetTrackableAsync(server, lastUUID, (response) =>
        {
            response.result.Name += "'";
            ResponseObject<string> token = TrackableRequest.UpdateTrackableAsync(server, response.result, (response) =>
            {
                handleResponseQ.Enqueue(response);
            });
        });
    }

    public void OnButtonClick_DeleteLastTrackable()
    {
        if (server == null)
        {
            output.text = "Error: No server defined!";
            return;
        }

        if (lastUUID == Guid.Empty)
        {
            output.text = "Error: Please, load first a list!";
            return;
        }

        ResponseObject<string> token = TrackableRequest.DeleteTrackableAsync(server, lastUUID, (response) =>
        {
            handleResponseQ.Enqueue(response);
            lastUUID = Guid.Empty;
        });
    }
}