using Microsoft.EntityFrameworkCore;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using Haoliang.Models.System;
using Haoliang.Data;
using Haoliang.Data.Repositories;
using Haoliang.Data.Entities;

namespace Haoliang.Data.Repositories
{
    public interface IAlarmRepository : IRepository<Alarm>
    {
        Task<IEnumerable<Alarm>> GetActiveAlarmsAsync();
        Task<IEnumerable<Alarm>> GetAlarmsByDeviceIdAsync(int deviceId);
        Task<IEnumerable<Alarm>> GetAlarmsByTypeAsync(string alarmType);
        Task<IEnumerable<Alarm>> GetAlarmsByLevelAsync(string alarmLevel);
        Task<IEnumerable<Alarm>> GetUnresolvedAlarmsAsync();
        Task<IEnumerable<Alarm>> GetAlarmsByDateRangeAsync(DateTime startDate, DateTime endDate);
        Task<int> CountActiveAlarmsAsync();
        Task<int> CountAlarmsByTypeAsync(string alarmType);
        Task<decimal> GetAlarmResolutionRateAsync(DateTime startDate, DateTime endDate);
        Task<bool> ResolveAlarmAsync(int alarmId, string resolutionNote, string resolvedBy);
        Task<bool> DeleteOldAlarmsAsync(int keepDays = 90);
    }

    public class AlarmRepository : Repository<Alarm>, IAlarmRepository
    {
        private readonly CNCDbContext _context;

        public AlarmRepository(CNCDbContext context) : base(context)
        {
            _context = context;
        }

        public async Task<IEnumerable<Alarm>> GetActiveAlarmsAsync()
        {
            return await _context.Alarms
                .Where(a => !a.IsResolved)
                .OrderByDescending(a => a.OccurrenceTime)
                .ToListAsync();
        }

        public async Task<IEnumerable<Alarm>> GetAlarmsByDeviceIdAsync(int deviceId)
        {
            return await _context.Alarms
                .Where(a => a.DeviceId == deviceId)
                .OrderByDescending(a => a.OccurrenceTime)
                .ToListAsync();
        }

        public async Task<IEnumerable<Alarm>> GetAlarmsByTypeAsync(string alarmType)
        {
            return await _context.Alarms
                .Where(a => a.AlarmType == alarmType)
                .OrderByDescending(a => a.OccurrenceTime)
                .ToListAsync();
        }

        public async Task<IEnumerable<Alarm>> GetAlarmsByLevelAsync(string alarmLevel)
        {
            return await _context.Alarms
                .Where(a => a.AlarmLevel == alarmLevel)
                .OrderByDescending(a => a.OccurrenceTime)
                .ToListAsync();
        }

        public async Task<IEnumerable<Alarm>> GetUnresolvedAlarmsAsync()
        {
            return await GetActiveAlarmsAsync();
        }

        public async Task<IEnumerable<Alarm>> GetAlarmsByDateRangeAsync(DateTime startDate, DateTime endDate)
        {
            return await _context.Alarms
                .Where(a => a.OccurrenceTime >= startDate && a.OccurrenceTime <= endDate)
                .OrderByDescending(a => a.OccurrenceTime)
                .ToListAsync();
        }

        public async Task<int> CountActiveAlarmsAsync()
        {
            return await _context.Alarms
                .CountAsync(a => !a.IsResolved);
        }

        public async Task<int> CountAlarmsByTypeAsync(string alarmType)
        {
            return await _context.Alarms
                .CountAsync(a => a.AlarmType == alarmType);
        }

        public async Task<decimal> GetAlarmResolutionRateAsync(DateTime startDate, DateTime endDate)
        {
            var alarms = await GetAlarmsByDateRangeAsync(startDate, endDate);
            if (alarms.Any())
            {
                var resolvedCount = alarms.Count(a => a.IsResolved);
                return (decimal)resolvedCount / alarms.Count() * 100;
            }
            return 0;
        }

        public async Task<bool> ResolveAlarmAsync(int alarmId, string resolutionNote, string resolvedBy)
        {
            var alarm = await GetByIdAsync(alarmId);
            if (alarm != null)
            {
                alarm.IsResolved = true;
                alarm.ResolutionTime = DateTime.Now;
                alarm.ResolutionNote = resolutionNote;
                
                Update(alarm);
                await SaveAsync();
                return true;
            }
            return false;
        }

        public async Task<bool> DeleteOldAlarmsAsync(int keepDays = 90)
        {
            var cutoffDate = DateTime.Now.AddDays(-keepDays);
            var oldAlarms = await _context.Alarms
                .Where(a => a.OccurrenceTime < cutoffDate)
                .ToListAsync();

            if (oldAlarms.Any())
            {
                RemoveRange(oldAlarms);
                await SaveAsync();
                return true;
            }
            return false;
        }
    }
}