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

namespace Haoliang.Api.Controllers
{
    [ApiController]
    [Route("api/v1/[controller]")]
    public class TemplateController : ControllerBase
    {
        private readonly ITemplateService _templateService;
        private readonly ITagMappingService _tagMappingService;
        private readonly ITemplateValidationService _validationService;
        private readonly ILoggingService _loggingService;

        public TemplateController(
            ITemplateService templateService,
            ITagMappingService tagMappingService,
            ITemplateValidationService validationService,
            ILoggingService loggingService)
        {
            _templateService = templateService;
            _tagMappingService = tagMappingService;
            _validationService = validationService;
            _loggingService = loggingService;
        }

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

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

        [HttpPost]
        public async Task<IActionResult> CreateTemplate([FromBody] CNCBrandTemplate template)
        {
            try
            {
                // 验证模板
                var isValid = await _templateService.ValidateTemplateAsync(template);
                if (!isValid)
                {
                    return BadRequest(ApiResponse.Error("Template validation failed"));
                }

                var createdTemplate = await _templateService.CreateTemplateAsync(template);
                return Ok(ApiResponse.Success(createdTemplate, "Template created successfully"));
            }
            catch (Exception ex)
            {
                await _loggingService.LogErrorAsync("Failed to create template", ex);
                return StatusCode(500, ApiResponse.Error("Failed to create template"));
            }
        }

        [HttpPut("{id}")]
        public async Task<IActionResult> UpdateTemplate(int id, [FromBody] CNCBrandTemplate template)
        {
            try
            {
                template.TemplateId = id;
                
                // 验证模板
                var isValid = await _templateService.ValidateTemplateAsync(template);
                if (!isValid)
                {
                    return BadRequest(ApiResponse.Error("Template validation failed"));
                }

                var updatedTemplate = await _templateService.UpdateTemplateAsync(id, template);
                if (updatedTemplate == null)
                {
                    return NotFound(ApiResponse.NotFound("Template not found"));
                }
                return Ok(ApiResponse.Success(updatedTemplate, "Template updated successfully"));
            }
            catch (Exception ex)
            {
                await _loggingService.LogErrorAsync($"Failed to update template {id}", ex);
                return StatusCode(500, ApiResponse.Error("Failed to update template"));
            }
        }

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

        [HttpPost("{id}/enable")]
        public async Task<IActionResult> EnableTemplate(int id)
        {
            try
            {
                var result = await _templateService.EnableTemplateAsync(id);
                if (!result)
                {
                    return NotFound(ApiResponse.NotFound("Template not found"));
                }
                return Ok(ApiResponse.Success(null, "Template enabled successfully"));
            }
            catch (Exception ex)
            {
                await _loggingService.LogErrorAsync($"Failed to enable template {id}", ex);
                return StatusCode(500, ApiResponse.Error("Failed to enable template"));
            }
        }

        [HttpPost("{id}/disable")]
        public async Task<IActionResult> DisableTemplate(int id)
        {
            try
            {
                var result = await _templateService.DisableTemplateAsync(id);
                if (!result)
                {
                    return NotFound(ApiResponse.NotFound("Template not found"));
                }
                return Ok(ApiResponse.Success(null, "Template disabled successfully"));
            }
            catch (Exception ex)
            {
                await _loggingService.LogErrorAsync($"Failed to disable template {id}", ex);
                return StatusCode(500, ApiResponse.Error("Failed to disable template"));
            }
        }

        [HttpPost("{id}/clone")]
        public async Task<IActionResult> CloneTemplate(int id, [FromBody] CloneTemplateRequest request)
        {
            try
            {
                var clonedTemplate = await _templateService.CloneTemplateAsync(id, request.NewName);
                return Ok(ApiResponse.Success(clonedTemplate, "Template cloned successfully"));
            }
            catch (Exception ex)
            {
                await _loggingService.LogErrorAsync($"Failed to clone template {id}", ex);
                return StatusCode(500, ApiResponse.Error("Failed to clone template"));
            }
        }

        [HttpPost("{id}/test")]
        public async Task<IActionResult> TestTemplate(int id)
        {
            try
            {
                await _templateService.TestTemplateAsync(id);
                return Ok(ApiResponse.Success(null, "Template test completed"));
            }
            catch (Exception ex)
            {
                await _loggingService.LogErrorAsync($"Failed to test template {id}", ex);
                return StatusCode(500, ApiResponse.Error("Failed to test template"));
            }
        }

        [HttpGet("brand/{brandName}")]
        public async Task<IActionResult> GetTemplatesByBrand(string brandName)
        {
            try
            {
                var templates = await _templateService.GetTemplatesByBrandAsync(brandName);
                return Ok(ApiResponse.Success(templates));
            }
            catch (Exception ex)
            {
                await _loggingService.LogErrorAsync($"Failed to get templates for brand {brandName}", ex);
                return StatusCode(500, ApiResponse.Error("Failed to get templates by brand"));
            }
        }

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

        [HttpGet("validate")]
        public async Task<IActionResult> ValidateTemplate([FromBody] CNCBrandTemplate template)
        {
            try
            {
                var isValid = await _templateService.ValidateTemplateAsync(template);
                
                if (!isValid)
                {
                    var errors = await _validationService.ValidateTemplateForDeviceAsync(template.TemplateId, 1);
                    return BadRequest(ApiResponse.Error("Template validation failed", errors));
                }

                return Ok(ApiResponse.Success(true, "Template validation passed"));
            }
            catch (Exception ex)
            {
                await _loggingService.LogErrorAsync("Failed to validate template", ex);
                return StatusCode(500, ApiResponse.Error("Failed to validate template"));
            }
        }

        [HttpPost("migrate")]
        public async Task<IActionResult> MigrateTemplate([FromBody] TemplateMigrationRequest request)
        {
            try
            {
                var migrationReport = await _validationService.GenerateMigrationReportAsync(request.Template, request.TargetBrand);
                
                if (!migrationReport.CanMigrate)
                {
                    return BadRequest(ApiResponse.Error("Migration not possible", migrationReport.Issues));
                }

                return Ok(ApiResponse.Success(migrationReport, "Migration report generated"));
            }
            catch (Exception ex)
            {
                await _loggingService.LogErrorAsync("Failed to generate migration report", ex);
                return StatusCode(500, ApiResponse.Error("Failed to generate migration report"));
            }
        }

        [HttpGet("mappings/{templateId}")]
        public async Task<IActionResult> GetTagMappings(int templateId)
        {
            try
            {
                var mappings = await _tagMappingService.GetMappingsByTemplateAsync(templateId);
                return Ok(ApiResponse.Success(mappings));
            }
            catch (Exception ex)
            {
                await _loggingService.LogErrorAsync($"Failed to get tag mappings for template {templateId}", ex);
                return StatusCode(500, ApiResponse.Error("Failed to get tag mappings"));
            }
        }

        [HttpPost("mappings")]
        public async Task<IActionResult> CreateTagMapping([FromBody] TagMapping mapping)
        {
            try
            {
                var createdMapping = await _tagMappingService.CreateTagMappingAsync(mapping);
                return Ok(ApiResponse.Success(createdMapping, "Tag mapping created successfully"));
            }
            catch (Exception ex)
            {
                await _loggingService.LogErrorAsync("Failed to create tag mapping", ex);
                return StatusCode(500, ApiResponse.Error("Failed to create tag mapping"));
            }
        }

        [HttpPost("sample-mapping")]
        public async Task<IActionResult> TestTagMapping([FromBody] TestTagMappingRequest request)
        {
            try
            {
                var mappedTags = await _tagMappingService.MapDeviceTagsAsync(request.DeviceTags, request.TemplateId);
                return Ok(ApiResponse.Success(mappedTags, "Tag mapping test completed"));
            }
            catch (Exception ex)
            {
                await _loggingService.LogErrorAsync("Failed to test tag mapping", ex);
                return StatusCode(500, ApiResponse.Error("Failed to test tag mapping"));
            }
        }
    }

    public class CloneTemplateRequest
    {
        public string NewName { get; set; }
    }

    public class TemplateMigrationRequest
    {
        public CNCBrandTemplate Template { get; set; }
        public string TargetBrand { get; set; }
    }

    public class TestTagMappingRequest
    {
        public IEnumerable<TagData> DeviceTags { get; set; }
        public int TemplateId { get; set; }
    }
}