using System;
using System.Collections.Generic;
using System.Linq;
using CNCSystem.Data.Entities;
using Haoliang.Data;
using Haoliang.Data.Entities;
using CNCSystem.Models.Template;

namespace CNCSystem.Data.Repositories
{
    public class TemplateRepository
    {
        private readonly CNCBusinessDbContext _context;

        public TemplateRepository(CNCBusinessDbContext context)
        {
            _context = context;
        }

        public List<CNCBrandTemplate> GetAllTemplates()
        {
            return _context.CNCTemplates
                .Include(t => t.FieldMappings)
                .ToList();
        }

        public List<CNCBrandTemplate> GetEnabledTemplates()
        {
            return _context.CNCTemplates
                .Include(t => t.FieldMappings)
                .Where(t => t.IsEnabled)
                .ToList();
        }

        public CNCBrandTemplate GetTemplateById(int id)
        {
            return _context.CNCTemplates
                .Include(t => t.FieldMappings)
                .FirstOrDefault(t => t.Id == id);
        }

        public CNCBrandTemplate GetTemplateByBrandName(string brandName)
        {
            return _context.CNCTemplates
                .Include(t => t.FieldMappings)
                .FirstOrDefault(t => t.BrandName == brandName);
        }

        public CNCBrandTemplate CreateTemplate(CNCBrandTemplate template)
        {
            template.CreatedAt = DateTime.Now;
            template.UpdatedAt = DateTime.Now;
            _context.CNCTemplates.Add(template);
            _context.SaveChanges();
            return template;
        }

        public CNCBrandTemplate UpdateTemplate(CNCBrandTemplate template)
        {
            template.UpdatedAt = DateTime.Now;
            _context.Entry(template).State = System.Data.Entity.EntityState.Modified;
            
            // 更新字段映射
            foreach (var fieldMapping in template.FieldMappings)
            {
                if (fieldMapping.Id == 0)
                {
                    _context.TemplateFieldMappings.Add(fieldMapping);
                }
                else
                {
                    _context.Entry(fieldMapping).State = System.Data.Entity.EntityState.Modified;
                }
            }
            
            _context.SaveChanges();
            return template;
        }

        public void DeleteTemplate(int id)
        {
            var template = _context.CNCTemplates.Find(id);
            if (template != null)
            {
                // 删除相关的字段映射
                var fieldMappings = _context.TemplateFieldMappings
                    .Where(fm => fm.TemplateId == id)
                    .ToList();
                
                _context.TemplateFieldMappings.RemoveRange(fieldMappings);
                _context.CNCTemplates.Remove(template);
                _context.SaveChanges();
            }
        }

        public void EnableTemplate(int id)
        {
            var template = _context.CNCTemplates.Find(id);
            if (template != null)
            {
                template.IsEnabled = true;
                template.UpdatedAt = DateTime.Now;
                _context.SaveChanges();
            }
        }

        public void DisableTemplate(int id)
        {
            var template = _context.CNCTemplates.Find(id);
            if (template != null)
            {
                template.IsEnabled = false;
                template.UpdatedAt = DateTime.Now;
                _context.SaveChanges();
            }
        }

        public List<TemplateFieldMapping> GetFieldMappingsByTemplateId(int templateId)
        {
            return _context.TemplateFieldMappings
                .Where(fm => fm.TemplateId == templateId)
                .ToList();
        }

        public TemplateFieldMapping GetFieldMappingById(int id)
        {
            return _context.TemplateFieldMappings.Find(id);
        }

        public TemplateFieldMapping CreateFieldMapping(TemplateFieldMapping fieldMapping)
        {
            fieldMapping.CreatedAt = DateTime.Now;
            _context.TemplateFieldMappings.Add(fieldMapping);
            _context.SaveChanges();
            return fieldMapping;
        }

        public TemplateFieldMapping UpdateFieldMapping(TemplateFieldMapping fieldMapping)
        {
            _context.Entry(fieldMapping).State = System.Data.Entity.EntityState.Modified;
            _context.SaveChanges();
            return fieldMapping;
        }

        public void DeleteFieldMapping(int id)
        {
            var fieldMapping = _context.TemplateFieldMappings.Find(id);
            if (fieldMapping != null)
            {
                _context.TemplateFieldMappings.Remove(fieldMapping);
                _context.SaveChanges();
            }
        }
    }

    public class TemplateMappingService
    {
        private readonly TemplateRepository _templateRepository;
        private readonly DeviceRepository _deviceRepository;

        public TemplateMappingService(TemplateRepository templateRepository, DeviceRepository deviceRepository)
        {
            _templateRepository = templateRepository;
            _deviceRepository = deviceRepository;
        }

        public Dictionary<string, object> MapRawDataToStandardFormat(string brandName, Dictionary<string, object> rawData)
        {
            var template = _templateRepository.GetTemplateByBrandName(brandName);
            if (template == null)
            {
                throw new Exception($"未找到品牌 {brandName} 的模板配置");
            }

            var standardData = new Dictionary<string, object>();

            foreach (var fieldMapping in template.FieldMappings)
            {
                try
                {
                    var rawValue = GetRawValueByPath(rawData, fieldMapping.SourceFieldPath);
                    var convertedValue = ConvertValue(rawValue, fieldMapping.DataType, fieldMapping.ConversionRule);
                    
                    standardData[fieldMapping.StandardFieldId] = new
                    {
                        id = fieldMapping.StandardFieldId,
                        desc = fieldMapping.StandardFieldDesc,
                        quality = "Good",
                        value = convertedValue,
                        time = DateTime.Now
                    };
                }
                catch (Exception ex)
                {
                    // 记录映射错误
                    standardData[fieldMapping.StandardFieldId] = new
                    {
                        id = fieldMapping.StandardFieldId,
                        desc = fieldMapping.StandardFieldDesc,
                        quality = "Bad",
                        value = null,
                        time = DateTime.Now,
                        error = ex.Message
                    };
                }
            }

            return standardData;
        }

        private object GetRawValueByPath(Dictionary<string, object> rawData, string fieldPath)
        {
            // 简化的路径解析，实际项目中需要更复杂的JSON路径解析
            if (rawData.ContainsKey(fieldPath))
            {
                return rawData[fieldPath];
            }

            // 如果是数组路径，需要更复杂的处理
            if (fieldPath.Contains("[") && fieldPath.Contains("]"))
            {
                var parts = fieldPath.Split('[');
                if (parts.Length > 1)
                {
                    var key = parts[0];
                    var indexPart = parts[1].Split(']')[0];
                    
                    if (int.TryParse(indexPart, out int index))
                    {
                        if (rawData.ContainsKey(key) && rawData[key] is List<object> list && list.Count > index)
                        {
                            return list[index];
                        }
                    }
                }
            }

            throw new Exception($"无法找到字段路径: {fieldPath}");
        }

        private object ConvertValue(object rawValue, string dataType, ConversionRule conversionRule)
        {
            if (rawValue == null) return null;

            try
            {
                switch (dataType.ToLower())
                {
                    case "string":
                        return rawValue.ToString();
                        
                    case "int":
                    case "integer":
                        if (int.TryParse(rawValue.ToString(), out int intValue))
                            return intValue;
                        throw new Exception($"无法将 {rawValue} 转换为整数");
                        
                    case "decimal":
                    case "float":
                    case "double":
                        if (decimal.TryParse(rawValue.ToString(), out decimal decimalValue))
                            return decimalValue;
                        throw new Exception($"无法将 {rawValue} 转换为数字");
                        
                    case "bool":
                    case "boolean":
                        if (bool.TryParse(rawValue.ToString(), out bool boolValue))
                            return boolValue;
                        throw new Exception($"无法将 {rawValue} 转换为布尔值");
                        
                    case "datetime":
                        if (DateTime.TryParse(rawValue.ToString(), out DateTime dateTimeValue))
                            return dateTimeValue;
                        throw new Exception($"无法将 {rawValue} 转换为日期时间");
                        
                    default:
                        return rawValue;
                }
            }
            catch (Exception ex)
            {
                throw new Exception($"数据类型转换失败: {ex.Message}");
            }
        }

        public void ValidateTemplate(CNCBrandTemplate template)
        {
            if (string.IsNullOrWhiteSpace(template.BrandName))
            {
                throw new Exception("品牌名称不能为空");
            }

            if (string.IsNullOrWhiteSpace(template.FieldMappings?.ToString()))
            {
                throw new Exception("字段映射不能为空");
            }

            // 检查字段映射的完整性
            foreach (var fieldMapping in template.FieldMappings)
            {
                if (string.IsNullOrWhiteSpace(fieldMapping.SourceFieldPath))
                {
                    throw new Exception("源字段路径不能为空");
                }

                if (string.IsNullOrWhiteSpace(fieldMapping.StandardFieldId))
                {
                    throw new Exception("标准字段ID不能为空");
                }

                if (string.IsNullOrWhiteSpace(fieldMapping.StandardFieldDesc))
                {
                    throw new Exception("标准字段描述不能为空");
                }

                if (string.IsNullOrWhiteSpace(fieldMapping.DataType))
                {
                    throw new Exception("数据类型不能为空");
                }
            }
        }
    }
}