using System;
using System.Collections.Generic;
using Newtonsoft.Json;
using Newtonsoft.Json.Linq;

namespace _Combo
{
    [Serializable]
    public class Command
    {
        public string cmd;
        [JsonConverter(typeof(ArgsConverter))]
        [JsonProperty(NullValueHandling = NullValueHandling.Ignore)] 
        public Args args;
    }

    [Serializable]
    public class Args {}

    [Serializable]
    public class OpenInBrowserArgs : Args
    {
        public string url;
    }

    [Serializable]
    public class OpenShortLinkArgs : Args
    {
        [JsonProperty("short_link")]
        public string shortLink;
        [JsonProperty("game_data")]
        public Dictionary<string, string> gameData;
    }

    [Serializable]
    public class CaptchaResultArgs : Args
    {
        [JsonProperty("captcha_id")]
        public string captchaId;
        [JsonProperty("captcha_result")]
        public string captchaResult;
    }


    public class JSResponse
    {
    }

    public class ListJSResponse : JSResponse
    {
        [JsonProperty("supported_cmds")]
        public string[] supportedCmds { get; set; }
    }
    public class OpenShortLinkJSSuccessResponse : JSResponse
    {
        public string error { get; set; }
    }

    public class OpenShortLinkJSFailResponse : JSResponse
    {
        public string error { get; set; }
        [JsonProperty("user_message")]
        public string UserMessage { get; set; }
        [JsonProperty("developer_message")]
        public string DeveloperMessage { get; set; }
    }

    public class GameAssetsSuccessResponse : JSResponse
    {
        public bool available { get; set; }
        [JsonProperty("base_url")]
        public string baseUrl { get; set; }
        public List<string> assets { get; set; }
    }

    public class GameAssetsFailResponse : JSResponse
    {
        public bool available { get; set; }
    }
    
    public class JSCallback
    {
        public string cmd { get; set; }
        public JSResponse response { get; set; }
    }

    internal class ArgsConverter : JsonConverter
    {
        public override bool CanConvert(Type objectType)
        {
            return objectType == typeof(Args);
        }

        public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer)
        {
            JObject obj = JObject.Load(reader);

            if (obj["url"] != null)
            {
                return obj.ToObject<OpenInBrowserArgs>(serializer);
            }
            else if(obj["short_link"] != null)
            {
                return obj.ToObject<OpenShortLinkArgs>(serializer);
            }
            else if(obj["captcha_id"] != null)
            {
                return obj.ToObject<CaptchaResultArgs>(serializer);
            }
            else
            {
                throw new JsonSerializationException("Unknown subclass of Args");
            }
        }

        public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer)
        {
            JToken t = JToken.FromObject(value);
            t.WriteTo(writer);
        }
    }
}