using System;
using System.Linq;
using System.Transactions;
using FMSAdmin.Data;
using FMSAdmin.Entities;
using FMSAdmin.Helpers;
using Microsoft.Extensions.Logging;

namespace FMSAdmin.Services {
    public class AlarmPointService {
        private readonly ILogger<AlarmPointService> _logger;
        private readonly FMSContext _context;
        private readonly PushHelper _pushHelper;

        public AlarmPointService(
            ILogger<AlarmPointService> logger,
            FMSContext context,
            PushHelper pushHelper) {
            _logger = logger;
            _context = context;
            _pushHelper = pushHelper;
        }
        public void Create(FmsAlarmPoint[] data) {
            foreach (var item in data) {
                checkName(item);
            }
            _context.FmsAlarmPoint.AddRange(data);
            _context.SaveChanges();
        }

        public void checkName(FmsAlarmPoint data) {
            var check = _context.FmsAlarmPoint.Where(x => x.SiteId == data.SiteId && x.FacilityCode == data.FacilityCode && x.PropertyId == data.PropertyId).Count();
            if (check > 0) {
                var monitoringPoint = _context.BemsMonitoringPoint.Where(x => x.SiteId == data.SiteId && x.FacilityCode == data.FacilityCode && x.PropertyId == data.PropertyId).FirstOrDefault();
                throw new ServiceException("이미 등록되어 있습니다.(" + monitoringPoint.CmFacility.Name + " - " + monitoringPoint.Name + ")");
            }
        }

        public void Delete(int siteId, int facilityCode, int propertyId) {
            var data = _context.FmsAlarmPoint.First(x => x.SiteId == siteId && x.FacilityCode == facilityCode && x.PropertyId == propertyId);
            _context.FmsAlarmPoint.Remove(data);
            _context.SaveChanges();
        }

        public IQueryable<FmsAlarmPoint> GetAll() {
            var query = _context.FmsAlarmPoint;
            return query;
        }

        public IQueryable<FmsAlarmPoint> Get(int siteId, int facilityCode, int propertyId) {
            var data = _context.FmsAlarmPoint.Where(x => x.SiteId == siteId && x.FacilityCode == facilityCode && x.PropertyId == propertyId);
            return data;
        }

        public IQueryable<FmsAlarmLog> GetAlarmLog() {
            var query = _context.FmsAlarmLog.Where(x => x.AlarmPoint != null);
            return query;
        }

        public IQueryable<BemsMonitoringPointHistory15min> GetPointHistoryList() {
            var query = _context.BemsMonitoringPointHistory15min.Where(x => x.FmsAlarmPoint != null && x.CurrentValue == 1);
            return query;
        }

        public void SendPush() {
            var list = _context.FmsAlarmLog.Where(
                x => x.AlarmPoint != null
                && x.CreatedDateTime >= DateTime.Now.Date
                && x.IsSendPush == false
            ).OrderBy(x => x.CreatedDateTime).ToList();

            foreach (var item in list) {
                try {
                    using (var trans = new TransactionScope()) {
                        var facilityTypeName = Util.V(item, x => x.AlarmPoint.BemsMonitoringPoint.FacilityType.Name);
                        var monitoringPointName = Util.V(item, x => x.AlarmPoint.BemsMonitoringPoint.Name);
                        var title = (Math.Abs(item.CurrentValue) <= double.Epsilon ? "경보해제" : "경보발생") + $" [{item.CreatedDateTime.ToString("yyyy-MM-dd HH:mm:ss")}]";
                        var message = $"{facilityTypeName} - {monitoringPointName}";

                        _logger.LogInformation($"{item.SiteId} / {item.FacilityCode} / {item.PropertyId} / {item.CreatedDateTime} / {item.FacilityTypeId} / {item.CurrentValue} / {title} / {message}");

                        _pushHelper.SendToSiteUsers(item.SiteId, title, message, new { });

                        item.IsSendPush = true;
                        _context.FmsAlarmLog.Update(item);
                        _context.SaveChanges();

                        trans.Complete();
                    }
                } catch (Exception ex) {
                    _logger.LogError(ex, "");
                }
            }
        }

    }
}