using System;
using System.Threading;
using RebootKit.Engine.Foundation;
using UnityEngine;

namespace RebootKit.Engine.Services.Game {
    [Serializable]
    public class GameModeConfig {
        public ControllerAsset[] Controllers;
    }

    public abstract class GameModeAsset : ScriptableObject {
        [field: SerializeField]
        public GameModeConfig GameModeConfig { get; private set; }

        public GameMode Create() {
            GameMode gameMode = new GameMode(GameModeConfig);
            ConfigureGameMode(gameMode);
            return gameMode;
        }

        public abstract void ConfigureGameMode(GameMode gameMode);
    }

    public class GameMode : IDisposable {
        private readonly GameModeConfig _config;
        private readonly ControllersManager _controllersManager;

        private CancellationTokenSource _destroyCancellationTokenSource;
        
        private bool _isRunning;

        public GameMode(GameModeConfig config) {
            _config = config;
            _isRunning = false;

            _destroyCancellationTokenSource = new CancellationTokenSource();
            _controllersManager = new ControllersManager(_destroyCancellationTokenSource.Token);
        }

        public void Dispose() {
            _destroyCancellationTokenSource.Cancel();
            _controllersManager.Dispose();
        }

        public async Awaitable<bool> Start(CancellationToken cancellationToken) {
            _controllersManager.Add(_config.Controllers);
            await _controllersManager.Start(cancellationToken);

            _isRunning = true;
            return true;
        }

        public void Stop() {
            _isRunning = false;

            _controllersManager.Stop();
        }

        public void Tick() {
            _controllersManager.Tick();
        }

        public void AddController(IController controller) {
            _controllersManager.Add(controller);
        }
    }
}