using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Mvc;
using Haoliang.Core.Services;
using Haoliang.Models.Device;
using Haoliang.Models.DataCollection;
using Haoliang.Models.System;
using Haoliang.Models.Template;

namespace Haoliang.Api.Controllers
{
    [ApiController]
    [Route("api/v1/[controller]")]
    public class DeviceController : ControllerBase
    {
        private readonly IDeviceCollectionService _collectionService;
        private readonly IProductionService _productionService;
        private readonly IAlarmService _alarmService;
        private readonly ITemplateService _templateService;
        private readonly ISystemConfigService _configService;
        private readonly ILoggingService _loggingService;

        public DeviceController(
            IDeviceCollectionService collectionService,
            IProductionService productionService,
            IAlarmService alarmService,
            ITemplateService templateService,
            ISystemConfigService configService,
            ILoggingService loggingService)
        {
            _collectionService = collectionService;
            _productionService = productionService;
            _alarmService = alarmService;
            _templateService = templateService;
            _configService = configService;
            _loggingService = loggingService;
        }

        [HttpGet]
        public async Task<IActionResult> GetAllDevices()
        {
            try
            {
                var devices = await _collectionService.GetAllDevicesAsync();
                return Ok(ApiResponse.Success(devices));
            }
            catch (Exception ex)
            {
                await _loggingService.LogErrorAsync("Failed to get devices", ex);
                return StatusCode(500, ApiResponse.Error("Failed to get devices"));
            }
        }

        [HttpGet("{id}")]
        public async Task<IActionResult> GetDevice(int id)
        {
            try
            {
                var device = await _collectionService.GetDeviceByIdAsync(id);
                if (device == null)
                {
                    return NotFound(ApiResponse.NotFound("Device not found"));
                }
                return Ok(ApiResponse.Success(device));
            }
            catch (Exception ex)
            {
                await _loggingService.LogErrorAsync($"Failed to get device {id}", ex);
                return StatusCode(500, ApiResponse.Error("Failed to get device"));
            }
        }

        [HttpPost]
        public async Task<IActionResult> CreateDevice([FromBody] CNCDevice device)
        {
            try
            {
                var createdDevice = await _collectionService.CreateDeviceAsync(device);
                return Ok(ApiResponse.Success(createdDevice, "Device created successfully"));
            }
            catch (Exception ex)
            {
                await _loggingService.LogErrorAsync("Failed to create device", ex);
                return StatusCode(500, ApiResponse.Error("Failed to create device"));
            }
        }

        [HttpPut("{id}")]
        public async Task<IActionResult> UpdateDevice(int id, [FromBody] CNCDevice device)
        {
            try
            {
                device.DeviceId = id;
                var updatedDevice = await _collectionService.UpdateDeviceAsync(device);
                if (updatedDevice == null)
                {
                    return NotFound(ApiResponse.NotFound("Device not found"));
                }
                return Ok(ApiResponse.Success(updatedDevice, "Device updated successfully"));
            }
            catch (Exception ex)
            {
                await _loggingService.LogErrorAsync($"Failed to update device {id}", ex);
                return StatusCode(500, ApiResponse.Error("Failed to update device"));
            }
        }

        [HttpDelete("{id}")]
        public async Task<IActionResult> DeleteDevice(int id)
        {
            try
            {
                var result = await _collectionService.DeleteDeviceAsync(id);
                if (!result)
                {
                    return NotFound(ApiResponse.NotFound("Device not found"));
                }
                return Ok(ApiResponse.Success(null, "Device deleted successfully"));
            }
            catch (Exception ex)
            {
                await _loggingService.LogErrorAsync($"Failed to delete device {id}", ex);
                return StatusCode(500, ApiResponse.Error("Failed to delete device"));
            }
        }

        [HttpPost("{id}/collect")]
        public async Task<IActionResult> CollectDeviceData(int id)
        {
            try
            {
                await _collectionService.CollectDeviceAsync(id);
                return Ok(ApiResponse.Success(null, "Data collection started"));
            }
            catch (Exception ex)
            {
                await _loggingService.LogErrorAsync($"Failed to collect data for device {id}", ex);
                return StatusCode(500, ApiResponse.Error("Failed to collect data"));
            }
        }

        [HttpPost("collect-all")]
        public async Task<IActionResult> CollectAllDevices()
        {
            try
            {
                await _collectionService.CollectAllDevicesAsync();
                return Ok(ApiResponse.Success(null, "All devices data collection started"));
            }
            catch (Exception ex)
            {
                await _loggingService.LogErrorAsync("Failed to collect data for all devices", ex);
                return StatusCode(500, ApiResponse.Error("Failed to collect data"));
            }
        }

        [HttpGet("{id}/status")]
        public async Task<IActionResult> GetDeviceStatus(int id)
        {
            try
            {
                var status = await _collectionService.GetDeviceStatusAsync(id);
                return Ok(ApiResponse.Success(status));
            }
            catch (Exception ex)
            {
                await _loggingService.LogErrorAsync($"Failed to get device status for {id}", ex);
                return StatusCode(500, ApiResponse.Error("Failed to get device status"));
            }
        }

        [HttpGet("{id}/production")]
        public async Task<IActionResult> GetDeviceProduction(int id, [FromQuery] DateTime date)
        {
            try
            {
                if (date == default)
                    date = DateTime.Today;

                var production = await _productionService.GetTodayProductionAsync(id);
                return Ok(ApiResponse.Success(production));
            }
            catch (Exception ex)
            {
                await _loggingService.LogErrorAsync($"Failed to get production for device {id}", ex);
                return StatusCode(500, ApiResponse.Error("Failed to get production data"));
            }
        }

        [HttpGet("{id}/alarms")]
        public async Task<IActionResult> GetDeviceAlarms(int id, [FromQuery] int days = 7)
        {
            try
            {
                var alarms = await _alarmService.GetDeviceAlarmsAsync(id, days);
                return Ok(ApiResponse.Success(alarms));
            }
            catch (Exception ex)
            {
                await _loggingService.LogErrorAsync($"Failed to get alarms for device {id}", ex);
                return StatusCode(500, ApiResponse.Error("Failed to get alarms"));
            }
        }

        [HttpGet("{id}/health")]
        public async Task<IActionResult> GetDeviceHealth(int id)
        {
            try
            {
                var health = await _collectionService.GetDeviceHealthAsync(id);
                return Ok(ApiResponse.Success(health));
            }
            catch (Exception ex)
            {
                await _loggingService.LogErrorAsync($"Failed to get health for device {id}", ex);
                return StatusCode(500, ApiResponse.Error("Failed to get device health"));
            }
        }
    }
}