using GEUTEBRUECK.GeViSoftSDKNET.ActionsWrapper;
using GEUTEBRUECK.GeViSoftSDKNET.ActionsWrapper.SystemActions;
using Serilog;

namespace GeViScopeBridge.SDK
{
    /// <summary>
    /// Handles state queries using GetFirst/GetNext enumeration pattern
    /// </summary>
    public class StateQueryHandler
    {
        private readonly GeViDatabaseWrapper _dbWrapper;
        private readonly ILogger _logger;

        public StateQueryHandler(GeViDatabaseWrapper dbWrapper, ILogger logger)
        {
            _dbWrapper = dbWrapper ?? throw new ArgumentNullException(nameof(dbWrapper));
            _logger = logger ?? throw new ArgumentNullException(nameof(logger));
        }

        /// <summary>
        /// Enumerate all video inputs (cameras) using GetFirst/GetNext pattern
        /// </summary>
        public async Task<List<VideoInputInfo>> EnumerateCamerasAsync()
        {
            var cameras = new List<VideoInputInfo>();

            if (!await _dbWrapper.EnsureConnectedAsync())
            {
                throw new InvalidOperationException("Not connected to GeViServer");
            }

            try
            {
                _logger.Debug("Starting camera enumeration");

                // Get first video input
                var firstQuery = new CSQGetFirstVideoInput();
                _dbWrapper.Database!.SendMessage(firstQuery.ToActionMessage());

                // Wait a bit for response (synchronous SDK call)
                await Task.Delay(100);

                // TODO: Implement actual response handling with callbacks
                // For now, this is a placeholder structure

                _logger.Information("Camera enumeration completed: {Count} cameras found", cameras.Count);
                return cameras;
            }
            catch (Exception ex)
            {
                _logger.Error(ex, "Failed to enumerate cameras");
                throw;
            }
        }

        /// <summary>
        /// Enumerate all video outputs (monitors) using GetFirst/GetNext pattern
        /// </summary>
        public async Task<List<VideoOutputInfo>> EnumerateMonitorsAsync()
        {
            var monitors = new List<VideoOutputInfo>();

            if (!await _dbWrapper.EnsureConnectedAsync())
            {
                throw new InvalidOperationException("Not connected to GeViServer");
            }

            try
            {
                _logger.Debug("Starting monitor enumeration");

                // Get first video output
                var firstQuery = new CSQGetFirstVideoOutput();
                _dbWrapper.Database!.SendMessage(firstQuery.ToActionMessage());

                // Wait a bit for response
                await Task.Delay(100);

                // TODO: Implement actual response handling with callbacks

                _logger.Information("Monitor enumeration completed: {Count} monitors found", monitors.Count);
                return monitors;
            }
            catch (Exception ex)
            {
                _logger.Error(ex, "Failed to enumerate monitors");
                throw;
            }
        }
    }

    /// <summary>
    /// Video input (camera) information
    /// </summary>
    public class VideoInputInfo
    {
        public int Id { get; set; }                    // GlobalID/Channel
        public string Name { get; set; } = string.Empty;
        public string Description { get; set; } = string.Empty;
        public bool HasPTZ { get; set; }
        public bool HasVideoSensor { get; set; }
        public string Status { get; set; } = "unknown";
    }

    /// <summary>
    /// Video output (monitor) information
    /// </summary>
    public class VideoOutputInfo
    {
        public int Id { get; set; }                    // GlobalID/Channel
        public string Name { get; set; } = string.Empty;
        public string Description { get; set; } = string.Empty;
        public bool IsActive { get; set; }
        public int CurrentCameraId { get; set; } = -1;  // -1 = no camera
        public string Status { get; set; } = "unknown";
    }
}
