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

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

        public ProductionController(
            IProductionService productionService,
            IAlarmService alarmService,
            ILoggingService loggingService,
            ISystemConfigService configService)
        {
            _productionService = productionService;
            _alarmService = alarmService;
            _loggingService = loggingService;
            _configService = configService;
        }

        [HttpGet]
        public async Task<IActionResult> GetAllProduction([FromQuery] DateTime date)
        {
            try
            {
                if (date == default)
                    date = DateTime.Today;

                var summary = await _productionService.GetProductionSummaryAsync(date);
                return Ok(ApiResponse.Success(summary));
            }
            catch (Exception ex)
            {
                await _loggingService.LogErrorAsync("Failed to get production summary", ex);
                return StatusCode(500, ApiResponse.Error("Failed to get production summary"));
            }
        }

        [HttpGet("statistics")]
        public async Task<IActionResult> GetProductionStatistics([FromQuery] DateTime date)
        {
            try
            {
                if (date == default)
                    date = DateTime.Today;

                var statistics = await _productionService.GetProductionStatisticsAsync(date);
                return Ok(ApiResponse.Success(statistics));
            }
            catch (Exception ex)
            {
                await _loggingService.LogErrorAsync("Failed to get production statistics", ex);
                return StatusCode(500, ApiResponse.Error("Failed to get production statistics"));
            }
        }

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

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

        [HttpGet("device/{deviceId}/statistics")]
        public async Task<IActionResult> GetDeviceProductionStatistics(
            int deviceId,
            [FromQuery] DateTime date)
        {
            try
            {
                if (date == default)
                    date = DateTime.Today;

                var statistics = await _productionService.GetProductionStatisticsAsync(deviceId, date);
                return Ok(ApiResponse.Success(statistics));
            }
            catch (Exception ex)
            {
                await _loggingService.LogErrorAsync($"Failed to get statistics for device {deviceId}", ex);
                return StatusCode(500, ApiResponse.Error("Failed to get device statistics"));
            }
        }

        [HttpGet("device/{deviceId}/quality-rate")]
        public async Task<IActionResult> GetDeviceQualityRate(
            int deviceId,
            [FromQuery] DateTime date)
        {
            try
            {
                if (date == default)
                    date = DateTime.Today;

                var qualityRate = await _productionService.GetQualityRateAsync(deviceId, date);
                return Ok(ApiResponse.Success(qualityRate));
            }
            catch (Exception ex)
            {
                await _loggingService.LogErrorAsync($"Failed to get quality rate for device {deviceId}", ex);
                return StatusCode(500, ApiResponse.Error("Failed to get quality rate"));
            }
        }

        [HttpPost("calculate")]
        public async Task<IActionResult> CalculateProduction()
        {
            try
            {
                await _productionService.CalculateAllProductionAsync();
                return Ok(ApiResponse.Success(null, "Production calculation completed"));
            }
            catch (Exception ex)
            {
                await _loggingService.LogErrorAsync("Failed to calculate production", ex);
                return StatusCode(500, ApiResponse.Error("Failed to calculate production"));
            }
        }

        [HttpPost("device/{deviceId}/calculate")]
        public async Task<IActionResult> CalculateDeviceProduction(int deviceId)
        {
            try
            {
                await _productionService.CalculateProductionAsync(deviceId);
                return Ok(ApiResponse.Success(null, "Device production calculation completed"));
            }
            catch (Exception ex)
            {
                await _loggingService.LogErrorAsync($"Failed to calculate production for device {deviceId}", ex);
                return StatusCode(500, ApiResponse.Error("Failed to calculate device production"));
            }
        }

        [HttpGet("programs")]
        public async Task<IActionResult> GetProductionPrograms([FromQuery] DateTime date)
        {
            try
            {
                if (date == default)
                    date = DateTime.Today;

                var programs = await _productionService.GetProductionProgramsAsync(date);
                return Ok(ApiResponse.Success(programs));
            }
            catch (Exception ex)
            {
                await _loggingService.LogErrorAsync("Failed to get production programs", ex);
                return StatusCode(500, ApiResponse.Error("Failed to get production programs"));
            }
        }

        [HttpGet("programs/{programName}")]
        public async Task<IActionResult> GetProgramProduction(
            string programName,
            [FromQuery] DateTime date)
        {
            try
            {
                if (date == default)
                    date = DateTime.Today;

                var programData = await _productionService.GetProgramProductionAsync(programName, date);
                return Ok(ApiResponse.Success(programData));
            }
            catch (Exception ex)
            {
                await _loggingService.LogErrorAsync($"Failed to get program production for {programName}", ex);
                return StatusCode(500, ApiResponse.Error("Failed to get program production"));
            }
        }

        [HttpGet("export")]
        public async Task<IActionResult> ExportProductionData(
            [FromQuery] DateTime startDate,
            [FromQuery] DateTime endDate)
        {
            try
            {
                if (startDate == default)
                    startDate = DateTime.Today.AddDays(-7);
                if (endDate == default)
                    endDate = DateTime.Today;

                var exportData = await _productionService.ExportProductionDataAsync(startDate, endDate);
                
                var fileName = $"production_{startDate:yyyy-MM-dd}_{endDate:yyyy-MM-dd}.csv";
                return File(exportData, "text/csv", fileName);
            }
            catch (Exception ex)
            {
                await _loggingService.LogErrorAsync("Failed to export production data", ex);
                return StatusCode(500, ApiResponse.Error("Failed to export production data"));
            }
        }

        [HttpPost("archive")]
        public async Task<IActionResult> ArchiveProductionData([FromQuery] int daysToKeep = 90)
        {
            try
            {
                await _productionService.ArchiveProductionDataAsync(daysToKeep);
                return Ok(ApiResponse.Success(null, "Production data archived successfully"));
            }
            catch (Exception ex)
            {
                await _loggingService.LogErrorAsync("Failed to archive production data", ex);
                return StatusCode(500, ApiResponse.Error("Failed to archive production data"));
            }
        }
    }
}