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

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

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

        public List<Alarm> GetAllAlarms()
        {
            return _context.Alarms
                .OrderByDescending(a => a.OccurrenceTime)
                .ToList();
        }

        public List<Alarm> GetActiveAlarms()
        {
            return _context.Alarms
                .Where(a => !a.IsResolved)
                .OrderByDescending(a => a.OccurrenceTime)
                .ToList();
        }

        public List<Alarm> GetAlarmsByType(string alarmType)
        {
            return _context.Alarms
                .Where(a => a.AlarmType == alarmType)
                .OrderByDescending(a => a.OccurrenceTime)
                .ToList();
        }

        public List<Alarm> GetAlarmsByDeviceId(int deviceId)
        {
            return _context.Alarms
                .Where(a => a.DeviceId == deviceId)
                .OrderByDescending(a => a.OccurrenceTime)
                .ToList();
        }

        public List<Alarm> GetAlarmsByDateRange(DateTime startDate, DateTime endDate)
        {
            return _context.Alarms
                .Where(a => a.OccurrenceTime >= startDate && a.OccurrenceTime <= endDate)
                .OrderByDescending(a => a.OccurrenceTime)
                .ToList();
        }

        public Alarm GetAlarmById(int id)
        {
            return _context.Alarms.Find(id);
        }

        public Alarm CreateAlarm(Alarm alarm)
        {
            alarm.CreatedAt = DateTime.Now;
            alarm.OccurrenceTime = DateTime.Now;
            
            _context.Alarms.Add(alarm);
            _context.SaveChanges();
            
            return alarm;
        }

        public Alarm UpdateAlarm(Alarm alarm)
        {
            alarm.UpdatedAt = DateTime.Now;
            _context.Entry(alarm).State = System.Data.Entity.EntityState.Modified;
            _context.SaveChanges();
            
            return alarm;
        }

        public void DeleteAlarm(int id)
        {
            var alarm = _context.Alarms.Find(id);
            if (alarm != null)
            {
                _context.Alarms.Remove(alarm);
                _context.SaveChanges();
            }
        }

        public void ResolveAlarm(int id, string resolutionNote)
        {
            var alarm = _context.Alarms.Find(id);
            if (alarm != null)
            {
                alarm.IsResolved = true;
                alarm.ResolutionTime = DateTime.Now;
                alarm.ResolutionNote = resolutionNote;
                alarm.UpdatedAt = DateTime.Now;
                
                _context.Entry(alarm).State = System.Data.Entity.EntityState.Modified;
                _context.SaveChanges();
            }
        }

        public AlarmStatistics GetAlarmStatistics(DateTime startDate, DateTime endDate)
        {
            var alarms = _context.Alarms
                .Where(a => a.OccurrenceTime >= startDate && a.OccurrenceTime <= endDate)
                .ToList();

            return new AlarmStatistics
            {
                TotalAlarms = alarms.Count,
                ActiveAlarms = alarms.Count(a => !a.IsResolved),
                ResolvedAlarms = alarms.Count(a => a.IsResolved),
                AlarmsByType = alarms.GroupBy(a => a.AlarmType)
                    .ToDictionary(g => g.Key, g => g.Count()),
                AlarmsByLevel = alarms.GroupBy(a => a.AlarmLevel)
                    .ToDictionary(g => g.Key, g => g.Count())
            };
        }

        public void CleanupOldAlarms(int retentionDays)
        {
            var cutoffDate = DateTime.Now.AddDays(-retentionDays);
            var oldAlarms = _context.Alarms
                .Where(a => a.OccurrenceTime < cutoffDate && a.IsResolved)
                .ToList();

            _context.Alarms.RemoveRange(oldAlarms);
            _context.SaveChanges();
        }
    }

    public class AlarmRuleRepository
    {
        private readonly CNCBusinessDbContext _context;

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

        public List<AlarmRule> GetAllAlarmRules()
        {
            return _context.AlarmRules.ToList();
        }

        public List<AlarmRule> GetEnabledAlarmRules()
        {
            return _context.AlarmRules
                .Where(r => r.IsEnabled)
                .ToList();
        }

        public AlarmRule GetAlarmRuleById(int id)
        {
            return _context.AlarmRules.Find(id);
        }

        public AlarmRule CreateAlarmRule(AlarmRule rule)
        {
            rule.CreatedAt = DateTime.Now;
            rule.UpdatedAt = DateTime.Now;
            
            _context.AlarmRules.Add(rule);
            _context.SaveChanges();
            
            return rule;
        }

        public AlarmRule UpdateAlarmRule(AlarmRule rule)
        {
            rule.UpdatedAt = DateTime.Now;
            _context.Entry(rule).State = System.Data.Entity.EntityState.Modified;
            _context.SaveChanges();
            
            return rule;
        }

        public void DeleteAlarmRule(int id)
        {
            var rule = _context.AlarmRules.Find(id);
            if (rule != null)
            {
                _context.AlarmRules.Remove(rule);
                _context.SaveChanges();
            }
        }

        public void EnableAlarmRule(int id)
        {
            var rule = _context.AlarmRules.Find(id);
            if (rule != null)
            {
                rule.IsEnabled = true;
                rule.UpdatedAt = DateTime.Now;
                _context.SaveChanges();
            }
        }

        public void DisableAlarmRule(int id)
        {
            var rule = _context.AlarmRules.Find(id);
            if (rule != null)
            {
                rule.IsEnabled = false;
                rule.UpdatedAt = DateTime.Now;
                _context.SaveChanges();
            }
        }
    }

    public class StatisticRuleRepository
    {
        private readonly CNCBusinessDbContext _context;

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

        public List<StatisticRule> GetAllStatisticRules()
        {
            return _context.StatisticRules.ToList();
        }

        public List<StatisticRule> GetEnabledStatisticRules()
        {
            return _context.StatisticRules
                .Where(r => r.IsEnabled)
                .ToList();
        }

        public StatisticRule GetStatisticRuleById(int id)
        {
            return _context.StatisticRules.Find(id);
        }

        public StatisticRule CreateStatisticRule(StatisticRule rule)
        {
            rule.CreatedAt = DateTime.Now;
            rule.UpdatedAt = DateTime.Now;
            
            _context.StatisticRules.Add(rule);
            _context.SaveChanges();
            
            return rule;
        }

        public StatisticRule UpdateStatisticRule(StatisticRule rule)
        {
            rule.UpdatedAt = DateTime.Now;
            _context.Entry(rule).State = System.Data.Entity.EntityState.Modified;
            _context.SaveChanges();
            
            return rule;
        }

        public void DeleteStatisticRule(int id)
        {
            var rule = _context.StatisticRules.Find(id);
            if (rule != null)
            {
                _context.StatisticRules.Remove(rule);
                _context.SaveChanges();
            }
        }

        public void EnableStatisticRule(int id)
        {
            var rule = _context.StatisticRules.Find(id);
            if (rule != null)
            {
                rule.IsEnabled = true;
                rule.UpdatedAt = DateTime.Now;
                _context.SaveChanges();
            }
        }

        public void DisableStatisticRule(int id)
        {
            var rule = _context.StatisticRules.Find(id);
            if (rule != null)
            {
                rule.IsEnabled = false;
                rule.UpdatedAt = DateTime.Now;
                _context.SaveChanges();
            }
        }

        public List<StatisticResult> ExecuteStatisticRule(StatisticRule rule, DateTime startDate, DateTime endDate)
        {
            var results = new List<StatisticResult>();
            
            // 根据规则中的分组维度执行统计
            var groupByDimensions = rule.GroupByDimensions;
            
            // 这里需要根据实际的业务逻辑实现统计
            // 简化实现，返回空列表
            return results;
        }
    }

    public class SystemConfigRepository
    {
        private readonly CNCBusinessDbContext _context;

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

        public List<SystemConfig> GetAllSystemConfigs()
        {
            return _context.SystemConfig.ToList();
        }

        public SystemConfig GetConfigByKey(string key)
        {
            return _context.SystemConfig.FirstOrDefault(c => c.ConfigKey == key);
        }

        public string GetConfigValue(string key)
        {
            var config = GetConfigByKey(key);
            return config?.ConfigValue;
        }

        public SystemConfig CreateSystemConfig(SystemConfig config)
        {
            config.CreatedAt = DateTime.Now;
            config.UpdatedAt = DateTime.Now;
            
            _context.SystemConfig.Add(config);
            _context.SaveChanges();
            
            return config;
        }

        public SystemConfig UpdateSystemConfig(SystemConfig config)
        {
            config.UpdatedAt = DateTime.Now;
            _context.Entry(config).State = System.Data.Entity.EntityState.Modified;
            _context.SaveChanges();
            
            return config;
        }

        public void DeleteSystemConfig(int id)
        {
            var config = _context.SystemConfig.Find(id);
            if (config != null)
            {
                _context.SystemConfig.Remove(config);
                _context.SaveChanges();
            }
        }

        public void SetConfigValue(string key, string value)
        {
            var config = GetConfigByKey(key);
            if (config != null)
            {
                config.ConfigValue = value;
                config.UpdatedAt = DateTime.Now;
                _context.SaveChanges();
            }
            else
            {
                // 如果配置不存在，创建新的配置
                CreateSystemConfig(new SystemConfig
                {
                    ConfigKey = key,
                    ConfigValue = value,
                    Description = $"自动生成的配置: {key}"
                });
            }
        }

        public Dictionary<string, string> GetAllConfigsAsDictionary()
        {
            return _context.SystemConfig
                .ToDictionary(c => c.ConfigKey, c => c.ConfigValue);
        }
    }

    public class AlarmService
    {
        private readonly AlarmRepository _alarmRepository;
        private readonly AlarmRuleRepository _alarmRuleRepository;
        private readonly DeviceRepository _deviceRepository;
        private readonly SystemConfigRepository _configRepository;

        public AlarmService(AlarmRepository alarmRepository, AlarmRuleRepository alarmRuleRepository,
            DeviceRepository deviceRepository, SystemConfigRepository configRepository)
        {
            _alarmRepository = alarmRepository;
            _alarmRuleRepository = alarmRuleRepository;
            _deviceRepository = deviceRepository;
            _configRepository = configRepository;
        }

        public Alarm CreateDeviceOfflineAlarm(int deviceId)
        {
            var device = _deviceRepository.GetDeviceById(deviceId);
            if (device == null)
            {
                throw new Exception($"设备 {deviceId} 不存在");
            }

            return _alarmRepository.CreateAlarm(new Alarm
            {
                AlarmType = "DEVICE_OFFLINE",
                AlarmLevel = "WARNING",
                AlarmContent = $"设备 {device.DeviceName} ({device.DeviceCode}) 已离线",
                DeviceId = deviceId,
                DeviceName = device.DeviceName
            });
        }

        public Alarm CreateCollectionFailureAlarm(int deviceId, string errorMessage)
        {
            var device = _deviceRepository.GetDeviceById(deviceId);
            if (device == null)
            {
                throw new Exception($"设备 {deviceId} 不存在");
            }

            return _alarmRepository.CreateAlarm(new Alarm
            {
                AlarmType = "COLLECTION_FAILURE",
                AlarmLevel = "ERROR",
                AlarmContent = $"设备 {device.DeviceName} ({device.DeviceCode}) 采集失败: {errorMessage}",
                DeviceId = deviceId,
                DeviceName = device.DeviceName
            });
        }

        public Alarm CreateDataAnomalyAlarm(int deviceId, string anomalyType, object anomalyValue)
        {
            var device = _deviceRepository.GetDeviceById(deviceId);
            if (device == null)
            {
                throw new Exception($"设备 {deviceId} 不存在");
            }

            return _alarmRepository.CreateAlarm(new Alarm
            {
                AlarmType = $"DATA_ANOMALY_{anomalyType.ToUpper()}",
                AlarmLevel = "WARNING",
                AlarmContent = $"设备 {device.DeviceName} ({device.DeviceCode}) 数据异常: {anomalyType} = {anomalyValue}",
                DeviceId = deviceId,
                DeviceName = device.DeviceName
            });
        }

        public List<Alarm> GetActiveAlarms()
        {
            return _alarmRepository.GetActiveAlarms();
        }

        public void ResolveAlarm(int id, string resolutionNote)
        {
            _alarmRepository.ResolveAlarm(id, resolutionNote);
        }

        public void AutoResolveOldAlarms(int days = 7)
        {
            var cutoffDate = DateTime.Now.AddDays(-days);
            var oldAlarms = _alarmRepository.GetAlarmsByDateRange(
                DateTime.MinValue, cutoffDate)
                .Where(a => a.IsResolved)
                .ToList();

            foreach (var alarm in oldAlarms)
            {
                // 这里可以将已解决的告警移动到历史表
                // 简化实现，直接删除
                _alarmRepository.DeleteAlarm(alarm.Id);
            }
        }
    }

    public class AlarmStatistics
    {
        public int TotalAlarms { get; set; }
        public int ActiveAlarms { get; set; }
        public int ResolvedAlarms { get; set; }
        public Dictionary<string, int> AlarmsByType { get; set; }
        public Dictionary<string, int> AlarmsByLevel { get; set; }
    }

    public class StatisticResult
    {
        public int RuleId { get; set; }
        public DateTime StatisticTime { get; set; }
        public Dictionary<string, object> GroupValues { get; set; }
        public decimal MetricValue { get; set; }
        public DateTime CreatedAt { get; set; }
    }
}