using ModMenu;
using Func;
using System;
using System.Threading;

namespace FreezeThread {
    public class WorkThread {
        private Thread MainThread;
        private bool running = false;
        public enum ThreadStatus { Running, Paused, Stopped }
        private ThreadStatus status = ThreadStatus.Stopped;
        private readonly object statusLock = new object();

        public ThreadStatus Status {
            get {
                lock (statusLock) {
                    return status;
                }
            }
            private set {
                lock (statusLock) {
                    status = value;
                }
            }
        }

        private readonly ManualResetEventSlim pauseEvent = new ManualResetEventSlim(true);
        private readonly Action ThreadAction;

        public WorkThread(Action ThreadAction) {
            this.ThreadAction = ThreadAction
                ?? throw new ArgumentNullException(nameof(ThreadAction));
        }

        private void ThreadLoop() {
            while (running) {
                try {
                    pauseEvent.Wait();

                    if (pauseEvent.IsSet)
                        Status = ThreadStatus.Running;

                    ThreadAction();
                    Thread.Sleep(1); // Prevent CPU Exhaustion by adding small delay
                } catch (ArgumentOutOfRangeException ex) {
                    running = false;
                    Status = ThreadStatus.Stopped;
                    Console.WriteLine($"Thread Killed! Caught: {ex}");
                }
            }

            Status = ThreadStatus.Stopped;
        }

        public void Start() {
            if (running)
                return;

            MainThread = new Thread(ThreadLoop);
            MainThread.IsBackground = true;
            running = true;
            MainThread.Start();
        }

        public void Pause() {
            if (Status == ThreadStatus.Running) {
                pauseEvent.Reset();
                Status = ThreadStatus.Paused;
            }
        }

        public void Resume() {
            if (Status == ThreadStatus.Paused) {
                pauseEvent.Set();
                Status = ThreadStatus.Running;
            }
        }

        public void Stop() {
            running = false;
            pauseEvent.Set();
            MainThread?.Join();
            Status = ThreadStatus.Stopped;
        }
    }
}
