#if UNITY_IOS && (DEVELOPMENT_BUILD || UNITY_EDITOR)

using UnityEngine;
using System.IO;
using System.Text;
using System.Collections.Generic;
using System.Threading;

namespace Blackbox
{
    public static class LogWriter
    {
        private static string logPath;
        private static StreamWriter writer;

        // Rolling buffer for last logs
        private static readonly Queue<string> logBuffer = new Queue<string>(5000);
        private const int MaxLines = 5000;

        // Async trimming
        private static int logCountSinceTrim = 0;
        private const int TrimThreshold = 500; // rewrite every 500 logs
        private static readonly object fileLock = new object();

        private static Thread trimThread;
        private static bool trimRequested = false;
        private static bool quitting = false;

        private static string headerText;

        [RuntimeInitializeOnLoadMethod(RuntimeInitializeLoadType.BeforeSceneLoad)]
        private static void Init()
        {
            logPath = Path.Combine(Application.persistentDataPath, "Player.log");

            writer = new StreamWriter(logPath, false, Encoding.UTF8) { AutoFlush = true };
            WriteHeader();

            Application.logMessageReceived += HandleLog;
            Application.quitting += OnQuit;

            // Background thread for trimming
            trimThread = new Thread(TrimWorker) { IsBackground = true };
            trimThread.Start();
        }

        private static void HandleLog(string logString, string stackTrace, LogType type)
        {
            string entry = $"[{type}] {logString}";
            if (!string.IsNullOrEmpty(stackTrace))
                entry += "\n" + stackTrace;

            lock (logBuffer)
            {
                if (logBuffer.Count >= MaxLines)
                    logBuffer.Dequeue();
                logBuffer.Enqueue(entry);
            }

            lock (fileLock)
            {
                writer.WriteLine(entry);
            }

            // Trigger background trim after threshold
            logCountSinceTrim++;
            if (logCountSinceTrim >= TrimThreshold)
            {
                trimRequested = true;
                logCountSinceTrim = 0;
            }
        }

        private static void WriteHeader()
        {
            headerText = $"=== Player.log started {System.DateTime.Now} ===\n" +
                         $"Unity {Application.unityVersion} | App {Application.version}\n" +
                         $"Device: {SystemInfo.deviceModel} ({SystemInfo.operatingSystem})\n" +
                         $"Graphics: {SystemInfo.graphicsDeviceName}\n";

            lock (fileLock)
            {
                writer.WriteLine(headerText);
            }
        }

        private static void TrimWorker()
        {
            while (!quitting)
            {
                if (trimRequested)
                {
                    trimRequested = false;
                    RewriteFile();
                }

                Thread.Sleep(200); // avoid CPU spin
            }
        }

        private static void RewriteFile()
        {
            string[] linesCopy;
            lock (logBuffer)
            {
                linesCopy = logBuffer.ToArray();
            }

            lock (fileLock)
            {
                writer.Close();
                writer = new StreamWriter(logPath, false, Encoding.UTF8) { AutoFlush = true };

                // Always prepend header
                writer.WriteLine(headerText);

                foreach (string line in linesCopy)
                    writer.WriteLine(line);
            }
        }

        private static void OnQuit()
        {
            quitting = true;

            RewriteFile();

            lock (fileLock)
            {
                writer?.Close();
                writer = null;
            }
        }
    }
}

#endif
