using AngleSharp.Dom;
using Masuit.Tools;
using Masuit.Tools.Models;
using Microsoft.AspNetCore.Mvc.RazorPages;
using PVDEMCS.Common;
using PVDEMCS.Common.Constant;
using PVDEMCS.Common.DI;
using PVDEMCS.Services.Models;
using PVDEMCS.Services.Repositories.Entities;
using SharpCompress.Common;
using System;
using static Microsoft.EntityFrameworkCore.DbLoggerCategory;

namespace PVDEMCS.Services.Repositories.Impl
{
    /// <summary>
    /// PLC控制器 数据层 实现
    /// </summary>
    internal class DeviceRepository : IDeviceRepository
    {
        #region PLC控制器

        /// <summary>
        /// 获取PLC控制器分页列表
        /// </summary>
        /// <param name="deviceCode">控制器编号</param>
        /// <param name="deviceName">控制器名称</param>
        /// <param name="activated">是否启用</param>
        /// <param name="page">当前页</param>
        /// <param name="size">页大小</param>
        /// <returns></returns>
        public Result<PagedList<DeviceInfo>> GetDevicePageList(string deviceCode, string deviceName, bool? activated, int page, int size)
        {
            using (var context = new EFContext())
            {
                var query = QueryDevice(deviceCode, deviceName, activated, context);

                var result = query.OrderBy(f => f.DeviceCode).ToPagedList(page, size);

                return new Result<PagedList<DeviceInfo>>(result);

            }
        }

        /// <summary>
        /// 获取PLC控制器列表
        /// </summary>
        /// <param name="deviceCode">控制器编号</param>
        /// <param name="deviceName">控制器名称</param>
        /// <param name="activated">是否启用</param>
        /// <returns></returns>
        public Result<List<DeviceInfo>> GetDeviceInfoList(string deviceCode, string deviceName, bool? activated = false)
        {
            using (var context = new EFContext())
            {
                var query = QueryDevice(deviceCode, deviceName, activated, context);

                var result = query.OrderBy(f => f.DeviceCode).ToList();

                return new Result<List<DeviceInfo>>(result);
            }
        }

        private IQueryable<DeviceInfo> QueryDevice(string deviceCode, string deviceName, bool? activated, EFContext context)
        {
            var query = context.DeviceInfos.Where(f => !f.IsDelete).Select(f =>
                            new DeviceInfo
                            {
                                Id = f.Id,
                                DeviceCode = f.DeviceCode,
                                DeviceName = f.DeviceName,
                                Host = f.Host,
                                Port = f.Port,
                                Protocol = f.Protocol,
                                Activated = f.Activated,
                                Remark = f.Remark,
                            });

            if (!deviceCode.IsNullOrEmpty())
            {
                query = query.Where(f => f.DeviceCode.StartsWith(deviceCode));
            }
            if (!deviceName.IsNullOrEmpty())
            {
                query = query.Where(f => f.DeviceName.StartsWith(deviceName));
            }
            if (activated.HasValue)
            {
                query = query.Where(f => f.Activated == activated.Value);
            }

            return query;
        }

        /// <summary>
        /// 获取PLC控制器明细
        /// </summary>
        /// <param name="id">主键Id</param>
        /// <returns></returns>
        public Result<DeviceInfoEntity> GetDeviceDetail(string id)
        {
            using (var context = new EFContext())
            {
                var result = new Result<DeviceInfoEntity>();

                var detail = context.DeviceInfos.Where(f => f.Id == id).FirstOrDefault();
                if (detail == null)
                {
                    result.Message = $"没有找到Id:【{id}】的数据";
                    return result;
                }
                result.Content = detail;
                return result;
            }
        }

        /// <summary>
        /// 添加PLC控制器
        /// </summary>
        /// <param name="entity"></param>
        /// <returns></returns>
        public Result<string> AddDevice(DeviceInfoEntity entity)
        {
            using (var context = new EFContext())
            {
                var result = new Result<string>();

                var query = context.DeviceInfos.Where(f => !f.IsDelete);
                if (query.Where(f => f.DeviceName == entity.DeviceName).FirstOrDefault() != null)
                {
                    result.Message = $"已存在DeviceName:【{entity.DeviceName}】的数据";
                    return result;
                }
                if (query.Where(f => f.DeviceCode == entity.DeviceCode).FirstOrDefault() != null)
                {
                    result.Message = $"已存在DeviceCode:【{entity.DeviceCode}】的数据";
                    return result;
                }

                entity.Create();
                context.DeviceInfos.Add(entity);
                context.SaveChanges();

                return new Result<string>(entity.Id);
            }
        }

        /// <summary>
        /// 更新PLC控制器
        /// </summary>
        /// <param name="entity"></param>

        public Result UpdateDevice(DeviceInfoEntity entity)
        {
            using (var context = new EFContext())
            {
                var result = new Result();

                var query = context.DeviceInfos.Where(f => !f.IsDelete);
                var update = query.Where(f => f.Id == entity.Id).FirstOrDefault();
                if (update == null)
                {
                    result.Message = $"没有找到Id:【{entity.Id}】的数据";
                    return result;
                }
                if (query.Where(f => f.DeviceName == entity.DeviceName && f.Id != entity.Id).FirstOrDefault() != null)
                {
                    result.Message = $"已存在DeviceName:【{entity.DeviceName}】的数据";
                    return result;
                }
                if (query.Where(f => f.DeviceCode == entity.DeviceCode && f.Id != entity.Id).FirstOrDefault() != null)
                {
                    result.Message = $"已存在DeviceCode:【{entity.DeviceCode}】的数据";
                    return result;
                }

                update.DeviceCode = entity.DeviceCode;
                update.DeviceName = entity.DeviceName;
                update.Activated = entity.Activated;
                update.Host = entity.Host;
                update.Port = entity.Port;
                update.Protocol = entity.Protocol;
                update.Remark = entity.Remark;
                entity.Update();
                context.SaveChanges();

                return result;
            }
        }

        /// <summary>
        /// 删除PLC控制器
        /// </summary>
        /// <param name="id"></param>
        public Result DeleteDevice(string id)
        {
            using (var context = new EFContext())
            {
                var result = new Result();
                var entity = context.DeviceInfos.Where(f => f.Id == id).FirstOrDefault();
                if (entity == null)
                {
                    result.Message = $"没有找到Id:【{id}】的数据";
                    return result;

                }

                entity.Delete();
                context.SaveChanges();

                return result;
            }
        }


        #endregion

        #region PLC点位

        /// <summary>
        /// 获取PLC控制器点位分页列表
        /// </summary>
        /// <param name="deviceId">控制器Id</param>
        /// <param name="deviceCode">控制器编号</param>
        /// <param name="deviceName">控制器名称</param>
        /// <param name="equipmentName">设备名称</param>
        /// <param name="equipmentCode">设备编号</param>
        /// <param name="equipmentType">设备类型</param>
        /// <param name="pointCode">点位编号</param>
        /// <param name="pointName">点位列表</param>
        ///<param name="activated">是否启用</param>
        /// <param name="page">当前页</param>
        /// <param name="size">页大小</param>
        /// <returns></returns>
        public Result<PagedList<DevicePoint>> GetDevicePointPageList(string deviceId, string deviceName, string deviceCode, string equipmentName, string equipmentCode, string equipmentType, string pointCode, string pointName, bool? activated, int page, int size)
        {
            using (var context = new EFContext())
            {
                var query = DevicePointQuery(deviceId, deviceName, deviceCode, equipmentName, equipmentCode, equipmentType, pointCode, pointName, activated, context);
                var pageList = query.OrderBy(f => f.PointCode).ToPagedList(page, size);
                return new Result<PagedList<DevicePoint>>(pageList);
            }
        }

        /// <summary>
        /// 获取PLC控制器点位列表
        /// </summary>
        /// <param name="deviceId">控制器Id</param>
        /// <param name="deviceCode">控制器编号</param>
        /// <param name="deviceName">控制器名称</param>
        /// <param name="equipmentName">设备名称</param>
        /// <param name="equipmentCode">设备编号</param>
        /// <param name="equipmentType">设备类型</param>
        /// <param name="pointCode">点位编号</param>
        /// <param name="pointName">点位列表</param>
        ///<param name="activated">是否启用</param>
        /// <returns></returns>
        public Result<List<DevicePoint>> GetDevicePointList(string deviceId, string deviceName, string deviceCode, string equipmentName, string equipmentCode, string equipmentType, string pointCode, string pointName, bool? activated)
        {
            using (var context = new EFContext())
            {
                var query = DevicePointQuery(deviceId, deviceName, deviceCode, equipmentName, equipmentCode, equipmentType, pointCode, pointName, activated, context);
                var list = query.ToList();
                return new Result<List<DevicePoint>>(list);
            }
        }

        private IQueryable<DevicePoint> DevicePointQuery(string deviceId, string deviceName, string deviceCode, string equipmentName, string equipmentCode, string equipmentType, string pointCode, string pointName, bool? activated, EFContext context)
        {
            var query = from device in context.DeviceInfos.Where(f => !f.IsDelete)
                        join point in context.DevicePoints.Where(f => !f.IsDelete) on device.Id equals point.DeviceId
                        join equipment in context.EquipmentInfos.Where(f => !f.IsDelete) on point.EquipmentId equals equipment.Id
                        select new DevicePoint
                        {
                            Id = point.Id,
                            DeviceId = device.Id,
                            DeviceCode = device.DeviceCode,
                            DeviceName = device.DeviceName,
                            EquipmentId = equipment.Id,
                            EquipmentCode = equipment.EquipmentCode,
                            EquipmentName = equipment.EquipmentName,
                            EquipmentType = equipment.EquipmentType,
                            Model = equipment.Model,
                            IsAlarm = equipment.IsAlarm,
                            Activated = point.Activated,
                            PointCode = point.PointCode,
                            PointName = point.PointName,
                            Address = point.Address,
                            DataType = point.DataType,
                            ActionType = point.ActionType,
                          
                            Remark = point.Remark,
                        };
            if (!deviceId.IsNullOrEmpty())
            {
                query = query.Where(f => f.DeviceId == deviceId);
            }
            if (!deviceName.IsNullOrEmpty())
            {
                query = query.Where(f => f.DeviceName.StartsWith(deviceName));
            }
            if (!deviceCode.IsNullOrEmpty())
            {
                query = query.Where(f => f.DeviceCode.StartsWith(deviceCode));
            }
            if (!equipmentName.IsNullOrEmpty())
            {
                query = query.Where(f => f.EquipmentName.StartsWith(equipmentName));
            }
            if (!equipmentCode.IsNullOrEmpty())
            {
                query = query.Where(f => f.EquipmentCode.StartsWith(equipmentCode));
            }
            if (!equipmentType.IsNullOrEmpty())
            {
                query = query.Where(f => f.EquipmentType == equipmentType);
            }
            if (!pointCode.IsNullOrEmpty())
            {
                query = query.Where(f => f.PointCode.StartsWith(pointCode));
            }
            if (!pointName.IsNullOrEmpty())
            {
                query = query.Where(f => f.PointName.StartsWith(pointName));
            }
            if (activated.HasValue)
            {
                query = query.Where(f => f.Activated == activated.Value);
            }

            return query;
        }

        /// <summary>
        /// 获取PLC控制器点位明细
        /// </summary>
        /// <param name="id">Id</param>
        /// <returns></returns>
        public Result<DevicePointEntity> GetDevicePointDetail(string id)
        {
            using (var context = new EFContext())
            {
                var result = new Result<DevicePointEntity>();

                var entity = context.DevicePoints.Where(f => f.Id == id).FirstOrDefault();
                if (entity == null)
                {
                    result.Message = $"没有找到Id:【{id}】的数据";
                    return result;
                }
                result.Content = entity;

                return result;
            }
        }

        /// <summary>
        /// 添加PLC控制器点位
        /// </summary>
        /// <param name="entity"></param>
        /// <returns></returns>
        public Result<string> AddDevicePoint(DevicePointEntity entity)
        {
            using (var context = new EFContext())
            {
                var result = new Result<string>();

                var query = context.DevicePoints.Where(f => !f.IsDelete);
                if (query.Where(f => f.PointName == entity.PointName).FirstOrDefault() != null)
                {
                    result.Message = $"已存在PointName:【{entity.PointName}】的数据";
                    return result;
                }
                if (query.Where(f => f.PointCode == entity.PointCode).FirstOrDefault() != null)
                {
                    result.Message = $"已存在PointCode:【{entity.PointCode}】的数据";
                    return result;
                }

                entity.Create();
                context.DevicePoints.Add(entity);
                context.SaveChanges();
                result.Content = entity.Id;

                return result;
            }
        }

        /// <summary>
        /// 更新PLC控制器点位
        /// </summary>
        /// <param name="entity"></param>
        /// <returns></returns>
        public Result UpdateDevicePoint(DevicePointEntity entity)
        {
            using (var context = new EFContext())
            {
                var result = new Result();

                var query = context.DevicePoints.Where(f => !f.IsDelete);
                var update = query.Where(f => f.Id == entity.Id).FirstOrDefault();
                if (update == null)
                {
                    result.Message = $"没有找到Id:【{entity.Id}】的数据";
                    return result;
                }
                if (query.Where(f => f.PointName == entity.PointName && f.Id != entity.Id).FirstOrDefault() != null)
                {
                    result.Message = $"已存在PointName:【{entity.PointName}】的数据";
                    return result;
                }
                if (query.Where(f => f.PointCode == entity.PointCode && f.Id != entity.Id).FirstOrDefault() != null)
                {
                    result.Message = $"已存在PointCode:【{entity.PointCode}】的数据";
                    return result;
                }
                update.DeviceId = entity.DeviceId;
                update.EquipmentId = entity.EquipmentId;
                update.PointCode = entity.PointCode;
                update.PointName = entity.PointName;
                update.ActionType = entity.ActionType;
                update.Activated = entity.Activated;
                update.Address = entity.Address;
                update.DataType = entity.DataType;
                update.Remark = entity.Remark;
                entity.Update();
                context.SaveChanges();

                return result;
            }
        }

        /// <summary>
        /// 删除PLC控制器点位
        /// </summary>
        /// <param name="id"></param>
        /// <returns></returns>
        public Result DeleteDevicePoint(string id)
        {
            using (var context = new EFContext())
            {
                var result = new Result();

                var entity = context.DevicePoints.Where(f => f.Id == id).FirstOrDefault();
                if (entity == null)
                {
                    result.Message = $"没有找到Id:【{id}】的数据";
                    return result;
                }

                entity.Delete();
                context.SaveChanges();

                return result;
            }
        }

        #endregion
    }
}
