using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using System.Text.Json;
using Haoliang.Models.Template;
using Haoliang.Models.Device;
using Haoliang.Models.DataCollection;
using Haoliang.Data.Repositories;

namespace Haoliang.Core.Services
{
    public interface ITemplateService
    {
        Task<CNCBrandTemplate> CreateTemplateAsync(CNCBrandTemplate template);
        Task<CNCBrandTemplate> UpdateTemplateAsync(int templateId, CNCBrandTemplate template);
        Task<bool> DeleteTemplateAsync(int templateId);
        Task<CNCBrandTemplate> GetTemplateByIdAsync(int templateId);
        Task<IEnumerable<CNCBrandTemplate>> GetAllTemplatesAsync();
        Task<IEnumerable<CNCBrandTemplate>> GetTemplatesByBrandAsync(string brandName);
        Task<IEnumerable<CNCBrandTemplate>> GetActiveTemplatesAsync();
        Task<bool> ValidateTemplateAsync(CNCBrandTemplate template);
        Task TestTemplateAsync(int templateId);
        Task<CNCBrandTemplate> CloneTemplateAsync(int templateId, string newName);
        Task<bool> EnableTemplateAsync(int templateId);
        Task<bool> DisableTemplateAsync(int templateId);
    }

    public interface ITagMappingService
    {
        Task<TagMapping> CreateTagMappingAsync(TagMapping mapping);
        Task<TagMapping> UpdateTagMappingAsync(int mappingId, TagMapping mapping);
        Task<bool> DeleteTagMappingAsync(int mappingId);
        Task<TagMapping> GetTagMappingByIdAsync(int mappingId);
        Task<IEnumerable<TagMapping>> GetAllTagMappingsAsync();
        Task<IEnumerable<TagMapping>> GetMappingsByTemplateAsync(int templateId);
        Task<TagMapping> MapDeviceTagAsync(TagData deviceTag, int templateId);
        Task<Dictionary<string, TagData>> MapDeviceTagsAsync(IEnumerable<TagData> deviceTags, int templateId);
        Task ValidateTagMappingAsync(TagMapping mapping);
    }

    public interface ITemplateValidationService
    {
        Task<bool> ValidateTemplateStructureAsync(CNCBrandTemplate template);
        Task<bool> ValidateTagMappingsAsync(CNCBrandTemplate template);
        Task<bool> ValidateDataParsingRulesAsync(CNCBrandTemplate template);
        Task<IEnumerable<ValidationError>> ValidateTemplateForDeviceAsync(int templateId, int deviceId);
        Task<bool> TestTemplateDataParsingAsync(CNCBrandTemplate template, string sampleData);
        Task<IEnumerable<string>> GetMissingRequiredTagsAsync(CNCBrandTemplate template);
    }

    public interface ITemplateMigrationService
    {
        Task<CNCBrandTemplate> MigrateTemplateAsync(CNCBrandTemplate oldTemplate, string targetBrand);
        Task<bool> ValidateMigrationCompatibilityAsync(CNCBrandTemplate sourceTemplate, string targetBrand);
        Task<MigrationReport> GenerateMigrationReportAsync(CNCBrandTemplate template, string targetBrand);
        Task<IEnumerable<MigrationIssue>> DetectMigrationIssuesAsync(CNCBrandTemplate template, string targetBrand);
    }

    public class TemplateManager : ITemplateService
    {
        private readonly ITemplateRepository _templateRepository;
        private readonly ITagMappingService _tagMappingService;
        private readonly ITemplateValidationService _validationService;
        private readonly ITemplateMigrationService _migrationService;

        public TemplateManager(
            ITemplateRepository templateRepository,
            ITagMappingService tagMappingService,
            ITemplateValidationService validationService,
            ITemplateMigrationService migrationService)
        {
            _templateRepository = templateRepository;
            _tagMappingService = tagMappingService;
            _validationService = validationService;
            _migrationService = migrationService;
        }

        public async Task<CNCBrandTemplate> CreateTemplateAsync(CNCBrandTemplate template)
        {
            // 验证模板
            var validationErrors = await _validationService.ValidateTemplateStructureAsync(template);
            if (validationErrors.Count > 0)
            {
                throw new InvalidOperationException($"Template validation failed: {string.Join(", ", validationErrors)}");
            }

            // 设置初始状态
            template.IsEnabled = true;
            template.CreateTime = DateTime.Now;
            template.UpdateTime = DateTime.Now;

            var createdTemplate = await _templateRepository.AddAsync(template);
            
            // 验证标签映射
            await _validationService.ValidateTagMappingsAsync(createdTemplate);
            
            return createdTemplate;
        }

        public async Task<CNCBrandTemplate> UpdateTemplateAsync(int templateId, CNCBrandTemplate template)
        {
            var existingTemplate = await _templateRepository.GetByIdAsync(templateId);
            if (existingTemplate == null)
            {
                throw new KeyNotFoundException($"Template with ID {templateId} not found");
            }

            // 验证更新后的模板
            var validationErrors = await _validationService.ValidateTemplateStructureAsync(template);
            if (validationErrors.Count > 0)
            {
                throw new InvalidOperationException($"Template validation failed: {string.Join(", ", validationErrors)}");
            }

            template.TemplateId = templateId;
            template.UpdateTime = DateTime.Now;

            var updatedTemplate = await _templateRepository.UpdateAsync(template);
            
            // 如果标签有变化，重新验证
            if (HasTagMappingsChanged(existingTemplate, template))
            {
                await _validationService.ValidateTagMappingsAsync(updatedTemplate);
            }

            return updatedTemplate;
        }

        public async Task<bool> DeleteTemplateAsync(int templateId)
        {
            // 检查模板是否被使用
            var isTemplateInUse = await _templateRepository.IsTemplateInUseAsync(templateId);
            if (isTemplateInUse)
            {
                throw new InvalidOperationException("Cannot delete template that is currently in use by devices");
            }

            return await _templateRepository.DeleteAsync(templateId);
        }

        public async Task<CNCBrandTemplate> GetTemplateByIdAsync(int templateId)
        {
            return await _templateRepository.GetByIdAsync(templateId);
        }

        public async Task<IEnumerable<CNCBrandTemplate>> GetAllTemplatesAsync()
        {
            return await _templateRepository.GetAllAsync();
        }

        public async Task<IEnumerable<CNCBrandTemplate>> GetTemplatesByBrandAsync(string brandName)
        {
            return await _templateRepository.GetByBrandAsync(brandName);
        }

        public async Task<IEnumerable<CNCBrandTemplate>> GetActiveTemplatesAsync()
        {
            return await _templateRepository.GetActiveTemplatesAsync();
        }

        public async Task<bool> ValidateTemplateAsync(CNCBrandTemplate template)
        {
            return await _validationService.ValidateTemplateStructureAsync(template);
        }

        public async Task TestTemplateAsync(int templateId)
        {
            var template = await _templateRepository.GetByIdAsync(templateId);
            if (template == null)
            {
                throw new KeyNotFoundException($"Template with ID {templateId} not found");
            }

            // 使用模板进行数据解析测试
            await _validationService.TestTemplateDataParsingAsync(template, GetSampleData(template));
        }

        public async Task<CNCBrandTemplate> CloneTemplateAsync(int templateId, string newName)
        {
            var originalTemplate = await _templateRepository.GetByIdAsync(templateId);
            if (originalTemplate == null)
            {
                throw new KeyNotFoundException($"Template with ID {templateId} not found");
            }

            var clonedTemplate = new CNCBrandTemplate
            {
                TemplateName = newName,
                BrandName = originalTemplate.BrandName,
                Description = $"Cloned from {originalTemplate.TemplateName}",
                IsEnabled = false, // 新克隆的模板默认禁用
                Version = originalTemplate.Version,
                TemplateJson = originalTemplate.TemplateJson,
                CreateTime = DateTime.Now,
                UpdateTime = DateTime.Now
            };

            return await CreateTemplateAsync(clonedTemplate);
        }

        public async Task<bool> EnableTemplateAsync(int templateId)
        {
            var template = await _templateRepository.GetByIdAsync(templateId);
            if (template == null)
            {
                return false;
            }

            template.IsEnabled = true;
            template.UpdateTime = DateTime.Now;

            return await _templateRepository.UpdateAsync(template) != null;
        }

        public async Task<bool> DisableTemplateAsync(int templateId)
        {
            var template = await _templateRepository.GetByIdAsync(templateId);
            if (template == null)
            {
                return false;
            }

            // 检查是否还有设备在使用此模板
            var isTemplateInUse = await _templateRepository.IsTemplateInUseAsync(templateId);
            if (isTemplateInUse)
            {
                throw new InvalidOperationException("Cannot disable template that is currently in use by devices");
            }

            template.IsEnabled = false;
            template.UpdateTime = DateTime.Now;

            return await _templateRepository.UpdateAsync(template) != null;
        }

        private bool HasTagMappingsChanged(CNCBrandTemplate oldTemplate, CNCBrandTemplate newTemplate)
        {
            // 简单比较JSON内容是否变化
            return oldTemplate.TemplateJson != newTemplate.TemplateJson;
        }

        private string GetSampleData(CNCBrandTemplate template)
        {
            // 返回模拟的设备数据用于测试
            return @"{
                ""device"": ""FANUC_01"",
                ""desc"": ""CNC Machine"",
                ""tags"": [
                    {
                        ""id"": ""_io_status"",
                        ""desc"": ""I/O Status"",
                        ""quality"": 0,
                        ""value"": 1,
                        ""time"": ""2024-01-01T10:00:00""
                    },
                    {
                        ""id"": ""Tag5"",
                        ""desc"": ""NC Program"",
                        ""quality"": 0,
                        ""value"": ""O1234"",
                        ""time"": ""2024-01-01T10:00:00""
                    },
                    {
                        ""id"": ""Tag8"",
                        ""desc"": ""Cumulative Count"",
                        ""quality"": 0,
                        ""value"": 12345.00000,
                        ""time"": ""2024-01-01T10:00:00""
                    }
                ]
            }";
        }
    }

    public class TagMappingService : ITagMappingService
    {
        private readonly ITagMappingRepository _tagMappingRepository;
        private readonly ITemplateRepository _templateRepository;
        private readonly ILoggerService _logger;

        public TagMappingService(
            ITagMappingRepository tagMappingRepository,
            ITemplateRepository templateRepository,
            ILoggerService logger)
        {
            _tagMappingRepository = tagMappingRepository;
            _templateRepository = templateRepository;
            _logger = logger;
        }

        public async Task<TagMapping> CreateTagMappingAsync(TagMapping mapping)
        {
            // 验证映射
            await ValidateTagMappingAsync(mapping);

            mapping.CreateTime = DateTime.Now;
            mapping.UpdateTime = DateTime.Now;

            return await _tagMappingRepository.AddAsync(mapping);
        }

        public async Task<TagMapping> UpdateTagMappingAsync(int mappingId, TagMapping mapping)
        {
            var existingMapping = await _tagMappingRepository.GetByIdAsync(mappingId);
            if (existingMapping == null)
            {
                throw new KeyNotFoundException($"Tag mapping with ID {mappingId} not found");
            }

            mapping.MappingId = mappingId;
            mapping.UpdateTime = DateTime.Now;

            // 验证更新后的映射
            await ValidateTagMappingAsync(mapping);

            return await _tagMappingRepository.UpdateAsync(mapping);
        }

        public async Task<bool> DeleteTagMappingAsync(int mappingId)
        {
            return await _tagMappingRepository.DeleteAsync(mappingId);
        }

        public async Task<TagMapping> GetTagMappingByIdAsync(int mappingId)
        {
            return await _tagMappingRepository.GetByIdAsync(mappingId);
        }

        public async Task<IEnumerable<TagMapping>> GetAllTagMappingsAsync()
        {
            return await _tagMappingRepository.GetAllAsync();
        }

        public async Task<IEnumerable<TagMapping>> GetMappingsByTemplateAsync(int templateId)
        {
            return await _tagMappingRepository.GetByTemplateIdAsync(templateId);
        }

        public async Task<TagMapping> MapDeviceTagAsync(TagData deviceTag, int templateId)
        {
            var template = await _templateRepository.GetByIdAsync(templateId);
            if (template == null)
            {
                throw new KeyNotFoundException($"Template with ID {templateId} not found");
            }

            // 解析模板JSON配置
            var templateConfig = ParseTemplateConfiguration(template.TemplateJson);
            
            // 查找匹配的标签映射
            var mapping = templateConfig.TagMappings.FirstOrDefault(m => 
                m.DeviceTagId == deviceTag.Id || m.DeviceTagPattern?.Equals(deviceTag.Id, StringComparison.OrdinalIgnoreCase) == true);

            if (mapping != null)
            {
                var mappedTag = new TagMapping
                {
                    TemplateId = templateId,
                    DeviceTagId = deviceTag.Id,
                    StandardTagId = mapping.StandardTagId,
                    DataType = mapping.DataType,
                    ConversionRule = mapping.ConversionRule,
                    IsRequired = mapping.IsRequired,
                    CreateTime = DateTime.Now,
                    UpdateTime = DateTime.Now
                };

                return await CreateTagMappingAsync(mappedTag);
            }

            return null;
        }

        public async Task<Dictionary<string, TagData>> MapDeviceTagsAsync(IEnumerable<TagData> deviceTags, int templateId)
        {
            var mappedTags = new Dictionary<string, TagData>();
            var template = await _templateRepository.GetByIdAsync(templateId);
            if (template == null)
            {
                throw new KeyNotFoundException($"Template with ID {templateId} not found");
            }

            var templateConfig = ParseTemplateConfiguration(template.TemplateJson);

            foreach (var deviceTag in deviceTags)
            {
                var mapping = templateConfig.TagMappings.FirstOrDefault(m => 
                    m.DeviceTagId == deviceTag.Id || m.DeviceTagPattern?.Equals(deviceTag.Id, StringComparison.OrdinalIgnoreCase) == true);

                if (mapping != null)
                {
                    var mappedTag = await MapDeviceTagAsync(deviceTag, templateId);
                    if (mappedTag != null)
                    {
                        mappedTags[mappedTag.StandardTagId] = deviceTag;
                    }
                }
            }

            return mappedTags;
        }

        public async Task ValidateTagMappingAsync(TagMapping mapping)
        {
            if (mapping == null)
            {
                throw new ArgumentNullException(nameof(mapping));
            }

            // 验证模板存在
            var template = await _templateRepository.GetByIdAsync(mapping.TemplateId);
            if (template == null)
            {
                throw new InvalidOperationException($"Template with ID {mapping.TemplateId} not found");
            }

            // 验证标准标签ID
            if (string.IsNullOrEmpty(mapping.StandardTagId))
            {
                throw new InvalidOperationException("Standard tag ID is required");
            }

            // 验证数据类型
            if (!IsValidDataType(mapping.DataType))
            {
                throw new InvalidOperationException($"Invalid data type: {mapping.DataType}");
            }

            // 验证设备标签ID
            if (string.IsNullOrEmpty(mapping.DeviceTagId))
            {
                throw new InvalidOperationException("Device tag ID is required");
            }
        }

        private TemplateConfiguration ParseTemplateConfiguration(string templateJson)
        {
            try
            {
                return JsonSerializer.Deserialize<TemplateConfiguration>(templateJson) ?? new TemplateConfiguration();
            }
            catch (Exception ex)
            {
                throw new InvalidOperationException($"Failed to parse template configuration: {ex.Message}");
            }
        }

        private bool IsValidDataType(string dataType)
        {
            return !string.IsNullOrEmpty(dataType) && 
                   new[] { "string", "int", "decimal", "bool", "datetime" }.Contains(dataType.ToLower());
        }
    }

    public class TemplateValidationService : ITemplateValidationService
    {
        private readonly ITemplateRepository _templateRepository;
        private readonly ITagMappingRepository _tagMappingRepository;
        private readonly ILoggerService _logger;

        public TemplateValidationService(
            ITemplateRepository templateRepository,
            ITagMappingRepository tagMappingRepository,
            ILoggerService logger)
        {
            _templateRepository = templateRepository;
            _tagMappingRepository = tagMappingRepository;
            _logger = logger;
        }

        public async Task<bool> ValidateTemplateStructureAsync(CNCBrandTemplate template)
        {
            var validationErrors = await GetTemplateStructureErrorsAsync(template);
            return validationErrors.Count == 0;
        }

        public async Task<bool> ValidateTagMappingsAsync(CNCBrandTemplate template)
        {
            var validationErrors = new List<ValidationError>();

            try
            {
                var templateConfig = ParseTemplateConfiguration(template.TemplateJson);

                // 验证必需的标签映射
                var requiredTags = templateConfig.TagMappings.Where(m => m.IsRequired).ToList();
                var existingMappings = await _tagMappingRepository.GetByTemplateIdAsync(template.TemplateId);

                foreach (var requiredTag in requiredTags)
                {
                    if (!existingMappings.Any(m => m.StandardTagId == requiredTag.StandardTagId))
                    {
                        validationErrors.Add(new ValidationError
                        {
                            Field = "TagMappings",
                            Message = $"Required mapping for tag '{requiredTag.StandardTagId}' is missing"
                        });
                    }
                }

                // 验证数据类型一致性
                foreach (var mapping in existingMappings)
                {
                    if (!IsValidDataType(mapping.DataType))
                    {
                        validationErrors.Add(new ValidationError
                        {
                            Field = $"TagMappings[{mapping.DeviceTagId}]",
                            Message = $"Invalid data type: {mapping.DataType}"
                        });
                    }
                }
            }
            catch (Exception ex)
            {
                validationErrors.Add(new ValidationError
                {
                    Field = "TemplateJson",
                    Message = $"Failed to parse template configuration: {ex.Message}"
                });
            }

            return validationErrors.Count == 0;
        }

        public async Task<bool> ValidateDataParsingRulesAsync(CNCBrandTemplate template)
        {
            var validationErrors = new List<ValidationError>();

            try
            {
                var templateConfig = ParseTemplateConfiguration(template.TemplateJson);

                // 验证数据解析规则
                foreach (var mapping in templateConfig.TagMappings)
                {
                    if (!string.IsNullOrEmpty(mapping.ConversionRule))
                    {
                        if (!ValidateConversionRule(mapping.ConversionRule))
                        {
                            validationErrors.Add(new ValidationError
                            {
                                Field = $"TagMappings[{mapping.DeviceTagId}].ConversionRule",
                                Message = $"Invalid conversion rule: {mapping.ConversionRule}"
                            });
                        }
                    }
                }
            }
            catch (Exception ex)
            {
                validationErrors.Add(new ValidationError
                {
                    Field = "TemplateJson",
                    Message = $"Failed to validate data parsing rules: {ex.Message}"
                });
            }

            return validationErrors.Count == 0;
        }

        public async Task<IEnumerable<ValidationError>> ValidateTemplateForDeviceAsync(int templateId, int deviceId)
        {
            var validationErrors = new List<ValidationError>();

            try
            {
                var template = await _templateRepository.GetByIdAsync(templateId);
                if (template == null)
                {
                    validationErrors.Add(new ValidationError
                    {
                        Field = "TemplateId",
                        Message = $"Template with ID {templateId} not found"
                    });
                    return validationErrors;
                }

                // 获取设备数据
                var deviceData = await GetSampleDeviceDataAsync(deviceId);
                if (deviceData == null)
                {
                    validationErrors.Add(new ValidationError
                    {
                        Field = "DeviceData",
                        Message = "No sample device data available for validation"
                    });
                    return validationErrors;
                }

                // 验证模板结构
                var structureErrors = await GetTemplateStructureErrorsAsync(template);
                validationErrors.AddRange(structureErrors);

                // 验证标签映射
                var tagMappingErrors = await ValidateTagMappingsWithDeviceData(template, deviceData);
                validationErrors.AddRange(tagMappingErrors);

                // 验证数据解析
                var parsingErrors = await ValidateDataParsingWithDeviceData(template, deviceData);
                validationErrors.AddRange(parsingErrors);
            }
            catch (Exception ex)
            {
                validationErrors.Add(new ValidationError
                {
                    Field = "Validation",
                    Message = $"Template validation failed: {ex.Message}"
                });
            }

            return validationErrors;
        }

        public async Task<bool> TestTemplateDataParsingAsync(CNCBrandTemplate template, string sampleData)
        {
            try
            {
                var templateConfig = ParseTemplateConfiguration(template.TemplateJson);
                var deviceData = JsonSerializer.Deserialize<DeviceSampleData>(sampleData);

                if (deviceData?.Tags == null)
                {
                    throw new InvalidOperationException("Invalid sample data format");
                }

                // 测试每个标签映射
                foreach (var mapping in templateConfig.TagMappings)
                {
                    var deviceTag = deviceData.Tags.FirstOrDefault(t => t.Id == mapping.DeviceTagId);
                    if (deviceTag == null)
                    {
                        if (mapping.IsRequired)
                        {
                            throw new InvalidOperationException($"Required tag '{mapping.DeviceTagId}' not found in sample data");
                        }
                        continue;
                    }

                    // 应用转换规则
                    var convertedValue = ApplyConversionRule(deviceTag.Value, mapping.ConversionRule);
                    if (convertedValue == null)
                    {
                        throw new InvalidOperationException($"Failed to convert tag '{mapping.DeviceTagId}' with rule '{mapping.ConversionRule}'");
                    }
                }

                return true;
            }
            catch (Exception ex)
            {
                await _logger.LogErrorAsync($"Template data parsing test failed: {ex.Message}");
                return false;
            }
        }

        public async Task<IEnumerable<string>> GetMissingRequiredTagsAsync(CNCBrandTemplate template)
        {
            var missingTags = new List<string>();

            try
            {
                var templateConfig = ParseTemplateConfiguration(template.TemplateJson);
                var requiredMappings = templateConfig.TagMappings.Where(m => m.IsRequired).ToList();

                foreach (var mapping in requiredMappings)
                {
                    var existingMapping = await _tagMappingRepository.GetByTemplateIdAsync(template.TemplateId)
                        .FirstOrDefault(m => m.StandardTagId == mapping.StandardTagId);
                    
                    if (existingMapping == null)
                    {
                        missingTags.Add(mapping.StandardTagId);
                    }
                }
            }
            catch (Exception ex)
            {
                await _logger.LogErrorAsync($"Failed to get missing required tags: {ex.Message}");
            }

            return missingTags;
        }

        #region Private Methods

        private async Task<List<ValidationError>> GetTemplateStructureErrorsAsync(CNCBrandTemplate template)
        {
            var errors = new List<ValidationError>();

            if (template == null)
            {
                errors.Add(new ValidationError { Field = "Template", Message = "Template is null" });
                return errors;
            }

            if (string.IsNullOrEmpty(template.TemplateName))
            {
                errors.Add(new ValidationError { Field = "TemplateName", Message = "Template name is required" });
            }

            if (string.IsNullOrEmpty(template.BrandName))
            {
                errors.Add(new ValidationError { Field = "BrandName", Message = "Brand name is required" });
            }

            if (string.IsNullOrEmpty(template.TemplateJson))
            {
                errors.Add(new ValidationError { Field = "TemplateJson", Message = "Template JSON is required" });
            }

            // 验证JSON格式
            try
            {
                var config = ParseTemplateConfiguration(template.TemplateJson);
                
                // 验证必需的标准标签
                var requiredStandardTags = new[] { "device", "production" };
                foreach (var requiredTag in requiredStandardTags)
                {
                    if (!config.TagMappings.Any(m => m.StandardTagId == requiredTag))
                    {
                        errors.Add(new ValidationError 
                        { 
                            Field = "TemplateJson", 
                            Message = $"Required standard tag '{requiredTag}' is missing" 
                        });
                    }
                }
            }
            catch (Exception ex)
            {
                errors.Add(new ValidationError { Field = "TemplateJson", Message = $"Invalid JSON format: {ex.Message}" });
            }

            return errors;
        }

        private async Task<List<ValidationError>> ValidateTagMappingsWithDeviceData(CNCBrandTemplate template, DeviceSampleData deviceData)
        {
            var errors = new List<ValidationError>();
            
            if (deviceData?.Tags == null) return errors;

            try
            {
                var templateConfig = ParseTemplateConfiguration(template.TemplateJson);

                foreach (var deviceTag in deviceData.Tags)
                {
                    var mapping = templateConfig.TagMappings.FirstOrDefault(m => 
                        m.DeviceTagId == deviceTag.Id || m.DeviceTagPattern?.Equals(deviceTag.Id, StringComparison.OrdinalIgnoreCase) == true);

                    if (mapping == null)
                    {
                        // 如果不是必需标签，则忽略
                        continue;
                    }

                    // 验证数据类型
                    var typeValid = ValidateTagDataType(deviceTag.Value, mapping.DataType);
                    if (!typeValid)
                    {
                        errors.Add(new ValidationError
                        {
                            Field = $"TagMappings[{deviceTag.Id}].DataType",
                            Message = $"Tag value '{deviceTag.Value}' cannot be converted to type '{mapping.DataType}'"
                        });
                    }
                }
            }
            catch (Exception ex)
            {
                errors.Add(new ValidationError
                {
                    Field = "TagMappings",
                    Message = $"Failed to validate tag mappings: {ex.Message}"
                });
            }

            return errors;
        }

        private async Task<List<ValidationError>> ValidateDataParsingWithDeviceData(CNCBrandTemplate template, DeviceSampleData deviceData)
        {
            var errors = new List<ValidationError>();

            try
            {
                var testResult = await TestTemplateDataParsingAsync(template, JsonSerializer.Serialize(deviceData));
                if (!testResult)
                {
                    errors.Add(new ValidationError
                    {
                        Field = "DataParsing",
                        Message = "Template failed data parsing test with sample data"
                    });
                }
            }
            catch (Exception ex)
            {
                errors.Add(new ValidationError
                {
                    Field = "DataParsing",
                    Message = $"Data parsing validation failed: {ex.Message}"
                });
            }

            return errors;
        }

        private bool ValidateTagDataType(object value, string expectedType)
        {
            if (value == null) return true;

            switch (expectedType.ToLower())
            {
                case "string":
                    return true; // Any value can be converted to string
                case "int":
                    return int.TryParse(value.ToString(), out _);
                case "decimal":
                    return decimal.TryParse(value.ToString(), out _);
                case "bool":
                    return bool.TryParse(value.ToString(), out _);
                case "datetime":
                    return DateTime.TryParse(value.ToString(), out _);
                default:
                    return false;
            }
        }

        private bool ValidateConversionRule(string conversionRule)
        {
            if (string.IsNullOrEmpty(conversionRule)) return true;

            // 简单的规则验证
            var validRules = new[] { "multiply:2", "divide:2", "add:1", "subtract:1", "format:0.00" };
            return validRules.Any(rule => conversionRule.StartsWith(rule.Split(':')[0]));
        }

        private object ApplyConversionRule(object value, string conversionRule)
        {
            if (value == null || string.IsNullOrEmpty(conversionRule)) return value;

            try
            {
                var ruleParts = conversionRule.Split(':');
                var operation = ruleParts[0];
                var parameter = ruleParts.Length > 1 ? ruleParts[1] : null;

                if (decimal.TryParse(value.ToString(), out decimal numericValue))
                {
                    switch (operation.ToLower())
                    {
                        case "multiply":
                            if (decimal.TryParse(parameter, out decimal multiplyFactor))
                                return numericValue * multiplyFactor;
                            break;
                        case "divide":
                            if (decimal.TryParse(parameter, out decimal divideFactor))
                                return divideFactor != 0 ? numericValue / divideFactor : 0;
                            break;
                        case "add":
                            if (decimal.TryParse(parameter, out decimal addValue))
                                return numericValue + addValue;
                            break;
                        case "subtract":
                            if (decimal.TryParse(parameter, out decimal subtractValue))
                                return numericValue - subtractValue;
                            break;
                        case "format":
                            if (parameter != null)
                                return numericValue.ToString(parameter);
                            break;
                    }
                }

                return value;
            }
            catch
            {
                return value; // Return original value if conversion fails
            }
        }

        private async Task<DeviceSampleData> GetSampleDeviceDataAsync(int deviceId)
        {
            // This would typically fetch actual device data for validation
            // For now, return sample data
            return new DeviceSampleData
            {
                Device = "SampleDevice",
                Desc = "Sample Device",
                Tags = new List<TagData>
                {
                    new TagData { Id = "_io_status", Desc = "I/O Status", Quality = "0", Value = 1, Time = DateTime.Now },
                    new TagData { Id = "Tag5", Desc = "NC Program", Quality = "0", Value = "O1234", Time = DateTime.Now },
                    new TagData { Id = "Tag8", Desc = "Cumulative Count", Quality = "0", Value = 12345, Time = DateTime.Now }
                }
            };
        }

        private TemplateConfiguration ParseTemplateConfiguration(string templateJson)
        {
            return JsonSerializer.Deserialize<TemplateConfiguration>(templateJson) ?? new TemplateConfiguration();
        }

        private bool IsValidDataType(string dataType)
        {
            return !string.IsNullOrEmpty(dataType) && 
                   new[] { "string", "int", "decimal", "bool", "datetime" }.Contains(dataType.ToLower());
        }

        #endregion
    }

    public class TemplateMigrationService : ITemplateMigrationService
    {
        private readonly ITemplateRepository _templateRepository;
        private readonly ITagMappingRepository _tagMappingRepository;
        private readonly ILoggerService _logger;

        public TemplateMigrationService(
            ITemplateRepository templateRepository,
            ITagMappingRepository tagMappingRepository,
            ILoggerService logger)
        {
            _templateRepository = templateRepository;
            _tagMappingRepository = tagMappingRepository;
            _logger = logger;
        }

        public async Task<CNCBrandTemplate> MigrateTemplateAsync(CNCBrandTemplate oldTemplate, string targetBrand)
        {
            // 验证迁移兼容性
            var isCompatible = await ValidateMigrationCompatibilityAsync(oldTemplate, targetBrand);
            if (!isCompatible)
            {
                throw new InvalidOperationException("Template migration is not compatible with target brand");
            }

            var migrationReport = await GenerateMigrationReportAsync(oldTemplate, targetBrand);
            var issues = await DetectMigrationIssuesAsync(oldTemplate, targetBrand);

            if (issues.Any())
            {
                throw new InvalidOperationException($"Migration detected {issues.Count} issues: {string.Join(", ", issues.Select(i => i.Description))}");
            }

            // 创建新模板
            var newTemplate = new CNCBrandTemplate
            {
                TemplateName = $"{oldTemplate.TemplateName}_Migrated_{DateTime.Now:yyyyMMdd}",
                BrandName = targetBrand,
                Description = $"Migrated from {oldTemplate.BrandName}: {oldTemplate.Description}",
                IsEnabled = false,
                Version = oldTemplate.Version,
                TemplateJson = oldTemplate.TemplateJson,
                CreateTime = DateTime.Now,
                UpdateTime = DateTime.Now
            };

            return await _templateRepository.AddAsync(newTemplate);
        }

        public async Task<bool> ValidateMigrationCompatibilityAsync(CNCBrandTemplate sourceTemplate, string targetBrand)
        {
            try
            {
                // 获取目标品牌的现有模板
                var targetTemplates = await _templateRepository.GetByBrandAsync(targetBrand);
                
                // 基本兼容性检查
                if (sourceTemplate == null)
                    return false;

                if (string.IsNullOrEmpty(targetBrand))
                    return false;

                // 检查模板结构兼容性
                var sourceConfig = ParseTemplateConfiguration(sourceTemplate.TemplateJson);
                var targetConfigs = targetTemplates.Select(t => ParseTemplateConfiguration(t.TemplateJson));

                // 检查必需标签是否兼容
                var requiredTags = sourceConfig.TagMappings.Where(m => m.IsRequired).ToList();
                foreach (var requiredTag in requiredTags)
                {
                    if (!targetConfigs.Any(c => c.TagMappings.Any(m => m.StandardTagId == requiredTag.StandardTagId)))
                    {
                        await _logger.LogWarningAsync($"Required tag '{requiredTag.StandardTagId}' not found in target brand templates");
                        return false;
                    }
                }

                return true;
            }
            catch (Exception ex)
            {
                await _logger.LogErrorAsync($"Migration compatibility check failed: {ex.Message}");
                return false;
            }
        }

        public async Task<MigrationReport> GenerateMigrationReportAsync(CNCBrandTemplate template, string targetBrand)
        {
            var report = new MigrationReport
            {
                SourceTemplate = template,
                TargetBrand = targetBrand,
                MigrationTime = DateTime.Now,
                Issues = new List<MigrationIssue>(),
                Recommendations = new List<string>()
            };

            try
            {
                var targetTemplates = await _templateRepository.GetByBrandAsync(targetBrand);
                var sourceConfig = ParseTemplateConfiguration(template.TemplateJson);

                // 分析兼容性
                report.IsCompatible = await ValidateMigrationCompatibilityAsync(template, targetBrand);

                // 识别缺失的标签
                var missingTags = await GetMissingTagsForMigration(template, targetBrand);
                report.MissingTags = missingTags;

                // 生成建议
                if (missingTags.Any())
                {
                    report.Recommendations.Add($"Create missing tag mappings for: {string.Join(", ", missingTags)}");
                }

                if (!report.IsCompatible)
                {
                    report.Recommendations.Add("Template migration is not recommended without manual review");
                }
            }
            catch (Exception ex)
            {
                report.IsCompatible = false;
                report.Issues.Add(new MigrationIssue
                {
                    Severity = MigrationIssueSeverity.Critical,
                    Description = $"Failed to generate migration report: {ex.Message}",
                    Recommendation = "Review template manually before migration"
                });
            }

            return report;
        }

        public async Task<IEnumerable<MigrationIssue>> DetectMigrationIssuesAsync(CNCBrandTemplate template, string targetBrand)
        {
            var issues = new List<MigrationIssue>();

            try
            {
                var targetTemplates = await _templateRepository.GetByBrandAsync(targetBrand);
                var sourceConfig = ParseTemplateConfiguration(template.TemplateJson);

                // 检查数据类型冲突
                var typeConflicts = await DetectDataTypeConflicts(template, targetBrand);
                issues.AddRange(typeConflicts);

                // 检查必需标签缺失
                var missingRequiredTags = await GetMissingRequiredTagsForMigration(template, targetBrand);
                foreach (var missingTag in missingRequiredTags)
                {
                    issues.Add(new MigrationIssue
                    {
                        Severity = MigrationIssueSeverity.High,
                        Description = $"Required tag '{missingTag}' is missing in target brand",
                        Recommendation = $"Create mapping for '{missingTag}' before migration"
                    });
                }

                // 检查数据转换规则兼容性
                var conversionConflicts = await DetectConversionRuleConflicts(template, targetBrand);
                issues.AddRange(conversionConflicts);

            }
            catch (Exception ex)
            {
                issues.Add(new MigrationIssue
                {
                    Severity = MigrationIssueSeverity.Critical,
                    Description = $"Migration issue detection failed: {ex.Message}",
                    Recommendation = "Manual review required"
                });
            }

            return issues;
        }

        #region Private Methods

        private async Task<List<string>> GetMissingTagsForMigration(CNCBrandTemplate template, string targetBrand)
        {
            var missingTags = new List<string>();
            var targetTemplates = await _templateRepository.GetByBrandAsync(targetBrand);
            var sourceConfig = ParseTemplateConfiguration(template.TemplateJson);

            var sourceTags = sourceConfig.TagMappings.Select(m => m.StandardTagId).ToList();
            var targetTags = targetTemplates.SelectMany(t => ParseTemplateConfiguration(t.TemplateJson).TagMappings.Select(m => m.StandardTagId));

            foreach (var sourceTag in sourceTags)
            {
                if (!targetTags.Contains(sourceTag))
                {
                    missingTags.Add(sourceTag);
                }
            }

            return missingTags;
        }

        private async Task<List<string>> GetMissingRequiredTagsForMigration(CNCBrandTemplate template, string targetBrand)
        {
            var missingTags = new List<string>();
            var targetTemplates = await _templateRepository.GetByBrandAsync(targetBrand);
            var sourceConfig = ParseTemplateConfiguration(template.TemplateJson);

            var requiredSourceTags = sourceConfig.TagMappings.Where(m => m.IsRequired).Select(m => m.StandardTagId).ToList();
            var targetTags = targetTemplates.SelectMany(t => ParseTemplateConfiguration(t.TemplateJson).TagMappings.Select(m => m.StandardTagId));

            foreach (var requiredTag in requiredSourceTags)
            {
                if (!targetTags.Contains(requiredTag))
                {
                    missingTags.Add(requiredTag);
                }
            }

            return missingTags;
        }

        private async Task<List<MigrationIssue>> DetectDataTypeConflicts(CNCBrandTemplate template, string targetBrand)
        {
            var issues = new List<MigrationIssue>();
            var targetTemplates = await _templateRepository.GetByBrandAsync(targetBrand);
            var sourceConfig = ParseTemplateConfiguration(template.TemplateJson);

            foreach (var sourceMapping in sourceConfig.TagMappings)
            {
                foreach (var targetTemplate in targetTemplates)
                {
                    var targetConfig = ParseTemplateConfiguration(targetTemplate.TemplateJson);
                    var targetMapping = targetConfig.TagMappings.FirstOrDefault(m => m.StandardTagId == sourceMapping.StandardTagId);

                    if (targetMapping != null && targetMapping.DataType != sourceMapping.DataType)
                    {
                        issues.Add(new MigrationIssue
                        {
                            Severity = MigrationIssueSeverity.Medium,
                            Description = $"Data type conflict for tag '{sourceMapping.StandardTagId}': source '{sourceMapping.DataType}', target '{targetMapping.DataType}'",
                            Recommendation = $"Review and reconcile data type difference"
                        });
                    }
                }
            }

            return issues;
        }

        private async Task<List<MigrationIssue>> DetectConversionRuleConflicts(CNCBrandTemplate template, string targetBrand)
        {
            var issues = new List<MigrationIssue>();
            var targetTemplates = await _templateRepository.GetByBrandAsync(targetBrand);
            var sourceConfig = ParseTemplateConfiguration(template.TemplateJson);

            foreach (var sourceMapping in sourceConfig.TagMappings)
            {
                if (!string.IsNullOrEmpty(sourceMapping.ConversionRule))
                {
                    foreach (var targetTemplate in targetTemplates)
                    {
                        var targetConfig = ParseTemplateConfiguration(targetTemplate.TemplateJson);
                        var targetMapping = targetConfig.TagMappings.FirstOrDefault(m => m.StandardTagId == sourceMapping.StandardTagId);

                        if (targetMapping != null && !string.IsNullOrEmpty(targetMapping.ConversionRule) && targetMapping.ConversionRule != sourceMapping.ConversionRule)
                        {
                            issues.Add(new MigrationIssue
                            {
                                Severity = MigrationIssueSeverity.Low,
                                Description = $"Conversion rule conflict for tag '{sourceMapping.StandardTagId}': source '{sourceMapping.ConversionRule}', target '{targetMapping.ConversionRule}'",
                                Recommendation = $"Review conversion rule compatibility"
                            });
                        }
                    }
                }
            }

            return issues;
        }

        private TemplateConfiguration ParseTemplateConfiguration(string templateJson)
        {
            return JsonSerializer.Deserialize<TemplateConfiguration>(templateJson) ?? new TemplateConfiguration();
        }

        #endregion
    }

    // Supporting classes and models
    public class TemplateConfiguration
    {
        public List<TagMapping> TagMappings { get; set; } = new List<TagMapping>();
    }

    public class ValidationError
    {
        public string Field { get; set; }
        public string Message { get; set; }
    }

    public class MigrationReport
    {
        public CNCBrandTemplate SourceTemplate { get; set; }
        public string TargetBrand { get; set; }
        public DateTime MigrationTime { get; set; }
        public bool IsCompatible { get; set; }
        public List<string> MissingTags { get; set; }
        public List<MigrationIssue> Issues { get; set; }
        public List<string> Recommendations { get; set; }
    }

    public class MigrationIssue
    {
        public MigrationIssueSeverity Severity { get; set; }
        public string Description { get; set; }
        public string Recommendation { get; set; }
    }

    public enum MigrationIssueSeverity
    {
        Low,
        Medium,
        High,
        Critical
    }

    public class DeviceSampleData
    {
        public string Device { get; set; }
        public string Desc { get; set; }
        public List<TagData> Tags { get; set; }
    }

    // Additional repository interfaces
    public interface ITagMappingRepository
    {
        Task<TagMapping> AddAsync(TagMapping mapping);
        Task<TagMapping> UpdateAsync(TagMapping mapping);
        Task<bool> DeleteAsync(int mappingId);
        Task<TagMapping> GetByIdAsync(int mappingId);
        Task<IEnumerable<TagMapping>> GetAllAsync();
        Task<IEnumerable<TagMapping>> GetByTemplateIdAsync(int templateId);
    }

    public interface ITemplateMigrationRepository
    {
        Task<MigrationReport> GetMigrationReportAsync(int templateId, string targetBrand);
        Task<IEnumerable<MigrationIssue>> GetMigrationIssuesAsync(int templateId, string targetBrand);
        Task<bool> SaveMigrationLogAsync(MigrationLog log);
    }

    public class MigrationLog
    {
        public int LogId { get; set; }
        public int SourceTemplateId { get; set; }
        public string TargetBrand { get; set; }
        public DateTime MigrationTime { get; set; }
        public bool IsSuccessful { get; set; }
        public string ResultMessage { get; set; }
    }
}