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

namespace ZB.MOM.WW.GRAccess.Cli.GRAccess
{
    public sealed class LlmUnavailableField
    {
        [JsonProperty("field")]
        public string Field { get; set; } = string.Empty;

        [JsonProperty("reason")]
        public string Reason { get; set; } = string.Empty;
    }

    public sealed class LlmError
    {
        [JsonProperty("message")]
        public string Message { get; set; } = string.Empty;

        [JsonProperty("type")]
        public string Type { get; set; } = string.Empty;
    }

    public sealed class LlmResponse
    {
        [JsonProperty("success")]
        public bool Success { get; set; }

        [JsonProperty("command")]
        public string Command { get; set; } = string.Empty;

        [JsonProperty("galaxy")]
        public string Galaxy { get; set; } = string.Empty;

        [JsonProperty("target")]
        public string Target { get; set; } = string.Empty;

        [JsonProperty("data")]
        public object Data { get; set; }

        [JsonProperty("commandResult")]
        public object CommandResult { get; set; }

        [JsonProperty("warnings")]
        public List<string> Warnings { get; set; } = new List<string>();

        [JsonProperty("unavailable")]
        public List<LlmUnavailableField> Unavailable { get; set; } = new List<LlmUnavailableField>();

        [JsonProperty("error")]
        public LlmError Error { get; set; }

        [JsonProperty("exitCode")]
        public int ExitCode { get; set; }

        public static string Ok(string command, string galaxy, string target, object data, object commandResult = null, IEnumerable<string> warnings = null, IEnumerable<LlmUnavailableField> unavailable = null)
        {
            return Serialize(new LlmResponse
            {
                Success = true,
                Command = command,
                Galaxy = galaxy ?? string.Empty,
                Target = target ?? string.Empty,
                Data = data,
                CommandResult = commandResult,
                Warnings = warnings == null ? new List<string>() : new List<string>(warnings),
                Unavailable = unavailable == null ? new List<LlmUnavailableField>() : new List<LlmUnavailableField>(unavailable),
                ExitCode = 0
            });
        }

        public static string Fail(string command, string galaxy, string target, Exception exception, int exitCode = 1)
        {
            return Serialize(new LlmResponse
            {
                Success = false,
                Command = command ?? string.Empty,
                Galaxy = galaxy ?? string.Empty,
                Target = target ?? string.Empty,
                Error = new LlmError
                {
                    Message = exception?.Message ?? "Unknown error",
                    Type = exception?.GetType().Name ?? "Error"
                },
                ExitCode = exitCode
            });
        }

        public static string Serialize(object value)
        {
            return JsonConvert.SerializeObject(value, Formatting.Indented, new JsonSerializerSettings
            {
                NullValueHandling = NullValueHandling.Include
            });
        }
    }
}
