using System;
using _Core;
using Newtonsoft.Json;
using Newtonsoft.Json.Linq;

namespace _Combo
{
    public class StoreContext : Serializable { }
    public class PurchaseOptions : Serializable { }

    // PurchaseOptions

    public class SeayooPurchaseOptions : PurchaseOptions
    {
        [JsonProperty("payment_methods")]
        public string[] paymentMethods;
    }

    public class LenovoPCPurchaseOptions : PurchaseOptions
    {
        [JsonProperty("notify_url")]
        public string notifyUrl;
        [JsonProperty("extra_common_param")]
        public string extraCommonParam;
    }

    // Order

    public class Order : Serializable
    {
        [JsonProperty("order_id")]
        public string orderId;

        [JsonProperty("product_id")]
        public string productId;

        [JsonProperty("product_name")]
        public string productName;

        [JsonProperty("quantity")]
        public int quantity;

        [JsonProperty("currency")]
        public string currency;

        [JsonProperty("amount")]
        public int amount;

        [JsonProperty("status")]
        public string status;
    }

    public class Request : Serializable
    {
        [JsonProperty("order_token")]
        public string orderToken;

        [JsonProperty("store")]
        public string store;

        [JsonProperty("context")]
        public StoreContext context;
    }

    public class Response : Serializable
    {
        [JsonProperty("order")]
        public Order order;

        [JsonProperty("store")]
        public string store;

        [JsonConverter(typeof(PurchaseOptionsConverter))]
        [JsonProperty("purchase_options")]
        public PurchaseOptions purchaseOptions;
    }

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

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

            if (obj["payment_methods"] != null)
            {
                return obj.ToObject<SeayooPurchaseOptions>(serializer);
            }
            else if(obj["notify_url"] != null)
            {
                return obj.ToObject<LenovoPCPurchaseOptions>(serializer);
            }
            else
            {
                return new PurchaseOptions();
            }
        }

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