using System;
using System.Collections.Generic;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Mvc;
using Haoliang.Core.Services;
using Haoliang.Models.Common;

namespace Haoliang.Api.Controllers
{
    [Route("api/v1/realtime")]
    [ApiController]
    public class RealTimeController : ControllerBase
    {
        private readonly IRealTimeService _realTimeService;

        public RealTimeController(IRealTimeService realTimeService)
        {
            _realTimeService = realTimeService;
        }

        /// <summary>
        /// Get connected clients count
        /// </summary>
        [HttpGet("clients/count")]
        public async Task<ActionResult<ApiResponse<int>>> GetConnectedClientsCount()
        {
            try
            {
                var count = await _realTimeService.GetConnectedClientsCountAsync();
                return Ok(ApiResponse<int>.Success(count));
            }
            catch (Exception ex)
            {
                return StatusCode(500, ApiResponse<int>.InternalServerError($"Error getting connected clients count: {ex.Message}"));
            }
        }

        /// <summary>
        /// Get connected clients by type
        /// </summary>
        [HttpGet("clients/{clientType}")]
        public async Task<ActionResult<ApiResponse<List<ClientInfo>>>> GetConnectedClientsByType(string clientType)
        {
            try
            {
                var clients = await _realTimeService.GetConnectedClientsByTypeAsync(clientType);
                return Ok(ApiResponse<List<ClientInfo>>.Success(clients));
            }
            catch (Exception ex)
            {
                return StatusCode(500, ApiResponse<List<ClientInfo>>.InternalServerError($"Error getting connected clients by type: {ex.Message}"));
            }
        }

        /// <summary>
        /// Get device monitoring status
        /// </summary>
        [HttpGet("devices/{deviceId}/monitoring")]
        public async Task<ActionResult<ApiResponse<DeviceMonitoringStatus>>> GetDeviceMonitoringStatus(int deviceId)
        {
            try
            {
                var status = await _realTimeService.GetDeviceMonitoringStatusAsync(deviceId);
                return Ok(ApiResponse<DeviceMonitoringStatus>.Success(status));
            }
            catch (Exception ex)
            {
                return StatusCode(500, ApiResponse<DeviceMonitoringStatus>.InternalServerError($"Error getting device monitoring status: {ex.Message}"));
            }
        }

        /// <summary>
        /// Start device streaming
        /// </summary>
        [HttpPost("devices/{deviceId}/streaming/start")]
        public async Task<ActionResult<ApiResponse<bool>>> StartDeviceStreaming(
            int deviceId,
            [FromQuery] int intervalMs = 1000)
        {
            try
            {
                await _realTimeService.StartDeviceStreamingAsync(deviceId, intervalMs);
                return Ok(ApiResponse<bool>.Success(true));
            }
            catch (Exception ex)
            {
                return StatusCode(500, ApiResponse<bool>.InternalServerError($"Error starting device streaming: {ex.Message}"));
            }
        }

        /// <summary>
        /// Stop device streaming
        /// </summary>
        [HttpPost("devices/{deviceId}/streaming/stop")]
        public async Task<ActionResult<ApiResponse<bool>>> StopDeviceStreaming(int deviceId)
        {
            try
            {
                await _realTimeService.StopDeviceStreamingAsync(deviceId);
                return Ok(ApiResponse<bool>.Success(true));
            }
            catch (Exception ex)
            {
                return StatusCode(500, ApiResponse<bool>.InternalServerError($"Error stopping device streaming: {ex.Message}"));
            }
        }

        /// <summary>
        /// Get active streaming devices
        /// </summary>
        [HttpGet("devices/streaming/active")]
        public async Task<ActionResult<ApiResponse<List<int>>>> GetActiveStreamingDevices()
        {
            try
            {
                var devices = await _realTimeService.GetActiveStreamingDevicesAsync();
                return Ok(ApiResponse<List<int>>.Success(devices));
            }
            catch (Exception ex)
            {
                return StatusCode(500, ApiResponse<List<int>>.InternalServerError($"Error getting active streaming devices: {ex.Message}"));
            }
        }

        /// <summary>
        /// Send test device status update
        /// </summary>
        [HttpPost("devices/{deviceId}/status")]
        public async Task<ActionResult<ApiResponse<bool>>> SendDeviceStatusUpdate(
            int deviceId,
            [FromBody] DeviceStatusUpdate statusUpdate)
        {
            try
            {
                statusUpdate.DeviceId = deviceId;
                statusUpdate.Timestamp = DateTime.UtcNow;
                
                await _realTimeService.BroadcastDeviceStatusAsync(statusUpdate);
                return Ok(ApiResponse<bool>.Success(true));
            }
            catch (Exception ex)
            {
                return StatusCode(500, ApiResponse<bool>.InternalServerError($"Error sending device status update: {ex.Message}"));
            }
        }

        /// <summary>
        /// Send test production update
        /// </summary>
        [HttpPost("devices/{deviceId}/production")]
        public async Task<ActionResult<ApiResponse<bool>>> SendProductionUpdate(
            int deviceId,
            [FromBody] ProductionUpdate productionUpdate)
        {
            try
            {
                productionUpdate.DeviceId = deviceId;
                productionUpdate.Timestamp = DateTime.UtcNow;
                
                await _realTimeService.BroadcastProductionUpdateAsync(productionUpdate);
                return Ok(ApiResponse<bool>.Success(true));
            }
            catch (Exception ex)
            {
                return StatusCode(500, ApiResponse<bool>.InternalServerError($"Error sending production update: {ex.Message}"));
            }
        }

        /// <summary>
        /// Send test alert
        /// </summary>
        [HttpPost("alerts")]
        public async Task<ActionResult<ApiResponse<bool>>> SendAlert([FromBody] AlertUpdate alertUpdate)
        {
            try
            {
                alertUpdate.Timestamp = DateTime.UtcNow;
                await _realTimeService.BroadcastAlertAsync(alertUpdate);
                return Ok(ApiResponse<bool>.Success(true));
            }
            catch (Exception ex)
            {
                return StatusCode(500, ApiResponse<bool>.InternalServerError($"Error sending alert: {ex.Message}"));
            }
        }

        /// <summary>
        /// Send system notification
        /// </summary>
        [HttpPost("notifications")]
        public async Task<ActionResult<ApiResponse<bool>>> SendSystemNotification([FromBody] SystemNotification notification)
        {
            try
            {
                notification.Timestamp = DateTime.UtcNow;
                await _realTimeService.SendSystemNotificationAsync(notification);
                return Ok(ApiResponse<bool>.Success(true));
            }
            catch (Exception ex)
            {
                return StatusCode(500, ApiResponse<bool>.InternalServerError($"Error sending system notification: {ex.Message}"));
            }
        }

        /// <summary>
        /// Send dashboard update
        /// </summary>
        [HttpPost("dashboard")]
        public async Task<ActionResult<ApiResponse<bool>>> SendDashboardUpdate([FromBody] DashboardUpdate dashboardUpdate)
        {
            try
            {
                dashboardUpdate.Timestamp = DateTime.UtcNow;
                await _realTimeService.SendDashboardUpdateAsync(dashboardUpdate);
                return Ok(ApiResponse<bool>.Success(true));
            }
            catch (Exception ex)
            {
                return StatusCode(500, ApiResponse<bool>.InternalServerError($"Error sending dashboard update: {ex.Message}"));
            }
        }

        /// <summary>
        /// Send command to specific client
        /// </summary>
        [HttpPost("clients/{connectionId}/command")]
        public async Task<ActionResult<ApiResponse<bool>>> SendCommandToClient(
            string connectionId,
            [FromBody] RealTimeCommand command)
        {
            try
            {
                command.Timestamp = DateTime.UtcNow;
                await _realTimeService.SendCommandToClientAsync(connectionId, command);
                return Ok(ApiResponse<bool>.Success(true));
            }
            catch (Exception ex)
            {
                return StatusCode(500, ApiResponse<bool>.InternalServerError($"Error sending command to client: {ex.Message}"));
            }
        }

        /// <summary>
        /// Broadcast command to all clients
        /// </summary>
        [HttpPost("command/broadcast")]
        public async Task<ActionResult<ApiResponse<bool>>> BroadcastCommand([FromBody] RealTimeCommand command)
        {
            try
            {
                command.Timestamp = DateTime.UtcNow;
                await _realTimeService.BroadcastCommandAsync(command);
                return Ok(ApiResponse<bool>.Success(true));
            }
            catch (Exception ex)
            {
                return StatusCode(500, ApiResponse<bool>.InternalServerError($"Error broadcasting command: {ex.Message}"));
            }
        }

        /// <summary>
        /// Get WebSocket connection URL
        /// </summary>
        [HttpGet("connection-url")]
        public ActionResult<ApiResponse<string>> GetConnectionUrl()
        {
            try
            {
                var baseUrl = $"{Request.Scheme}://{Request.Host}";
                var connectionUrl = $"{baseUrl}/realtimehub";
                
                return Ok(ApiResponse<string>.Success(connectionUrl));
            }
            catch (Exception ex)
            {
                return StatusCode(500, ApiResponse<string>.InternalServerError($"Error getting connection URL: {ex.Message}"));
            }
        }

        /// <summary>
        /// Test WebSocket connectivity
        /// </summary>
        [HttpGet("test")]
        public async Task<ActionResult<ApiResponse<TestResult>>> TestWebSocket()
        {
            try
            {
                var testResult = new TestResult
                {
                    TestId = Guid.NewGuid().ToString(),
                    Timestamp = DateTime.UtcNow,
                    ConnectedClients = await _realTimeService.GetConnectedClientsCountAsync(),
                    ActiveStreamingDevices = await _realTimeService.GetActiveStreamingDevicesAsync(),
                    Status = "Success"
                };

                return Ok(ApiResponse<TestResult>.Success(testResult));
            }
            catch (Exception ex)
            {
                return StatusCode(500, ApiResponse<TestResult>.InternalServerError($"Error testing WebSocket: {ex.Message}"));
            }
        }

        /// <summary>
        /// Get WebSocket statistics
        /// </summary>
        [HttpGet("statistics")]
        public async Task<ActionResult<ApiResponse<WebSocketStatistics>>> GetWebSocketStatistics()
        {
            try
            {
                var connectedClients = await _realTimeService.GetConnectedClientsCountAsync();
                var streamingDevices = await _realTimeService.GetActiveStreamingDevicesAsync();
                
                var stats = new WebSocketStatistics
                {
                    Timestamp = DateTime.UtcNow,
                    ConnectedClients = connectedClients,
                    ActiveStreamingDevices = streamingDevices.Count,
                    TotalSessions = connectedClients, // Simplified
                    MessageCount = 0, // Would need to track this in the service
                    BytesTransferred = 0 // Would need to track this in the service
                };

                return Ok(ApiResponse<WebSocketStatistics>.Success(stats));
            }
            catch (Exception ex)
            {
                return StatusCode(500, ApiResponse<WebSocketStatistics>.InternalServerError($"Error getting WebSocket statistics: {ex.Message}"));
            }
        }

        /// <summary>
        /// Force refresh dashboard data
        /// </summary>
        [HttpPost("dashboard/refresh")]
        public async Task<ActionResult<ApiResponse<bool>>> RefreshDashboardData()
        {
            try
            {
                // This would trigger the dashboard update logic
                // Implementation depends on specific requirements
                return Ok(ApiResponse<bool>.Success(true));
            }
            catch (Exception ex)
            {
                return StatusCode(500, ApiResponse<bool>.InternalServerError($"Error refreshing dashboard data: {ex.Message}"));
            }
        }
    }
}