using MilitaryTrainingManagement.Models.Entities;
using MilitaryTrainingManagement.Models.Enums;

namespace MilitaryTrainingManagement.Services.Interfaces;

/// <summary>
/// 物资配额服务接口
/// </summary>
public interface IAllocationService
{
    /// <summary>
    /// 根据ID获取物资配额
    /// </summary>
    Task<MaterialAllocation?> GetByIdAsync(int id);

    /// <summary>
    /// 获取所有物资配额
    /// </summary>
    Task<IEnumerable<MaterialAllocation>> GetAllAsync();

    /// <summary>
    /// 获取指定单位创建的物资配额
    /// </summary>
    Task<IEnumerable<MaterialAllocation>> GetByUnitAsync(int unitId);

    /// <summary>
    /// 获取指定单位可见的物资配额（包括分配给该单位及其下级单位的配额）
    /// </summary>
    Task<IEnumerable<MaterialAllocation>> GetVisibleToUnitAsync(int unitId);

    /// <summary>
    /// 获取分配给指定单位的配额分配记录
    /// </summary>
    Task<IEnumerable<AllocationDistribution>> GetDistributionsForUnitAsync(int unitId);

    /// <summary>
    /// 根据ID获取配额分配记录
    /// </summary>
    Task<AllocationDistribution?> GetDistributionByIdAsync(int id);

    /// <summary>
    /// 创建物资配额并自动分发给目标单位
    /// </summary>
    Task<MaterialAllocation> CreateAsync(string category, string materialName, string unit, decimal totalQuota, int createdByUnitId, Dictionary<int, decimal> distributions);

    /// <summary>
    /// 更新物资配额基本信息
    /// </summary>
    Task<MaterialAllocation> UpdateAsync(int id, string category, string materialName, string unit, decimal totalQuota);

    /// <summary>
    /// 更新配额分配记录
    /// </summary>
    Task<MaterialAllocation> UpdateDistributionsAsync(int allocationId, Dictionary<int, decimal> distributions);

    /// <summary>
    /// 更新单个分配记录的实际完成数量(上报消耗)
    /// </summary>
    Task<AllocationDistribution> UpdateDistributionCompletionAsync(int distributionId, int unitId, int userId, decimal actualCompletion, string? remarks = null);

    /// <summary>
    /// 删除物资配额
    /// </summary>
    Task DeleteAsync(int id);

    /// <summary>
    /// 验证分配配额总和是否不超过总配额
    /// </summary>
    Task<bool> ValidateDistributionQuotasAsync(decimal totalQuota, Dictionary<int, decimal> distributions);

    /// <summary>
    /// 验证目标单位是否存在
    /// </summary>
    Task<bool> ValidateTargetUnitsExistAsync(IEnumerable<int> targetUnitIds);

    /// <summary>
    /// 获取配额分配的上报历史记录
    /// </summary>
    Task<IEnumerable<ConsumptionReport>> GetConsumptionReportsAsync(int distributionId);

    /// <summary>
    /// 获取配额分配的上报历史记录（带可见性过滤）
    /// 只返回用户可见范围内的单位的上报记录
    /// </summary>
    Task<IEnumerable<ConsumptionReport>> GetConsumptionReportsAsync(int distributionId, int userUnitId, OrganizationalLevel userLevel);

    /// <summary>
    /// 检查用户是否有权限查看指定单位的配额分配记录
    /// 使用可见性过滤：营部及以下级别只能查看本单位及直接下级
    /// </summary>
    Task<bool> CanViewDistributionAsync(int userUnitId, OrganizationalLevel userLevel, int targetUnitId);

    /// <summary>
    /// 获取用户可见范围内的上报总和
    /// 营部及以下级别：只计算本单位及直接下级的上报
    /// </summary>
    Task<decimal> GetVisibleActualCompletionAsync(int allocationId, int userUnitId, OrganizationalLevel userLevel);

    /// <summary>
    /// 获取按单位汇总的上报数据（带可见性过滤）
    /// </summary>
    Task<IEnumerable<Models.DTOs.UnitReportSummary>> GetReportSummaryByUnitAsync(int distributionId, int userUnitId, OrganizationalLevel userLevel, DateTime? startDate = null, DateTime? endDate = null);

    /// <summary>
    /// 获取配额的消耗统计（按时间范围）
    /// </summary>
    Task<IEnumerable<Models.DTOs.UnitConsumptionStat>> GetConsumptionStatsByPeriodAsync(int allocationId, DateTime startDate, DateTime endDate);
}
