using Microsoft.EntityFrameworkCore;
using MilitaryTrainingManagement.Data;
using MilitaryTrainingManagement.Models.DTOs;
using MilitaryTrainingManagement.Models.Entities;
using MilitaryTrainingManagement.Services.Interfaces;

namespace MilitaryTrainingManagement.Services.Implementations;

/// <summary>
/// 数据汇总服务实现
/// 需求：3.4, 3.5, 4.1, 4.2
/// </summary>
public class DataAggregatorService : IDataAggregatorService
{
    private readonly ApplicationDbContext _context;
    private readonly IOrganizationService _organizationService;

    public DataAggregatorService(ApplicationDbContext context, IOrganizationService organizationService)
    {
        _context = context;
        _organizationService = organizationService;
    }

    /// <summary>
    /// 汇总指定单位及其下级的所有分配数据
    /// </summary>
    public async Task<IEnumerable<AllocationDistribution>> AggregateDistributionsAsync(int unitId)
    {
        var subordinateIds = await _organizationService.GetAllSubordinateIdsAsync(unitId);
        var allUnitIds = subordinateIds.ToList();
        allUnitIds.Add(unitId);

        return await _context.AllocationDistributions
            .Include(d => d.Allocation)
            .Include(d => d.TargetUnit)
            .Include(d => d.ReportedByUser)
            .Where(d => allUnitIds.Contains(d.TargetUnitId))
            .ToListAsync();
    }

    /// <summary>
    /// 计算层级汇总数据
    /// 需求4.1：显示所有下级单位的总配额、实际完成和整体完成率
    /// </summary>
    public async Task<HierarchicalAggregatedResponse> CalculateHierarchicalAggregationAsync(int unitId)
    {
        var unit = await _organizationService.GetByIdAsync(unitId);
        if (unit == null)
            throw new ArgumentException("组织单位不存在");

        var distributions = await AggregateDistributionsAsync(unitId);
        var distributionList = distributions.ToList();

        // 按配额分组汇总
        var allocationGroups = distributionList
            .GroupBy(d => d.AllocationId)
            .Select(g => new AllocationAggregation
            {
                AllocationId = g.Key,
                Category = g.First().Allocation?.Category ?? string.Empty,
                MaterialName = g.First().Allocation?.MaterialName ?? string.Empty,
                Unit = g.First().Allocation?.Unit ?? string.Empty,
                TotalQuota = SumTotalQuota(g),
                TotalActualCompletion = SumTotalActualCompletion(g),
                CompletionRate = CalculateOverallCompletionRate(
                    SumTotalQuota(g),
                    SumTotalActualCompletion(g))
            })
            .ToList();

        // 获取直接下级单位汇总
        var subordinateSummaries = await GetDirectSubordinateSummariesAsync(unitId);

        var totalQuota = SumTotalQuota(distributionList);
        var totalActualCompletion = SumTotalActualCompletion(distributionList);

        return new HierarchicalAggregatedResponse
        {
            UnitId = unit.Id,
            UnitName = unit.Name,
            UnitLevel = unit.Level.ToString(),
            TotalQuota = totalQuota,
            TotalActualCompletion = totalActualCompletion,
            OverallCompletionRate = CalculateOverallCompletionRate(totalQuota, totalActualCompletion),
            AllocationAggregations = allocationGroups,
            SubordinateSummaries = subordinateSummaries.ToList()
        };
    }

    /// <summary>
    /// 按配额分组汇总数据
    /// </summary>
    public async Task<IEnumerable<AggregatedReportResponse>> AggregateByAllocationAsync(int unitId)
    {
        var distributions = await AggregateDistributionsAsync(unitId);
        var distributionList = distributions.ToList();

        return distributionList
            .GroupBy(d => d.AllocationId)
            .Select(g =>
            {
                var allocation = g.First().Allocation;
                var totalQuota = SumTotalQuota(g);
                var totalActualCompletion = SumTotalActualCompletion(g);

                return new AggregatedReportResponse
                {
                    AllocationId = g.Key,
                    Category = allocation?.Category ?? string.Empty,
                    MaterialName = allocation?.MaterialName ?? string.Empty,
                    Unit = allocation?.Unit ?? string.Empty,
                    TotalQuota = totalQuota,
                    TotalActualCompletion = totalActualCompletion,
                    OverallCompletionRate = CalculateOverallCompletionRate(totalQuota, totalActualCompletion),
                    UnitSummaries = g.Select(d => new UnitReportSummary
                    {
                        UnitId = d.TargetUnitId,
                        UnitName = d.TargetUnit?.Name ?? string.Empty,
                        UnitLevel = d.TargetUnit?.Level.ToString() ?? string.Empty,
                        UnitQuota = d.UnitQuota,
                        ActualCompletion = d.ActualCompletion,
                        CompletionRate = d.CompletionRate,
                        ReportedAt = d.ReportedAt,
                        ReportedByUserName = d.ReportedByUser?.DisplayName
                    }).ToList()
                };
            })
            .ToList();
    }

    /// <summary>
    /// 获取直接下级单位汇总
    /// 需求4.2：显示直接下级单位的详细配额、实际完成和完成率数据
    /// </summary>
    public async Task<IEnumerable<SubordinateUnitSummary>> GetDirectSubordinateSummariesAsync(int unitId)
    {
        var unit = await _context.OrganizationalUnits
            .Include(u => u.Children)
            .FirstOrDefaultAsync(u => u.Id == unitId);

        if (unit == null)
            return Enumerable.Empty<SubordinateUnitSummary>();

        var summaries = new List<SubordinateUnitSummary>();

        foreach (var child in unit.Children)
        {
            // 获取该下级单位及其所有下级的分配数据
            var childDistributions = await AggregateDistributionsAsync(child.Id);
            var childDistributionList = childDistributions.ToList();

            var totalQuota = SumTotalQuota(childDistributionList);
            var totalActualCompletion = SumTotalActualCompletion(childDistributionList);

            summaries.Add(new SubordinateUnitSummary
            {
                UnitId = child.Id,
                UnitName = child.Name,
                UnitLevel = child.Level.ToString(),
                TotalQuota = totalQuota,
                TotalActualCompletion = totalActualCompletion,
                CompletionRate = CalculateOverallCompletionRate(totalQuota, totalActualCompletion)
            });
        }

        return summaries;
    }

    /// <summary>
    /// 汇总单位的总配额
    /// </summary>
    public decimal SumTotalQuota(IEnumerable<AllocationDistribution> distributions)
    {
        return distributions.Sum(d => d.UnitQuota);
    }

    /// <summary>
    /// 汇总单位的总实际完成
    /// </summary>
    public decimal SumTotalActualCompletion(IEnumerable<AllocationDistribution> distributions)
    {
        return distributions.Sum(d => d.ActualCompletion ?? 0);
    }

    /// <summary>
    /// 计算整体完成率
    /// </summary>
    public decimal CalculateOverallCompletionRate(decimal totalQuota, decimal totalActualCompletion)
    {
        if (totalQuota <= 0)
            return 0;

        return totalActualCompletion / totalQuota;
    }

    /// <summary>
    /// 验证汇总数据一致性
    /// 属性4：层级数据汇总 - 显示的汇总数据应等于所有直接下级单位数据的总和
    /// </summary>
    public bool ValidateAggregationConsistency(
        decimal parentTotalQuota,
        decimal parentTotalActualCompletion,
        IEnumerable<SubordinateUnitSummary> subordinateSummaries)
    {
        var summaryList = subordinateSummaries.ToList();
        
        // 如果没有下级单位，则父级数据应该是自己的数据（或为0）
        if (!summaryList.Any())
            return true;

        var subordinateTotalQuota = summaryList.Sum(s => s.TotalQuota);
        var subordinateTotalActualCompletion = summaryList.Sum(s => s.TotalActualCompletion);

        // 父级汇总应等于所有下级单位数据的总和
        return parentTotalQuota == subordinateTotalQuota &&
               parentTotalActualCompletion == subordinateTotalActualCompletion;
    }
}
