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

namespace NPP.SmartSchedue.Api.Repositories.Integration
{
    /// <summary>
    /// 智能整合记录仓储实现类
    /// 
    /// 业务实现思考：
    /// 1. 充分利用FreeSql的强大功能，包括分页、索引优化、JSON查询等
    /// 2. 考虑查询性能，合理使用索引和查询优化策略
    /// 3. 实现完整的统计分析功能，为业务决策提供数据支持
    /// 4. 处理大数据量场景，提供高效的分页和聚合查询
    /// </summary>
    public class IntegrationRecordRepository : AppRepositoryBase<IntegrationRecordEntity>, IIntegrationRecordRepository
    {
        public IntegrationRecordRepository(UnitOfWorkManagerCloud unitOfWorkManager) : base(unitOfWorkManager)
        {
        }

        #region 基础查询方法

        /// <summary>
        /// 根据批次编码获取整合记录
        /// 利用唯一索引，确保查询性能
        /// </summary>
        public async Task<IntegrationRecordEntity?> GetByBatchCodeAsync(string batchCode)
        {
            if (string.IsNullOrWhiteSpace(batchCode))
                return null;

            return await Select
                .Where(r => r.IntegrationBatchCode == batchCode)
                .FirstAsync();
        }

        /// <summary>
        /// 获取指定时间范围内的整合记录
        /// 使用时间索引优化查询性能
        /// </summary>
        public async Task<(List<IntegrationRecordEntity> Records, long Total)> GetByTimeRangeAsync(
            DateTime startTime, 
            DateTime endTime, 
            int pageIndex = 1, 
            int pageSize = 20)
        {
            var query = Select
                .Where(r => r.IntegrationTime >= startTime && r.IntegrationTime <= endTime)
                .OrderByDescending(r => r.IntegrationTime);

            var total = await query.CountAsync();
            var records = await query
                .Page(pageIndex, pageSize)
                .ToListAsync();

            return (records, total);
        }

        /// <summary>
        /// 根据操作人员获取整合记录
        /// 使用操作员索引优化查询
        /// </summary>
        public async Task<(List<IntegrationRecordEntity> Records, long Total)> GetByOperatorAsync(
            long operatorUserId, 
            int pageIndex = 1, 
            int pageSize = 20)
        {
            var query = Select
                .Where(r => r.OperatorUserId == operatorUserId)
                .OrderByDescending(r => r.IntegrationTime);

            var total = await query.CountAsync();
            var records = await query
                .Page(pageIndex, pageSize)
                .ToListAsync();

            return (records, total);
        }

        /// <summary>
        /// 根据项目编号获取相关整合记录
        /// 使用字符串包含查询，注意性能优化
        /// </summary>
        public async Task<(List<IntegrationRecordEntity> Records, long Total)> GetByProjectNumberAsync(
            string projectNumber, 
            int pageIndex = 1, 
            int pageSize = 20)
        {
            if (string.IsNullOrWhiteSpace(projectNumber))
                return (new List<IntegrationRecordEntity>(), 0);

            var query = Select
                .Where(r => r.ProjectNumbers.Contains(projectNumber))
                .OrderByDescending(r => r.IntegrationTime);

            var total = await query.CountAsync();
            var records = await query
                .Page(pageIndex, pageSize)
                .ToListAsync();

            return (records, total);
        }

        #endregion

        #region 复合查询方法

        /// <summary>
        /// 多维度综合查询整合记录
        /// 动态构建查询条件，支持灵活的业务查询需求
        /// </summary>
        public async Task<(List<IntegrationRecordEntity> Records, long Total)> GetByMultipleConditionsAsync(
            long? operatorUserId = null,
            string? projectNumber = null,
            string? integrationType = null,
            DateTime? startTime = null,
            DateTime? endTime = null,
            decimal? minSuccessRate = null,
            int pageIndex = 1,
            int pageSize = 20)
        {
            var query = Select;

            // 动态添加查询条件
            if (operatorUserId.HasValue)
            {
                query = query.Where(r => r.OperatorUserId == operatorUserId.Value);
            }

            if (!string.IsNullOrWhiteSpace(projectNumber))
            {
                query = query.Where(r => r.ProjectNumbers.Contains(projectNumber));
            }

            if (!string.IsNullOrWhiteSpace(integrationType))
            {
                query = query.Where(r => r.IntegrationType == integrationType);
            }

            if (startTime.HasValue)
            {
                query = query.Where(r => r.IntegrationTime >= startTime.Value);
            }

            if (endTime.HasValue)
            {
                query = query.Where(r => r.IntegrationTime <= endTime.Value);
            }

            if (minSuccessRate.HasValue)
            {
                // 使用计算字段进行筛选
                query = query.Where(r => r.SuccessTaskCount + r.FailedTaskCount > 0)
                            .Where(r => (decimal)r.SuccessTaskCount / (r.SuccessTaskCount + r.FailedTaskCount) * 100 >= minSuccessRate.Value);
            }

            var orderedQuery = query.OrderByDescending(r => r.IntegrationTime);
            
            var total = await orderedQuery.CountAsync();
            var records = await orderedQuery
                .Page(pageIndex, pageSize)
                .ToListAsync();

            return (records, total);
        }

        /// <summary>
        /// 获取包含指定任务的整合记录
        /// 使用JSON查询功能，在TaskIdsJson中搜索任务ID
        /// </summary>
        public async Task<List<IntegrationRecordEntity>> GetRecordsContainingTaskAsync(long taskId)
        {
            // 使用FreeSql的JSON查询功能，支持JSON数组格式
            return await Select
                .Where(r => r.TaskIdsJson.Contains($"\"{taskId}\"") || r.TaskIdsJson.Contains($"{taskId}"))
                .OrderByDescending(r => r.IntegrationTime)
                .ToListAsync();
        }

        #endregion

        #region 统计分析方法

        /// <summary>
        /// 获取指定时间段的整合统计数据
        /// 使用聚合查询生成统计报表
        /// </summary>
        public async Task<IntegrationStatistics> GetIntegrationStatisticsAsync(DateTime startTime, DateTime endTime)
        {
            var records = await Select
                .Where(r => r.IntegrationTime >= startTime && r.IntegrationTime <= endTime)
                .Where(r => !r.IsTestData) // 排除测试数据
                .ToListAsync();

            if (!records.Any())
            {
                return new IntegrationStatistics
                {
                    StartTime = startTime,
                    EndTime = endTime
                };
            }

            var totalTasks = records.Sum(r => r.SuccessTaskCount + r.FailedTaskCount);
            var successfulTasks = records.Sum(r => r.SuccessTaskCount);
            var failedTasks = records.Sum(r => r.FailedTaskCount);

            return new IntegrationStatistics
            {
                StartTime = startTime,
                EndTime = endTime,
                TotalIntegrations = records.Count,
                TotalTasks = totalTasks,
                SuccessfulTasks = successfulTasks,
                FailedTasks = failedTasks,
                AverageSuccessRate = totalTasks > 0 ? Math.Round((decimal)successfulTasks / totalTasks * 100, 2) : 0,
                AverageElapsedTime = records.Any() ? (long)records.Average(r => r.ElapsedMilliseconds) : 0,
                AveragePersonnelFairnessScore = records.Any() ? Math.Round((decimal)records.Average(r => r.PersonnelFairnessScore), 1) : 0,
                AverageEquipmentUtilizationRate = records.Any() ? Math.Round(records.Average(r => r.EquipmentUtilizationRate), 1) : 0,
                ActiveOperatorCount = records.Select(r => r.OperatorUserId).Distinct().Count(),
                InvolvedProjectCount = records
                    .Where(r => !string.IsNullOrWhiteSpace(r.ProjectNumbers))
                    .SelectMany(r => r.GetProjectNumbers())
                    .Distinct()
                    .Count()
            };
        }

        /// <summary>
        /// 获取操作员整合统计数据
        /// 针对特定操作员的详细统计分析
        /// </summary>
        public async Task<OperatorIntegrationStats> GetOperatorStatisticsAsync(
            long operatorUserId, 
            DateTime startTime, 
            DateTime endTime)
        {
            var records = await Select
                .Where(r => r.OperatorUserId == operatorUserId)
                .Where(r => r.IntegrationTime >= startTime && r.IntegrationTime <= endTime)
                .Where(r => !r.IsTestData)
                .OrderByDescending(r => r.IntegrationTime)
                .ToListAsync();

            if (!records.Any())
            {
                var operatorInfo = await Select
                    .Where(r => r.OperatorUserId == operatorUserId)
                    .OrderByDescending(r => r.IntegrationTime)
                    .FirstAsync();

                return new OperatorIntegrationStats
                {
                    OperatorUserId = operatorUserId,
                    OperatorUserName = operatorInfo?.OperatorUserName ?? "",
                    OperatorRealName = operatorInfo?.OperatorRealName ?? ""
                };
            }

            var totalTasks = records.Sum(r => r.SuccessTaskCount + r.FailedTaskCount);
            var successfulTasks = records.Sum(r => r.SuccessTaskCount);

            return new OperatorIntegrationStats
            {
                OperatorUserId = operatorUserId,
                OperatorUserName = records.First().OperatorUserName,
                OperatorRealName = records.First().OperatorRealName,
                IntegrationCount = records.Count,
                TotalTasks = totalTasks,
                AverageSuccessRate = totalTasks > 0 ? Math.Round((decimal)successfulTasks / totalTasks * 100, 2) : 0,
                TotalElapsedTime = records.Sum(r => r.ElapsedMilliseconds),
                AverageIntegrationTime = records.Any() ? (long)records.Average(r => r.ElapsedMilliseconds) : 0,
                LastOperationTime = records.Max(r => r.IntegrationTime)
            };
        }

        /// <summary>
        /// 获取策略效果分析数据
        /// 分析不同分配策略的效果，支持策略优化决策
        /// </summary>
        public async Task<List<StrategyEffectivenessStats>> GetStrategyEffectivenessAsync(
            DateTime startTime, 
            DateTime endTime)
        {
            var records = await Select
                .Where(r => r.IntegrationTime >= startTime && r.IntegrationTime <= endTime)
                .Where(r => !r.IsTestData)
                .ToListAsync();

            if (!records.Any())
                return new List<StrategyEffectivenessStats>();

            // 解析策略配置并进行分组统计
            var strategyGroups = records
                .Where(r => !string.IsNullOrWhiteSpace(r.StrategyConfigJson))
                .GroupBy(r => r.StrategyConfigJson) // 按策略配置JSON分组
                .Select(g => new StrategyEffectivenessStats
                {
                    PersonnelStrategy = ExtractPersonnelStrategyFromJson(g.Key),
                    EquipmentStrategy = ExtractEquipmentStrategyFromJson(g.Key),
                    UsageCount = g.Count(),
                    AverageSuccessRate = CalculateGroupSuccessRate(g.ToList()),
                    AveragePersonnelFairnessScore = Math.Round((decimal)g.Average(r => r.PersonnelFairnessScore), 1),
                    AverageEquipmentUtilizationRate = Math.Round(g.Average(r => r.EquipmentUtilizationRate), 1),
                    AverageElapsedTime = (long)g.Average(r => r.ElapsedMilliseconds)
                })
                .OrderByDescending(s => s.UsageCount)
                .ToList();

            return strategyGroups;
        }

        /// <summary>
        /// 获取整合性能趋势数据
        /// 生成性能趋势图表数据，支持性能监控
        /// </summary>
        public async Task<List<IntegrationPerformanceTrend>> GetPerformanceTrendAsync(int days = 30)
        {
            var startDate = DateTime.Today.AddDays(-days + 1);
            var endDate = DateTime.Today.AddDays(1);

            var records = await Select
                .Where(r => r.IntegrationTime >= startDate && r.IntegrationTime < endDate)
                .Where(r => !r.IsTestData)
                .ToListAsync();

            var trends = records
                .GroupBy(r => r.IntegrationTime.Date)
                .Select(g => new IntegrationPerformanceTrend
                {
                    Date = g.Key,
                    IntegrationCount = g.Count(),
                    AverageSuccessRate = CalculateGroupSuccessRate(g.ToList()),
                    AverageElapsedTime = (long)g.Average(r => r.ElapsedMilliseconds),
                    TotalTasks = g.Sum(r => r.SuccessTaskCount + r.FailedTaskCount)
                })
                .OrderBy(t => t.Date)
                .ToList();

            // 填充没有数据的日期
            var allDates = Enumerable.Range(0, days)
                .Select(i => startDate.AddDays(i))
                .ToList();

            var completeTrends = allDates
                .Select(date => trends.FirstOrDefault(t => t.Date == date) ?? new IntegrationPerformanceTrend
                {
                    Date = date,
                    IntegrationCount = 0,
                    AverageSuccessRate = 0,
                    AverageElapsedTime = 0,
                    TotalTasks = 0
                })
                .ToList();

            return completeTrends;
        }

        #endregion

        #region 业务专用方法

        /// <summary>
        /// 检查批次编码是否已存在
        /// 利用唯一索引快速查询
        /// </summary>
        public async Task<bool> BatchCodeExistsAsync(string batchCode)
        {
            if (string.IsNullOrWhiteSpace(batchCode))
                return false;

            return await Select
                .Where(r => r.IntegrationBatchCode == batchCode)
                .AnyAsync();
        }

        /// <summary>
        /// 获取最近的整合记录
        /// 支持监控面板和快速状态查看
        /// </summary>
        public async Task<List<IntegrationRecordEntity>> GetRecentRecordsAsync(int count = 10)
        {
            return await Select
                .Where(r => !r.IsTestData)
                .OrderByDescending(r => r.IntegrationTime)
                .Take(count)
                .ToListAsync();
        }

        /// <summary>
        /// 获取失败率高的整合记录
        /// 支持质量监控和问题识别
        /// </summary>
        public async Task<List<IntegrationRecordEntity>> GetHighFailureRateRecordsAsync(
            decimal minFailureRate, 
            DateTime startTime, 
            DateTime endTime, 
            int count = 50)
        {
            return await Select
                .Where(r => r.IntegrationTime >= startTime && r.IntegrationTime <= endTime)
                .Where(r => !r.IsTestData)
                .Where(r => r.SuccessTaskCount + r.FailedTaskCount > 0) // 确保有任务数据
                .ToListAsync()
                .ContinueWith(task =>
                {
                    var records = task.Result;
                    return records
                        .Where(r =>
                        {
                            var totalTasks = r.SuccessTaskCount + r.FailedTaskCount;
                            var failureRate = totalTasks > 0 ? (decimal)r.FailedTaskCount / totalTasks * 100 : 0;
                            return failureRate >= minFailureRate;
                        })
                        .OrderByDescending(r => (decimal)r.FailedTaskCount / (r.SuccessTaskCount + r.FailedTaskCount))
                        .Take(count)
                        .ToList();
                });
        }

        /// <summary>
        /// 软删除过期的测试数据
        /// 定期数据清理，保持系统性能
        /// </summary>
        public async Task<int> SoftDeleteExpiredTestDataAsync(DateTime beforeDate)
        {
            var expiredRecords = await Select
                .Where(r => r.IsTestData && r.CreatedTime < beforeDate)
                .Where(r => !r.IsDeleted)
                .ToListAsync();

            if (!expiredRecords.Any())
                return 0;

            // 批量软删除
            var deletedCount = await UpdateDiy
                .Set(r => r.IsDeleted, true)
                .Set(r => r.ModifiedTime, DateTime.Now)
                .Where(r => expiredRecords.Select(er => er.Id).Contains(r.Id))
                .ExecuteAffrowsAsync();

            return deletedCount;
        }

        #endregion

        #region 私有辅助方法

        /// <summary>
        /// 从策略JSON中提取人员策略
        /// </summary>
        private string ExtractPersonnelStrategyFromJson(string strategyConfigJson)
        {
            try
            {
                if (string.IsNullOrWhiteSpace(strategyConfigJson))
                    return "未知";

                using var document = System.Text.Json.JsonDocument.Parse(strategyConfigJson);
                var root = document.RootElement;

                if (root.TryGetProperty("PersonnelStrategy", out var personnelStrategyProp))
                {
                    return personnelStrategyProp.GetString() ?? "未知";
                }

                return "未知";
            }
            catch
            {
                return "未知";
            }
        }

        /// <summary>
        /// 从策略JSON中提取设备策略
        /// </summary>
        private string ExtractEquipmentStrategyFromJson(string strategyConfigJson)
        {
            try
            {
                if (string.IsNullOrWhiteSpace(strategyConfigJson))
                    return "未知";

                using var document = System.Text.Json.JsonDocument.Parse(strategyConfigJson);
                var root = document.RootElement;

                if (root.TryGetProperty("EquipmentStrategy", out var equipmentStrategyProp))
                {
                    return equipmentStrategyProp.GetString() ?? "未知";
                }

                return "未知";
            }
            catch
            {
                return "未知";
            }
        }

        /// <summary>
        /// 计算分组的平均成功率
        /// </summary>
        private decimal CalculateGroupSuccessRate(List<IntegrationRecordEntity> records)
        {
            if (!records.Any())
                return 0;

            var totalTasks = records.Sum(r => r.SuccessTaskCount + r.FailedTaskCount);
            var successfulTasks = records.Sum(r => r.SuccessTaskCount);

            return totalTasks > 0 ? Math.Round((decimal)successfulTasks / totalTasks * 100, 2) : 0;
        }

        #endregion
    }
}