using System;
using System.Linq;
using System.Threading.Tasks;
using AIRuntime.Runtime.Capabilities;
using Newtonsoft.Json;
using Newtonsoft.Json.Linq;

namespace AIRuntime.Editor
{
    // Kanban-only policy. The general conversation/provider image guard remains strict.
    internal sealed class KanbanHumanVisualReviewMiddleware : ICapabilityMiddleware
    {
        internal bool Enabled;
        internal Action<string> EvidenceSink;

        public async Task InvokeAsync(CapabilityContext context, CapabilityDelegate next)
        {
            await next(context);
            if (!Enabled || EvidenceSink == null || context.Exception != null) return;
            context.Result = DeferImages(context.Result, EvidenceSink);
        }

        internal static string DeferImages(string result, Action<string> sink)
        {
            if (string.IsNullOrWhiteSpace(result)) return result;
            JObject report;
            try { report = JObject.Parse(result); }
            catch (JsonException) { return result; }
            if (report.Value<bool?>("Succeeded") == false) return result;
            var artifacts = report["Artifacts"] as JArray;
            if (artifacts == null) return result;
            var images = artifacts.OfType<JObject>().Where(item =>
                string.Equals(item.Value<string>("Kind"), "Image", StringComparison.OrdinalIgnoreCase) ||
                (item.Value<string>("MediaType")?.StartsWith("image/", StringComparison.OrdinalIgnoreCase) ?? false)).ToArray();
            if (images.Length == 0) return result;
            var evidence = new JArray(images.Select(item => item.DeepClone()));
            sink(evidence.ToString(Formatting.None));
            foreach (var image in images) image.Remove();
            report["HumanReviewArtifacts"] = evidence;
            report["VisualVerification"] = "Awaiting human approval. These are saved screenshot descriptions, not image pixels inspected by the agent. Continue nonvisual checks. Report remaining visual checks for the human; never infer appearance from a path, hash, or successful capture.";
            return report.ToString(Formatting.None);
        }
    }
}
