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

namespace MilitaryTrainingManagement.Services.Implementations;

/// <summary>
/// 上报服务实现
/// 需求：3.1, 3.2, 3.3, 3.4, 3.5, 4.1, 4.2, 4.3
/// </summary>
public class ReportingService : IReportingService
{
    private readonly ApplicationDbContext _context;
    private readonly IOrganizationService _organizationService;

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

    /// <summary>
    /// 根据ID获取分配记录
    /// </summary>
    public async Task<AllocationDistribution?> GetDistributionByIdAsync(int id)
    {
        return await _context.AllocationDistributions
            .Include(d => d.Allocation)
            .Include(d => d.TargetUnit)
            .Include(d => d.ReportedByUser)
            .FirstOrDefaultAsync(d => d.Id == id);
    }

    /// <summary>
    /// 获取单位的分配记录
    /// 需求3.1：显示类别、物资名称、单位、配额、实际完成和完成率
    /// </summary>
    public async Task<IEnumerable<AllocationDistribution>> GetDistributionsByUnitAsync(int unitId)
    {
        return await _context.AllocationDistributions
            .Include(d => d.Allocation)
            .Include(d => d.TargetUnit)
            .Include(d => d.ReportedByUser)
            .Where(d => d.TargetUnitId == unitId)
            .ToListAsync();
    }

    /// <summary>
    /// 提交上报数据
    /// 需求3.2：允许团级用户输入实际完成值并提交
    /// </summary>
    public async Task<AllocationDistribution> SubmitReportAsync(int distributionId, decimal actualCompletion, int reportedByUserId)
    {
        if (actualCompletion < 0)
            throw new ArgumentException("实际完成数量不能为负数");

        var distribution = await _context.AllocationDistributions
            .Include(d => d.TargetUnit)
            .FirstOrDefaultAsync(d => d.Id == distributionId);

        if (distribution == null)
            throw new ArgumentException("分配记录不存在");

        // 验证上报用户是否属于目标单位或其上级
        var user = await _context.UserAccounts
            .Include(u => u.OrganizationalUnit)
            .FirstOrDefaultAsync(u => u.Id == reportedByUserId);
        if (user == null)
            throw new ArgumentException("用户不存在");

        var userLevel = user.OrganizationalUnit?.Level ?? OrganizationalLevel.Company;
        var canReport = await CanViewUnitDataAsync(user.OrganizationalUnitId, distribution.TargetUnitId, userLevel);
        if (!canReport)
            throw new UnauthorizedAccessException("无权限为该单位提交上报");

        distribution.ActualCompletion = actualCompletion;
        distribution.ReportedAt = DateTime.UtcNow;
        distribution.ReportedByUserId = reportedByUserId;

        await _context.SaveChangesAsync();
        return distribution;
    }

    /// <summary>
    /// 计算完成率
    /// 需求3.3：完成率 = 实际完成 / 配额
    /// </summary>
    public async Task<decimal> CalculateCompletionRateAsync(int distributionId)
    {
        var distribution = await _context.AllocationDistributions.FindAsync(distributionId);
        if (distribution == null)
            return 0;

        return CalculateCompletionRate(distribution.ActualCompletion, distribution.UnitQuota);
    }

    /// <summary>
    /// 计算完成率（纯函数版本）
    /// 需求3.3：完成率 = 实际完成 / 配额
    /// </summary>
    public decimal CalculateCompletionRate(decimal? actualCompletion, decimal unitQuota)
    {
        if (unitQuota <= 0 || !actualCompletion.HasValue)
            return 0;

        return actualCompletion.Value / unitQuota;
    }

    /// <summary>
    /// 获取汇总数据（包含下级单位，应用可见性过滤）
    /// 需求3.4, 4.1：显示下级单位的汇总信息
    /// 需求2.2：对营部及以下级别用户应用可见性过滤
    /// </summary>
    public async Task<IEnumerable<AllocationDistribution>> GetAggregatedDataAsync(int unitId, OrganizationalLevel userLevel)
    {
        var visibleUnitIds = await _organizationService.GetVisibleUnitIdsAsync(unitId, userLevel);
        var allUnitIds = visibleUnitIds.ToList();

        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, 4.2：显示总配额、实际完成和整体完成率
    /// </summary>
    public async Task<HierarchicalAggregatedResponse> GetHierarchicalAggregatedDataAsync(int unitId)
    {
        var unit = await _organizationService.GetByIdAsync(unitId);
        if (unit == null)
            throw new ArgumentException("组织单位不存在");

        // 使用单位自身的层级来确定可见性
        return await GetHierarchicalAggregatedDataAsync(unitId, unit.Level);
    }

    /// <summary>
    /// 获取层级汇总数据（应用可见性过滤）
    /// 需求4.1, 4.2：显示总配额、实际完成和整体完成率
    /// 需求2.2：对营部及以下级别用户应用可见性过滤
    /// </summary>
    public async Task<HierarchicalAggregatedResponse> GetHierarchicalAggregatedDataAsync(int unitId, OrganizationalLevel userLevel)
    {
        var unit = await _organizationService.GetByIdAsync(unitId);
        if (unit == null)
            throw new ArgumentException("组织单位不存在");

        var distributions = await GetAggregatedDataAsync(unitId, userLevel);
        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 = g.Sum(d => d.UnitQuota),
                TotalActualCompletion = g.Sum(d => d.ActualCompletion ?? 0),
                CompletionRate = g.Sum(d => d.UnitQuota) > 0
                    ? g.Sum(d => d.ActualCompletion ?? 0) / g.Sum(d => d.UnitQuota)
                    : 0
            })
            .ToList();

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

        var totalQuota = distributionList.Sum(d => d.UnitQuota);
        var totalActualCompletion = distributionList.Sum(d => d.ActualCompletion ?? 0);

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

    /// <summary>
    /// 获取按配额分组的汇总数据
    /// 需求4.1：显示所有下级单位的总配额、实际完成和整体完成率
    /// </summary>
    public async Task<IEnumerable<AggregatedReportResponse>> GetAggregatedByAllocationAsync(int unitId)
    {
        // 获取单位信息以确定可见性
        var unit = await _organizationService.GetByIdAsync(unitId);
        var userLevel = unit?.Level ?? OrganizationalLevel.Division;
        
        var distributions = await GetAggregatedDataAsync(unitId, userLevel);
        var distributionList = distributions.ToList();

        return distributionList
            .GroupBy(d => d.AllocationId)
            .Select(g =>
            {
                var allocation = g.First().Allocation;
                var totalQuota = g.Sum(d => d.UnitQuota);
                var totalActualCompletion = g.Sum(d => d.ActualCompletion ?? 0);

                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 = totalQuota > 0 ? totalActualCompletion / totalQuota : 0,
                    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 childSubordinateIds = await _organizationService.GetAllSubordinateIdsAsync(child.Id);
            var allChildUnitIds = childSubordinateIds.ToList();
            allChildUnitIds.Add(child.Id);

            var childDistributions = await _context.AllocationDistributions
                .Where(d => allChildUnitIds.Contains(d.TargetUnitId))
                .ToListAsync();

            var totalQuota = childDistributions.Sum(d => d.UnitQuota);
            var totalActualCompletion = childDistributions.Sum(d => d.ActualCompletion ?? 0);

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

        return summaries;
    }

    /// <summary>
    /// 检查用户是否有权限查看指定单位的数据
    /// 需求4.4, 8.1, 8.2：基于组织层级的数据访问控制
    /// 需求2.3：使用可见性范围检查
    /// </summary>
    public async Task<bool> CanViewUnitDataAsync(int userUnitId, int targetUnitId, OrganizationalLevel userLevel)
    {
        // 获取用户可见的单位ID列表
        var visibleUnitIds = await _organizationService.GetVisibleUnitIdsAsync(userUnitId, userLevel);
        
        // 检查目标单位是否在可见范围内
        return visibleUnitIds.Contains(targetUnitId);
    }

    /// <summary>
    /// 获取详细上报记录
    /// 需求4.3：提供具体上报记录的访问，包括时间戳和上报人员
    /// 需求2.1：对营部及以下级别用户应用可见性过滤
    /// </summary>
    public async Task<IEnumerable<ReportResponse>> GetDetailedReportsAsync(int unitId, OrganizationalLevel userLevel)
    {
        var distributions = await GetAggregatedDataAsync(unitId, userLevel);

        return distributions.Select(d => new ReportResponse
        {
            Id = d.Id,
            AllocationId = d.AllocationId,
            Category = d.Allocation?.Category ?? string.Empty,
            MaterialName = d.Allocation?.MaterialName ?? string.Empty,
            Unit = d.Allocation?.Unit ?? string.Empty,
            TargetUnitId = d.TargetUnitId,
            TargetUnitName = d.TargetUnit?.Name ?? string.Empty,
            UnitQuota = d.UnitQuota,
            ActualCompletion = d.ActualCompletion,
            CompletionRate = d.CompletionRate,
            ReportedAt = d.ReportedAt,
            ReportedByUserId = d.ReportedByUserId,
            ReportedByUserName = d.ReportedByUser?.DisplayName
        });
    }
}
