using System;
using System.IO;
using System.Linq;
using UnityEditor.SceneManagement;
using UnityEngine.SceneManagement;
using Newtonsoft.Json.Linq;
using UnityEditor;
using UnityEngine;

namespace AIRuntime.Editor
{
    public sealed partial class AIRuntimeKanbanSession
    {
        // One-shot recovery explicitly requested on 2026-10-11. Uses the live
        // scheduler and its normal revision-safe persistence/resume operation.
        [InitializeOnLoadMethod]
        private static void QueueOctober11OperatorRecovery()
        {
            if (!Application.isBatchMode)
                EditorApplication.delayCall += ApplyOctober11OperatorRecovery;
        }

        private static void ApplyOctober11OperatorRecovery()
        {
            string root = Path.GetFullPath(Path.Combine(Application.dataPath, ".."));
            if (!string.Equals(root, @"C:\Projects\AIRuntime", StringComparison.OrdinalIgnoreCase)) return;
            string directory = Path.Combine(root, "Logs", "human-visual-review-recovery-20261012");
            string request = Path.Combine(directory, "request.txt");
            string result = Path.Combine(directory, "result.json");
            if (!File.Exists(request) || File.Exists(result)) return;
            File.Move(request, Path.Combine(directory, "consumed-request.txt"));
            try
            {
                if (EditorApplication.isPlayingOrWillChangePlaymode || EditorApplication.isCompiling)
                    throw new InvalidOperationException("Recovery requires idle Edit Mode.");
                var session = AIRuntimeKanbanScheduler.Session;
                if (session._activeAgentRuns.Count != 0 || session._board.Revision != 9566)
                    throw new InvalidOperationException("Board changed or has an active run; recovery was not applied.");
                const string taskId = "efe89899773a47eaae70f40dbf635161";
                var task = session.FindTask(taskId);
                if (task == null || task.Status != TaskStatus.Todo || task.ReviewStatus != "Retry Available" ||
                    !(task.AgentError ?? string.Empty).StartsWith("Visual verification blocked: no configured provider can accept these images.", StringComparison.Ordinal))
                    throw new InvalidOperationException("Expected the paused visual verification attempt.");
                File.Copy(session.BoardPath, Path.Combine(directory, "board-before.json"), false);
                task.HumanVisualReviewRequired = true;
                task.HumanVisualApprovalFingerprint = string.Empty;
                session.ResumeProviderRetry(task);
                task.NextAgentMessage = "[HumanVisualReviewEnabled] This project has no configured image-capable provider. Screenshot captures are now saved for HUMAN review and no longer sent as image input. Continue feasible automated checks using your saved work; capture fresh representative screenshots under Logs/KanbanVisualReviews/. Do not claim their appearance was inspected. Clearly list the visual checks the human must perform. AIRuntime will require human visual approval after automated review passes. The player prefab tag was repaired and its producer review passed; verify current state rather than repeating the old tag defect.";
                TouchTask(task);
                session.MarkDirty();
                if (!session.PersistSchedulerState()) throw new InvalidOperationException("Could not persist recovery.");
                File.WriteAllText(result, new JObject {
                    ["Outcome"] = "VerificationResumedWithHumanVisualGate", ["TaskId"] = taskId,
                    ["Revision"] = session._board.Revision, ["TimestampUtc"] = DateTime.UtcNow.ToString("O")
                }.ToString());
                AIRuntimeKanbanScheduler.Wake();
            }
            catch (Exception error)
            {
                File.WriteAllText(result, new JObject { ["Outcome"] = "RecoveryIncomplete", ["Error"] = error.Message }.ToString());
                Debug.LogException(error);
            }
        }

        private static Component FindRecoveryUIManager(Scene scene)
        {
            var matches = scene.GetRootGameObjects().SelectMany(root => root.GetComponentsInChildren<Component>(true))
                .Where(component => component != null && component.GetType().FullName == "BallJumpGame.UIManager").ToArray();
            if (matches.Length != 1) throw new InvalidOperationException("Expected exactly one UIManager in " + scene.path);
            return matches[0];
        }

        private static void RepairRecoveryText(SerializedObject manager, string field, string name,
            string text, Component template, float y)
        {
            var property = manager.FindProperty(field);
            var existing = property.objectReferenceValue as Component;
            if (existing != null && existing != template && existing.gameObject.scene == template.gameObject.scene) return;
            GameObject label = UnityEngine.Object.Instantiate(template.gameObject, template.transform.parent);
            label.name = name;
            Undo.RegisterCreatedObjectUndo(label, "Create " + name);
            label.SetActive(true);
            var rect = label.GetComponent<RectTransform>();
            rect.anchorMin = rect.anchorMax = new Vector2(0, 1);
            rect.pivot = new Vector2(0, 1);
            rect.anchoredPosition = new Vector2(20, y);
            rect.sizeDelta = new Vector2(260, 30);
            Component component = label.GetComponent(template.GetType());
            var serialized = new SerializedObject(component);
            serialized.FindProperty("m_Text").stringValue = text;
            serialized.ApplyModifiedProperties();
            property.objectReferenceValue = component;
        }

        private static void VerifyRecoverySavedReferences(Component manager, string scenePath)
        {
            ulong managerId = GlobalObjectId.GetGlobalObjectIdSlow(manager).targetObjectId;
            if (managerId == 0)
                throw new InvalidOperationException("Could not identify saved UIManager.");
            string yaml = File.ReadAllText(scenePath);
            string marker = "--- !u!114 &" + managerId + "\n";
            yaml = yaml.Replace("\r\n", "\n");
            int start = yaml.IndexOf(marker, StringComparison.Ordinal);
            if (start < 0) throw new InvalidOperationException("Saved UIManager was not found.");
            int end = yaml.IndexOf("\n---", start + marker.Length, StringComparison.Ordinal);
            string block = end < 0 ? yaml.Substring(start) : yaml.Substring(start, end - start);
            var serialized = new SerializedObject(manager);
            foreach (string field in new[] { "controlsText", "statusText", "restartText", "livesText", "scoreText" })
            {
                var reference = serialized.FindProperty(field).objectReferenceValue;
                ulong id = GlobalObjectId.GetGlobalObjectIdSlow(reference).targetObjectId;
                if (id == 0 || !block.Contains("  " + field + ": {fileID: " + id + "}"))
                    throw new InvalidOperationException("Saved reference did not match live MainScene object: " + field);
            }
        }

        private static void ValidateRecoveryUI(Component manager, Scene scene)
        {
            var serialized = new SerializedObject(manager);
            var references = new System.Collections.Generic.HashSet<int>();
            foreach (string field in new[] { "controlsText", "statusText", "restartText", "livesText", "scoreText" })
            {
                var component = serialized.FindProperty(field).objectReferenceValue as Component;
                if (component == null || component.gameObject.scene != scene || !references.Add(component.GetInstanceID()))
                    throw new InvalidOperationException("UI reference is missing, shared, or outside MainScene: " + field);
            }
        }
    }
}
// Recovery activation after isolated verification: 2026-10-11.
// Activate integration recovery after the 370 passing focused checks.


// Activate tested image-input pause after 395 passing checks.
// Activate tested human visual review workflow.
