using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using NPP.SmartSchedue.Api.Contracts.Domain.Equipment;
using NPP.SmartSchedue.Api.Core.Repositories;
using ZhonTai.Admin.Core.Db.Transaction;

namespace NPP.SmartSchedue.Api.Repositories.Equipment
{
    /// <summary>
    /// 设备仓储实现
    /// </summary>
    public class EquipmentRepository : AppRepositoryBase<EquipmentEntity>, IEquipmentRepository
    {
        public EquipmentRepository(UnitOfWorkManagerCloud uowm) : base(uowm)
        {
        }

        /// <summary>
        /// 根据设备类型获取设备列表
        /// </summary>
        public async Task<List<EquipmentEntity>> GetByTypeAsync(string equipmentType)
        {
            if (string.IsNullOrWhiteSpace(equipmentType))
                return new List<EquipmentEntity>();

            return await Select
                .Where(e => e.EquipmentType == equipmentType)
                .Where(e => e.IsDeleted == false)
                .ToListAsync();
        }

        /// <summary>
        /// 根据状态获取设备列表
        /// </summary>
        public async Task<List<EquipmentEntity>> GetByStatusAsync(int status)
        {
            return await Select
                .Where(e => e.Status == status)
                .Where(e => e.IsDeleted == false)
                .ToListAsync();
        }

        /// <summary>
        /// 根据内部编号获取设备
        /// </summary>
        public async Task<EquipmentEntity> GetByInternalNumberAsync(string internalNumber)
        {
            if (string.IsNullOrWhiteSpace(internalNumber))
                return null;

            return await Select
                .Where(e => e.InternalNumber == internalNumber)
                .Where(e => e.IsDeleted == false)
                .FirstAsync();
        }

        /// <summary>
        /// 获取可用设备列表（正常状态）
        /// 综合考虑设备状态、维护计划、校验计划等因素
        /// </summary>
        /// <param name="date">指定日期，用于检查维护和校验计划</param>
        /// <returns>可用设备列表</returns>
        public async Task<List<EquipmentEntity>> GetAvailableEquipmentAsync(DateTime date)
        {
            // 获取在指定日期可用的设备
            return await Select
                .Where(e => e.IsDeleted == false) // 未删除
                .Where(e => e.Status == EquipmentStatus.Normal) // 正常状态
                .Where(e => !e.NextMaintenanceDate.HasValue || e.NextMaintenanceDate.Value.Date > date.Date) // 不需要维护
                .Where(e => !e.NextCalibrationDate.HasValue || e.NextCalibrationDate.Value.Date > date.Date) // 不需要校验
                .ToListAsync();
        }

        /// <summary>
        /// 根据工序获取适配设备列表
        /// </summary>
        public async Task<List<EquipmentEntity>> GetByProcessAsync(string processName)
        {
            if (string.IsNullOrWhiteSpace(processName))
                return new List<EquipmentEntity>();

            // 注意：这里假设有工序关联关系，实际可能需要通过ProcessID关联
            return await Select
                .Where(e => e.Status == EquipmentStatus.Normal)
                .Where(e => e.IsDeleted == false)
                .ToListAsync();
        }

        /// <summary>
        /// 检查设备是否可用
        /// </summary>
        public async Task<bool> IsEquipmentAvailableAsync(long equipmentId, DateTime date)
        {
            var equipment = await Select
                .Where(e => e.Id == equipmentId)
                .Where(e => e.IsDeleted == false)
                .FirstAsync();

            if (equipment == null)
                return false;

            // 检查设备基本状态
            if (equipment.Status != EquipmentStatus.Normal)
                return false;

            // 可以扩展检查维护计划、校验计划等
            return true;
        }

        /// <summary>
        /// 获取设备使用情况
        /// </summary>
        public async Task<EquipmentUsageInfo> GetUsageAsync(long equipmentId, DateTime startDate, DateTime endDate)
        {
            var equipment = await Select
                .Where(e => e.Id == equipmentId)
                .Where(e => e.IsDeleted == false)
                .FirstAsync();

            if (equipment == null)
                return new EquipmentUsageInfo { EquipmentId = equipmentId };

            // 这里可以统计设备在指定时间范围内的使用情况
            // 需要关联工作任务表等来获取实际使用数据
            return new EquipmentUsageInfo
            {
                EquipmentId = equipmentId,
                EquipmentName = equipment.Name,
                UsageDays = (endDate - startDate).Days,
                UsageHours = 0, // 需要从工作任务中统计
                MaintenanceCount = 0, // 需要从维护记录中统计
                CalibrationCount = 0, // 需要从校验记录中统计
                FaultCount = 0 // 需要从故障记录中统计
            };
        }

        /// <summary>
        /// 获取需要维护的设备列表
        /// </summary>
        public async Task<List<EquipmentEntity>> GetNeedMaintenanceAsync(DateTime date)
        {
            return await Select
                .Where(e => e.NextMaintenanceDate.HasValue)
                .Where(e => e.NextMaintenanceDate.Value.Date <= date.Date)
                .Where(e => e.Status == EquipmentStatus.Normal)
                .Where(e => e.IsDeleted == false)
                .ToListAsync();
        }

        /// <summary>
        /// 获取需要校验的设备列表
        /// </summary>
        public async Task<List<EquipmentEntity>> GetNeedCalibrationAsync(DateTime date)
        {
            return await Select
                .Where(e => e.NextCalibrationDate.HasValue)
                .Where(e => e.NextCalibrationDate.Value.Date <= date.Date)
                .Where(e => e.Status == EquipmentStatus.Normal)
                .Where(e => e.IsDeleted == false)
                .ToListAsync();
        }

        /// <summary>
        /// 检查指定设备类型是否有可用设备
        /// 用于任务验证时检查设备可用性
        /// </summary>
        /// <param name="equipmentType">设备类型</param>
        /// <returns>是否有可用设备</returns>
        public async Task<bool> HasAvailableEquipmentByTypeAsync(string equipmentType)
        {
            if (string.IsNullOrWhiteSpace(equipmentType))
                return false;

            return await Select
                .Where(e => e.EquipmentType == equipmentType)
                .Where(e => e.Status == EquipmentStatus.Normal)
                .Where(e => e.IsDeleted == false)
                .AnyAsync();
        }
    }
}