#if UNITY_EDITOR
using System.Collections;
using System.Collections.Generic;
using System.IO;
using UnityEngine;

namespace Davanci.Nexus
{
    // Captures store marketing screenshots at exact App Store resolutions during Play Mode.
    // Spawned by the editor tool (Davanci Nexus -> App Store Screenshots). Editor-only, so it
    // never ships in builds.
    public class NexusScreenshotCapture : MonoBehaviour
    {
        public struct Resolution
        {
            public string FolderName;
            public int Width;
            public int Height;
        }

        public static NexusScreenshotCapture Spawn()
        {
            var go = new GameObject("_NexusScreenshotCapture");
            DontDestroyOnLoad(go);
            return go.AddComponent<NexusScreenshotCapture>();
        }

        public void CaptureAll(List<Resolution> resolutions, string rootFolder, System.Action<string> onStatus, System.Action onDone)
        {
            StartCoroutine(CaptureSequence(resolutions, rootFolder, onStatus, onDone));
        }

        static int NextFileIndex(string folder)
        {
            int max = 0;
            foreach (var file in Directory.GetFiles(folder, "*.png"))
            {
                string name = Path.GetFileNameWithoutExtension(file);
                if (int.TryParse(name, out int n) && n > max)
                    max = n;
            }
            return max + 1;
        }

        IEnumerator CaptureSequence(List<Resolution> resolutions, string rootFolder, System.Action<string> onStatus, System.Action onDone)
        {
            // Gather all root overlay canvases once
            var allCanvases = FindObjectsByType<Canvas>(FindObjectsSortMode.None);
            var overlayCanvases = new List<Canvas>();
            foreach (var c in allCanvases)
                if (c.isRootCanvas && c.renderMode == RenderMode.ScreenSpaceOverlay)
                    overlayCanvases.Add(c);

            var origModes   = new RenderMode[overlayCanvases.Count];
            var origCameras = new Camera[overlayCanvases.Count];

            foreach (var res in resolutions)
            {
                onStatus?.Invoke($"Capturing {res.FolderName}...");

                var rt = new RenderTexture(res.Width, res.Height, 24, RenderTextureFormat.ARGB32);
                rt.Create();

                var mainCam = Camera.main;
                var origTarget = mainCam != null ? mainCam.targetTexture : null;

                // Switch overlays to ScreenSpaceCamera so they render through mainCam into rt
                if (mainCam != null)
                {
                    mainCam.targetTexture = rt;

                    for (int i = 0; i < overlayCanvases.Count; i++)
                    {
                        origModes[i]   = overlayCanvases[i].renderMode;
                        origCameras[i] = overlayCanvases[i].worldCamera;
                        overlayCanvases[i].renderMode  = RenderMode.ScreenSpaceCamera;
                        overlayCanvases[i].worldCamera = mainCam;
                    }
                }

                // Let Cinemachine + Unity render a full frame into rt
                yield return new WaitForEndOfFrame();

                // Read pixels
                RenderTexture.active = rt;
                var tex = new Texture2D(res.Width, res.Height, TextureFormat.RGB24, false);
                tex.ReadPixels(new Rect(0, 0, res.Width, res.Height), 0, 0);
                tex.Apply();

                string folder = Path.Combine(rootFolder, res.FolderName);
                Directory.CreateDirectory(folder);
                int nextIndex = NextFileIndex(folder);
                string path = Path.Combine(folder, $"{nextIndex}.png");
                File.WriteAllBytes(path, tex.EncodeToPNG());
                Debug.Log($"[Nexus] Screenshot saved: {path}");

                // Restore
                RenderTexture.active = null;
                if (mainCam != null)
                {
                    mainCam.targetTexture = origTarget;

                    for (int i = 0; i < overlayCanvases.Count; i++)
                    {
                        overlayCanvases[i].renderMode  = origModes[i];
                        overlayCanvases[i].worldCamera = origCameras[i];
                    }
                }

                Destroy(tex);
                rt.Release();
                Destroy(rt);

                // One frame gap before next capture
                yield return null;
            }

            onDone?.Invoke();
            Destroy(gameObject);
        }
    }
}
#endif
