using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using System.Text.Json;
using Microsoft.AspNetCore.Mvc;
using Microsoft.Extensions.Logging;
using ZhonTai.Admin.Core.Dto;
using ZhonTai.Admin.Services;
using ZhonTai.DynamicApi;
using ZhonTai.DynamicApi.Attributes;
using NPP.SmartSchedue.Api.Contracts.Services.Notification;
using NPP.SmartSchedue.Api.Contracts.Services.Notification.Input;
using NPP.SmartSchedue.Api.Contracts.Services.Notification.Output;
using NPP.SmartSchedue.Api.Contracts.Domain.Notification;
using NPP.SmartSchedue.Api.Repositories.Notification;
using NPP.SmartSchedue.Api.Contracts.Core.Enums;
using NPP.SmartSchedue.Api.Core.Consts;
using ZhonTai.Admin.Core.GrpcServices;
using ZhonTai.Admin.Core.GrpcServices.Dtos;

namespace NPP.SmartSchedue.Api.Services.Notification;

/// <summary>
/// 通知服务
/// </summary>
[DynamicApi(Area = "app")]
public class NotificationService : BaseService, INotificationService, IDynamicApi
{
    private readonly NotificationSettingRepository _notificationSettingRepository;
    private readonly PersonnelGroupRepository _personnelGroupRepository;
    private readonly NotificationHistoryRepository _notificationHistoryRepository;
    private readonly IEmailNotificationService _emailNotificationService;
    private readonly ISystemMessageService _systemMessageService;
    private readonly INotificationTemplateService _templateService;
    private readonly IUserGrpcService  _userService;
    private readonly ILogger<NotificationService> _logger;
  
    public NotificationService(
        NotificationSettingRepository notificationSettingRepository,
        PersonnelGroupRepository personnelGroupRepository,
        NotificationHistoryRepository notificationHistoryRepository,
        IEmailNotificationService emailNotificationService,
        ISystemMessageService systemMessageService,
        INotificationTemplateService templateService,
        IUserGrpcService userService,
        ILogger<NotificationService> logger)
    {
        _notificationSettingRepository = notificationSettingRepository;
        _personnelGroupRepository = personnelGroupRepository;
        _notificationHistoryRepository = notificationHistoryRepository;
        _emailNotificationService = emailNotificationService;
        _systemMessageService = systemMessageService;
        _templateService = templateService;
        _userService = userService;
        _logger = logger;
    }

    #region 通知设置管理

    /// <summary>
    /// 获取通知设置列表（可选过滤，含缓存）
    /// </summary>
    [HttpGet]
    public async Task<List<NotificationSettingOutput>> GetNotificationSettingListAsync(bool? isEnabled = null, long? personnelGroupId = null)
    {
        var cacheKey = $"{CacheKeys.NotificationSettingsKey}:all";
        
       var cachedList = await Cache.GetAsync<List<NotificationSettingOutput>>(cacheKey);
       if ( cachedList != null && cachedList.Any())
       {
           return cachedList;
       }

       var query = _notificationSettingRepository.Select.Include(a => a.PersonnelGroup);
        if (isEnabled != null)
        {
            query = query.Where(a => a.IsEnabled == isEnabled);
        }
        if (personnelGroupId.HasValue && personnelGroupId.Value > 0)
        {
            query = query.Where(a => a.PersonnelGroupId == personnelGroupId.Value);
        }

        var entities = await query.OrderByDescending(a => a.CreatedTime).ToListAsync();
        var outputs = entities.Select(MapToNotificationSettingOutput).ToList();

        Cache.Set(cacheKey, outputs, TimeSpan.FromHours(12));
        return outputs;
    }

    /// <summary>
    /// 查询通知设置
    /// </summary>
    [HttpGet]
    public async Task<NotificationSettingOutput> GetNotificationSettingAsync(long id)
    {
        _logger.LogInformation("开始查询通知设置，ID：{Id}", id);

        var entity = await _notificationSettingRepository.Select
            .WhereDynamic(id)
            .Include(a => a.PersonnelGroup)
            .ToOneAsync();

        if (entity == null)
        {
            _logger.LogWarning("通知设置不存在，ID：{Id}", id);
            throw new Exception($"通知设置不存在，ID：{id}");
        }

        var output = MapToNotificationSettingOutput(entity);
        _logger.LogInformation("成功查询通知设置，ID：{Id}", id);
        return output;
    }



    /// <summary>
    /// 查询通知设置分页
    /// </summary>
    [HttpPost]
    public async Task<PageOutput<NotificationSettingOutput>> GetNotificationSettingPageAsync(PageInput<NotificationSettingPageInput> input)
    {
        _logger.LogInformation("开始查询通知设置分页，页码：{Current}，页大小：{Size}", input.CurrentPage, input.PageSize);

        var query = _notificationSettingRepository.Select
            .Include(a => a.PersonnelGroup);

        // 根据搜索条件过滤
        if (!string.IsNullOrEmpty(input.Filter?.NotificationName))
        {
            query = query.Where(a => a.NotificationName.Contains(input.Filter.NotificationName));
        }

        if (input.Filter?.IsEnabled != null)
        {
            query = query.Where(a => a.IsEnabled == input.Filter.IsEnabled);
        }

        if (input.Filter?.PersonnelGroupId != null && input.Filter.PersonnelGroupId > 0)
        {
            query = query.Where(a => a.PersonnelGroupId == input.Filter.PersonnelGroupId);
        }

        var totalCount = await query.CountAsync();
        var entities = await query
            .OrderByDescending(a => a.CreatedTime)
            .Page(input.CurrentPage, input.PageSize)
            .ToListAsync();

        var outputs = entities.Select(MapToNotificationSettingOutput).ToList();

        _logger.LogInformation("成功查询通知设置分页，总数：{Total}，当前页数据：{Count}", totalCount, outputs.Count);
        return new PageOutput<NotificationSettingOutput>
        {
            List = outputs,
            Total = totalCount
        };
    }

    /// <summary>
    /// 创建通知设置
    /// </summary>
    [HttpPost]
    public async Task<long> CreateNotificationSettingAsync(NotificationSettingCreateInput input)
    {
        _logger.LogInformation("开始创建通知设置：{NotificationName}", input.NotificationName);

        // 业务验证：检查通知设置名称是否已存在
        var exists = await _notificationSettingRepository.ExistsNotificationNameAsync(input.NotificationName);
        if (exists)
        {
            _logger.LogWarning("通知设置名称已存在：{NotificationName}", input.NotificationName);
            throw new Exception($"通知设置名称已存在：{input.NotificationName}");
        }

        // 验证人员组是否存在
        var personnelGroup = await _personnelGroupRepository.GetAsync(input.PersonnelGroupId);
        if (personnelGroup == null)
        {
            _logger.LogWarning("人员组不存在，ID：{PersonnelGroupId}", input.PersonnelGroupId);
            throw new Exception($"人员组不存在，ID：{input.PersonnelGroupId}");
        }

        // 业务验证：时间配置合法性检查
        ValidateTimeConfiguration(input.StartTime, input.EndTime);

        // 业务验证：频次配置合法性检查
        ValidateFrequencyConfiguration(input.FrequencyType, input.IntervalMinutes);

        // 业务验证：模板配置合法性检查
        await ValidateTemplateConfiguration(input);

        var entity = new NotificationSettingEntity
        {
            NotificationName = input.NotificationName,
            Description = input.Description,
            IsEnabled = input.IsEnabled,
            StartTime = input.StartTime,
            EndTime = input.EndTime,
            FrequencyType = (int)input.FrequencyType,
            IntervalMinutes = input.IntervalMinutes,
            PersonnelGroupId = input.PersonnelGroupId,
            EmailSubjectTemplate = input.EmailSubjectTemplate,
            EmailContentTemplate = input.EmailContentTemplate,
            SystemMessageTitleTemplate = input.SystemMessageTitleTemplate,
            SystemMessageContentTemplate = input.SystemMessageContentTemplate,
            TriggerConditions = input.TriggerConditions,
            LastModifiedTime = DateTime.Now
        };

        // 设置通知方式
        entity.IsEmailEnabled = input.IsEmailEnabled;
        entity.IsSystemMessageEnabled = input.IsSystemMessageEnabled;

        entity = await _notificationSettingRepository.InsertAsync(entity);
        _logger.LogInformation("成功创建通知设置，ID：{Id}，名称：{NotificationName}", entity.Id, entity.NotificationName);
        
        var cacheKey = $"{CacheKeys.NotificationSettingsKey}:all";
        await ClearNotificationSettingCache();
        
        return entity.Id;
    }

    /// <summary>
    /// 更新通知设置
    /// </summary>
    [HttpPut]
    public async Task UpdateNotificationSettingAsync(NotificationSettingUpdateInput input)
    {
        _logger.LogInformation("开始更新通知设置，ID：{Id}", input.Id);

        var entity = await _notificationSettingRepository.GetAsync(input.Id);
        if (entity == null)
        {
            _logger.LogWarning("通知设置不存在，ID：{Id}", input.Id);
            throw new Exception($"通知设置不存在，ID：{input.Id}");
        }

        // 业务验证：检查通知设置名称是否已存在（排除自己）
        var exists = await _notificationSettingRepository.ExistsNotificationNameAsync(input.NotificationName, input.Id);
        if (exists)
        {
            _logger.LogWarning("通知设置名称已存在：{NotificationName}", input.NotificationName);
            throw new Exception($"通知设置名称已存在：{input.NotificationName}");
        }

        // 验证人员组是否存在
        var personnelGroup = await _personnelGroupRepository.GetAsync(input.PersonnelGroupId);
        if (personnelGroup == null)
        {
            _logger.LogWarning("人员组不存在，ID：{PersonnelGroupId}", input.PersonnelGroupId);
            throw new Exception($"人员组不存在，ID：{input.PersonnelGroupId}");
        }

        // 业务验证：时间配置合法性检查
        ValidateTimeConfiguration(input.StartTime, input.EndTime);

        // 业务验证：频次配置合法性检查
        ValidateFrequencyConfiguration(input.FrequencyType, input.IntervalMinutes);

        // 业务验证：模板配置合法性检查
        await ValidateTemplateConfiguration(input);

        // 更新实体属性
        entity.NotificationName = input.NotificationName;
        entity.Description = input.Description;
        entity.IsEnabled = input.IsEnabled;
        entity.StartTime = input.StartTime;
        entity.EndTime = input.EndTime;
        entity.FrequencyType = (int)input.FrequencyType;
        entity.IntervalMinutes = input.IntervalMinutes;
        entity.PersonnelGroupId = input.PersonnelGroupId;
        entity.EmailSubjectTemplate = input.EmailSubjectTemplate;
        entity.EmailContentTemplate = input.EmailContentTemplate;
        entity.SystemMessageTitleTemplate = input.SystemMessageTitleTemplate;
        entity.SystemMessageContentTemplate = input.SystemMessageContentTemplate;
        entity.TriggerConditions = input.TriggerConditions;
        entity.LastModifiedTime = DateTime.Now;

        // 设置通知方式
        entity.IsEmailEnabled = input.IsEmailEnabled;
        entity.IsSystemMessageEnabled = input.IsSystemMessageEnabled;

        await _notificationSettingRepository.UpdateAsync(entity);
        _logger.LogInformation("成功更新通知设置，ID：{Id}，名称：{NotificationName}", entity.Id, entity.NotificationName);
        var cacheKey = $"{CacheKeys.NotificationSettingsKey}:all";
        await ClearNotificationSettingCache();
    }

    /// <summary>
    /// 删除通知设置
    /// </summary>
    [HttpDelete]
    public async Task DeleteNotificationSettingAsync(long id)
    {
        _logger.LogInformation("开始删除通知设置，ID：{Id}", id);

        var entity = await _notificationSettingRepository.GetAsync(id);
        if (entity == null)
        {
            _logger.LogWarning("通知设置不存在，ID：{Id}", id);
            throw new Exception($"通知设置不存在，ID：{id}");
        }

        // 业务验证：检查是否存在关联的通知历史记录
        var hasHistory = await _notificationHistoryRepository.Select
            .Where(a => a.NotificationSettingId == id)
            .AnyAsync();

        if (hasHistory)
        {
            _logger.LogWarning("通知设置存在历史记录，无法删除，ID：{Id}", id);
            throw new Exception($"通知设置存在历史记录，无法删除，ID：{id}");
        }

        await _notificationSettingRepository.DeleteAsync(id);
        _logger.LogInformation("成功删除通知设置，ID：{Id}，名称：{NotificationName}", id, entity.NotificationName);
        
        await ClearNotificationSettingCache();
    }

    /// <summary>
    /// 启用/禁用通知设置
    /// </summary>
    [HttpPut]
    public async Task ToggleNotificationSettingAsync(long id, bool enabled)
    {
        _logger.LogInformation("开始{Action}通知设置，ID：{Id}", enabled ? "启用" : "禁用", id);

        var entity = await _notificationSettingRepository.GetAsync(id);
        if (entity == null)
        {
            _logger.LogWarning("通知设置不存在，ID：{Id}", id);
            throw new Exception($"通知设置不存在，ID：{id}");
        }

        entity.IsEnabled = enabled;
        entity.LastModifiedTime = DateTime.Now;

        await _notificationSettingRepository.UpdateAsync(entity);
        _logger.LogInformation("成功{Action}通知设置，ID：{Id}，名称：{NotificationName}", enabled ? "启用" : "禁用", id, entity.NotificationName);

        await ClearNotificationSettingCache();
    }


    /// <summary>
    /// 清除消息配置缓存
    /// </summary>
    private async Task ClearNotificationSettingCache()
    {
        var cacheKey = $"{CacheKeys.NotificationSettingsKey}:all";
        Cache.ExistsAsync(cacheKey);
    }

    #endregion

    #region 人员组管理

    /// <summary>
    /// 查询人员组
    /// </summary>
    [HttpGet]
    public async Task<PersonnelGroupOutput> GetPersonnelGroupAsync(long id)
    {
        _logger.LogInformation("开始查询人员组，ID：{Id}", id);

        var entity = await _personnelGroupRepository.Select
            .WhereDynamic(id)
            .ToOneAsync();

        if (entity == null)
        {
            _logger.LogWarning("人员组不存在，ID：{Id}", id);
            throw new Exception($"人员组不存在，ID：{id}");
        }

        var output = MapToPersonnelGroupOutput(entity);
        
        // 计算实际人员数量
        var actualCount = await GetPersonnelGroupMembersAsync(id);
        output.TotalPersonnelCount = actualCount.Count;

        _logger.LogInformation("成功查询人员组，ID：{Id}，实际人员数量：{Count}", id, output.TotalPersonnelCount);
        return output;
    }

    /// <summary>
    /// 查询人员组分页
    /// </summary>
    [HttpPost]
    public async Task<PageOutput<PersonnelGroupOutput>> GetPersonnelGroupPageAsync(PageInput<PersonnelGroupGetPageInput> input)
    {
        _logger.LogInformation("开始查询人员组分页，页码：{Current}，页大小：{Size}", input.CurrentPage, input.PageSize);

        var query = _personnelGroupRepository.Select;

        // 根据搜索条件过滤
        if (!string.IsNullOrEmpty(input.Filter?.GroupName))
        {
            query = query.Where(a => a.GroupName.Contains(input.Filter.GroupName));
        }

        if (input.Filter?.IsEnabled != null)
        {
            query = query.Where(a => a.IsEnabled == input.Filter.IsEnabled);
        }

        if (input.Filter?.GroupType != null &&  input.Filter?.GroupType != 0)
        {
            query = query.Where(a => a.GroupType == (int)input.Filter.GroupType);
        }

        var totalCount = await query.CountAsync();
        var entities = await query
            .OrderByDescending(a => a.CreatedTime)
            .Page(input.CurrentPage, input.PageSize)
            .ToListAsync();

        var outputs = entities.Select(MapToPersonnelGroupOutput).ToList();

        // 批量计算实际人员数量
        foreach (var output in outputs)
        {
            var actualMembers = await GetPersonnelGroupMembersAsync(output.Id);
            output.TotalPersonnelCount = actualMembers.Count;
        }

        _logger.LogInformation("成功查询人员组分页，总数：{Total}，当前页数据：{Count}", totalCount, outputs.Count);
        return new PageOutput<PersonnelGroupOutput>
        {
            List = outputs,
            Total = totalCount
        };
    }

    /// <summary>
    /// 创建人员组
    /// </summary>
    [HttpPost]
    public async Task<long> CreatePersonnelGroupAsync(PersonnelGroupCreateInput input)
    {
        _logger.LogInformation("开始创建人员组：{GroupName}", input.GroupName);

        // 业务验证：检查人员组名称是否已存在
        var exists = await _personnelGroupRepository.ExistsGroupNameAsync(input.GroupName);
        if (exists)
        {
            _logger.LogWarning("人员组名称已存在：{GroupName}", input.GroupName);
            throw new Exception($"人员组名称已存在：{input.GroupName}");
        }

        // 业务验证：人员组配置合法性检查
        ValidatePersonnelGroupConfiguration(input);

        var entity = new PersonnelGroupEntity
        {
            GroupName = input.GroupName,
            Description = input.Description,
            GroupType = (int)input.GroupType,
            IsEnabled = input.IsEnabled,
            StaticPersonnelIds = JsonSerializer.Serialize(input.StaticPersonnelIds),
            DynamicDepartmentIds = JsonSerializer.Serialize(input.DynamicDepartmentIds),
            DynamicPositions = JsonSerializer.Serialize(input.DynamicPositions),
            OnlyActivePersonnel = input.OnlyActivePersonnel,
            ExcludePersonnelIds = JsonSerializer.Serialize(input.ExcludePersonnelIds),
            LastModifiedTime = DateTime.Now
        };

        entity = await _personnelGroupRepository.InsertAsync(entity);
        _logger.LogInformation("成功创建人员组，ID：{Id}，名称：{GroupName}", entity.Id, entity.GroupName);
        return entity.Id;
    }

    /// <summary>
    /// 更新人员组
    /// </summary>
    [HttpPut]
    public async Task UpdatePersonnelGroupAsync(PersonnelGroupUpdateInput input)
    {
        _logger.LogInformation("开始更新人员组，ID：{Id}", input.Id);

        var entity = await _personnelGroupRepository.GetAsync(input.Id);
        if (entity == null)
        {
            _logger.LogWarning("人员组不存在，ID：{Id}", input.Id);
            throw new Exception($"人员组不存在，ID：{input.Id}");
        }

        // 业务验证：检查人员组名称是否已存在（排除自己）
        var exists = await _personnelGroupRepository.ExistsGroupNameAsync(input.GroupName, input.Id);
        if (exists)
        {
            _logger.LogWarning("人员组名称已存在：{GroupName}", input.GroupName);
            throw new Exception($"人员组名称已存在：{input.GroupName}");
        }

        // 业务验证：人员组配置合法性检查
        ValidatePersonnelGroupConfiguration(input);

        // 更新实体属性
        entity.GroupName = input.GroupName;
        entity.Description = input.Description;
        entity.GroupType = (int)input.GroupType;
        entity.IsEnabled = input.IsEnabled;
        entity.StaticPersonnelIds = JsonSerializer.Serialize(input.StaticPersonnelIds);
        entity.DynamicDepartmentIds = JsonSerializer.Serialize(input.DynamicDepartmentIds);
        entity.DynamicPositions = JsonSerializer.Serialize(input.DynamicPositions);
        entity.OnlyActivePersonnel = input.OnlyActivePersonnel;
        entity.ExcludePersonnelIds = JsonSerializer.Serialize(input.ExcludePersonnelIds);
        entity.LastModifiedTime = DateTime.Now;

        await _personnelGroupRepository.UpdateAsync(entity);
        _logger.LogInformation("成功更新人员组，ID：{Id}，名称：{GroupName}", entity.Id, entity.GroupName);
    }

    /// <summary>
    /// 删除人员组
    /// </summary>
    [HttpDelete]
    public async Task DeletePersonnelGroupAsync(long id)
    {
        _logger.LogInformation("开始删除人员组，ID：{Id}", id);

        var entity = await _personnelGroupRepository.GetAsync(id);
        if (entity == null)
        {
            _logger.LogWarning("人员组不存在，ID：{Id}", id);
            throw new Exception($"人员组不存在，ID：{id}");
        }

        // 业务验证：检查是否存在关联的通知设置
        var hasNotificationSettings = await _notificationSettingRepository.Select
            .Where(a => a.PersonnelGroupId == id)
            .AnyAsync();

        if (hasNotificationSettings)
        {
            _logger.LogWarning("人员组存在关联的通知设置，无法删除，ID：{Id}", id);
            throw new Exception($"人员组存在关联的通知设置，无法删除，ID：{id}");
        }

        await _personnelGroupRepository.DeleteAsync(id);
        _logger.LogInformation("成功删除人员组，ID：{Id}，名称：{GroupName}", id, entity.GroupName);
    }

    /// <summary>
    /// 获取人员组的实际人员列表
    /// 根据决策点4：混合人员组，支持静态+动态规则
    /// </summary>
    [HttpGet]
    public async Task<List<long>> GetPersonnelGroupMembersAsync(long personnelGroupId)
    {
        _logger.LogInformation("开始获取人员组实际人员列表，人员组ID：{PersonnelGroupId}", personnelGroupId);

        var personnelGroup = await _personnelGroupRepository.GetAsync(personnelGroupId);
        if (personnelGroup == null)
        {
            _logger.LogWarning("人员组不存在，ID：{PersonnelGroupId}", personnelGroupId);
            throw new Exception($"人员组不存在，ID：{personnelGroupId}");
        }

        var allPersonnelIds = new HashSet<long>();

        // 获取静态人员
        var staticPersonnelIds = JsonSerializer.Deserialize<List<long>>(personnelGroup.StaticPersonnelIds);
        if (staticPersonnelIds?.Any() == true)
        {
            foreach (var personnelId in staticPersonnelIds)
            {
                allPersonnelIds.Add(personnelId);
            }
            _logger.LogDebug("添加静态人员：{Count}个", staticPersonnelIds.Count);
        }

        // 获取动态人员（根据部门和职位规则）
        var groupType = (PersonnelGroupTypeEnum)personnelGroup.GroupType;
        if (groupType.HasFlag(PersonnelGroupTypeEnum.DynamicByDepartment) || 
            groupType.HasFlag(PersonnelGroupTypeEnum.Mixed))
        {
            var dynamicPersonnelIds = await GetDynamicPersonnelIds(personnelGroup);
            foreach (var personnelId in dynamicPersonnelIds)
            {
                allPersonnelIds.Add(personnelId);
            }
            _logger.LogDebug("添加动态人员：{Count}个", dynamicPersonnelIds.Count);
        }

        // 排除指定人员
        var excludePersonnelIds = JsonSerializer.Deserialize<List<long>>(personnelGroup.ExcludePersonnelIds);
        if (excludePersonnelIds?.Any() == true)
        {
            foreach (var excludeId in excludePersonnelIds)
            {
                allPersonnelIds.Remove(excludeId);
            }
            _logger.LogDebug("排除人员：{Count}个", excludePersonnelIds.Count);
        }

        var result = allPersonnelIds.ToList();
        _logger.LogInformation("成功获取人员组实际人员列表，人员组ID：{PersonnelGroupId}，人员总数：{Count}", personnelGroupId, result.Count);
        return result;
    }

    #endregion

    #region 通知发送

    /// <summary>
    /// 发送通知
    /// 决策点1：支持邮件和系统消息通知
    /// </summary>
    [HttpPost]
    public async Task<SendNotificationOutput> SendNotificationAsync(SendNotificationInput input)
    {
        _logger.LogInformation("开始发送通知，通知方式：{NotificationType}，接收人数：{Count}", 
            input.NotificationType, input.RecipientPersonnelIds.Count);

        var output = new SendNotificationOutput
        {
            TotalCount = input.RecipientPersonnelIds.Count,
            SendTime = DateTime.Now
        };

        // 获取用户信息
        var userInfoDict = await GetUserInfoDictionary(input.RecipientPersonnelIds);

        // 逐个发送通知
        foreach (var personnelId in input.RecipientPersonnelIds)
        {
            var sendResult = new NotificationSendResult
            {
                RecipientPersonnelId = personnelId,
                NotificationType = input.NotificationType
            };

            try
            {
                if (userInfoDict.TryGetValue(personnelId, out var userInfo))
                {
                    sendResult.RecipientPersonnelName = userInfo.Name;
                    sendResult.RecipientEmail = userInfo.Email;

                    // 创建通知历史记录
                    var historyId = await CreateNotificationHistory(input.SettingId, input, personnelId, userInfo);
                    sendResult.NotificationHistoryId = historyId;

                    // 发送通知
                    bool success = await SendSingleNotification(input, userInfo);
                    
                    if (success)
                    {
                        sendResult.SendStatus = NotificationStatusEnum.Success;
                        sendResult.SendResult = "发送成功";
                        sendResult.SendTime = DateTime.Now;
                        output.SuccessCount++;

                        // 更新历史记录状态
                        await UpdateNotificationHistoryStatus(historyId, NotificationStatusEnum.Success, "发送成功", null);
                    }
                    else
                    {
                        sendResult.SendStatus = NotificationStatusEnum.Failed;
                        sendResult.ErrorMessage = "发送失败";
                        output.FailedCount++;

                        // 更新历史记录状态
                        await UpdateNotificationHistoryStatus(historyId, NotificationStatusEnum.Failed, null, "发送失败");
                    }
                }
                else
                {
                    sendResult.SendStatus = NotificationStatusEnum.Failed;
                    sendResult.ErrorMessage = "用户不存在";
                    output.FailedCount++;
                    _logger.LogWarning("用户不存在，人员ID：{PersonnelId}", personnelId);
                }
            }
            catch (Exception ex)
            {
                sendResult.SendStatus = NotificationStatusEnum.Failed;
                sendResult.ErrorMessage = ex.Message;
                output.FailedCount++;
                _logger.LogError(ex, "发送通知异常，人员ID：{PersonnelId}", personnelId);

                // 更新历史记录状态
                if (sendResult.NotificationHistoryId > 0)
                {
                    await UpdateNotificationHistoryStatus(sendResult.NotificationHistoryId, 
                        NotificationStatusEnum.Failed, null, ex.Message);
                }
            }

            output.SendResults.Add(sendResult);
            output.NotificationHistoryIds.Add(sendResult.NotificationHistoryId);
        }

        output.IsAllSuccess = output.FailedCount == 0;
        if (output.FailedCount > 0)
        {
            output.OverallErrorMessage = $"部分发送失败，失败数量：{output.FailedCount}";
        }

        _logger.LogInformation("完成发送通知，总数：{Total}，成功：{Success}，失败：{Failed}", 
            output.TotalCount, output.SuccessCount, output.FailedCount);

        return output;
    }

    /// <summary>
    /// 发送群组通知（邮件发送一封给所有人，系统消息仍然单独发送）
    /// </summary>
    [HttpPost]
    public async Task<SendNotificationOutput> SendGroupNotificationAsync(SendNotificationInput input)
    {
        _logger.LogInformation("开始发送群组通知，通知方式：{NotificationType}，接收人数：{Count}", 
            input.NotificationType, input.RecipientPersonnelIds.Count);

        var output = new SendNotificationOutput
        {
            TotalCount = input.RecipientPersonnelIds.Count,
            SendTime = DateTime.Now
        };

        // 获取用户信息
        var userInfoDict = await GetUserInfoDictionary(input.RecipientPersonnelIds);

        // 过滤出有效的用户信息
        var validUsers = new List<(long personnelId, UserInfo userInfo)>();
        foreach (var personnelId in input.RecipientPersonnelIds)
        {
            if (userInfoDict.TryGetValue(personnelId, out var userInfo))
            {
                validUsers.Add((personnelId, userInfo));
            }
            else
            {
                // 处理无效用户
                var sendResult = new NotificationSendResult
                {
                    RecipientPersonnelId = personnelId,
                    NotificationType = input.NotificationType,
                    SendStatus = NotificationStatusEnum.Failed,
                    ErrorMessage = "用户不存在"
                };
                output.SendResults.Add(sendResult);
                output.FailedCount++;
                _logger.LogWarning("用户不存在，人员ID：{PersonnelId}", personnelId);
            }
        }

        if (!validUsers.Any())
        {
            output.IsAllSuccess = false;
            output.OverallErrorMessage = "没有有效的接收人";
            return output;
        }

        try
        {
            if (input.NotificationType == NotificationTypeEnum.Email)
            {
                // 邮件通知：发送一封邮件给所有人
                await SendGroupEmailNotification(input, validUsers, output);
            }
            else if (input.NotificationType == NotificationTypeEnum.SystemMessage)
            {
                // 系统消息：仍然逐个发送
                await SendIndividualSystemMessages(input, validUsers, output);
            }
        }
        catch (Exception ex)
        {
            _logger.LogError(ex, "发送群组通知异常");
            
            // 将所有结果标记为失败
            foreach (var (personnelId, userInfo) in validUsers)
            {
                if (!output.SendResults.Any(r => r.RecipientPersonnelId == personnelId))
                {
                    var sendResult = new NotificationSendResult
                    {
                        RecipientPersonnelId = personnelId,
                        RecipientPersonnelName = userInfo.Name,
                        RecipientEmail = userInfo.Email,
                        NotificationType = input.NotificationType,
                        SendStatus = NotificationStatusEnum.Failed,
                        ErrorMessage = ex.Message
                    };
                    output.SendResults.Add(sendResult);
                    output.FailedCount++;
                }
            }
        }

        output.IsAllSuccess = output.FailedCount == 0;
        if (output.FailedCount > 0)
        {
            output.OverallErrorMessage = $"部分发送失败，失败数量：{output.FailedCount}";
        }

        _logger.LogInformation("完成发送群组通知，总数：{Total}，成功：{Success}，失败：{Failed}", 
            output.TotalCount, output.SuccessCount, output.FailedCount);

        return output;
    }

    /// <summary>
    /// 批量发送通知
    /// </summary>
    [HttpPost]
    public async Task<List<SendNotificationOutput>> BatchSendNotificationAsync(List<SendNotificationInput> inputs)
    {
        _logger.LogInformation("开始批量发送通知，批次数量：{Count}", inputs.Count);

        var outputs = new List<SendNotificationOutput>();

        foreach (var input in inputs)
        {
            try
            {
                var output = await SendNotificationAsync(input);
                outputs.Add(output);
            }
            catch (Exception ex)
            {
                _logger.LogError(ex, "批量发送通知异常，通知类型：{NotificationType}", input.NotificationType);
                
                var errorOutput = new SendNotificationOutput
                {
                    TotalCount = input.RecipientPersonnelIds.Count,
                    FailedCount = input.RecipientPersonnelIds.Count,
                    IsAllSuccess = false,
                    OverallErrorMessage = ex.Message,
                    SendTime = DateTime.Now
                };
                outputs.Add(errorOutput);
            }
        }

        var totalSuccess = outputs.Sum(o => o.SuccessCount);
        var totalFailed = outputs.Sum(o => o.FailedCount);
        _logger.LogInformation("完成批量发送通知，批次数：{BatchCount}，总成功：{Success}，总失败：{Failed}", 
            outputs.Count, totalSuccess, totalFailed);

        return outputs;
    }

    /// <summary>
    /// 根据通知设置发送通知
    /// </summary>
    [HttpPost]
    public async Task<SendNotificationOutput> SendNotificationBySettingAsync(
        long notificationSettingId,
        string businessType,
        long? businessId = null,
        string businessData = "",
        Dictionary<string, string> templateVariables = null)
    {
        _logger.LogInformation("开始根据通知设置发送通知，设置ID：{SettingId}，业务类型：{BusinessType}", 
            notificationSettingId, businessType);

        // 获取通知设置
        var notificationSetting = await _notificationSettingRepository.Select
            .WhereDynamic(notificationSettingId)
            .Include(a => a.PersonnelGroup)
            .ToOneAsync();

        if (notificationSetting == null)
        {
            _logger.LogWarning("通知设置不存在，ID：{SettingId}", notificationSettingId);
            throw new Exception($"通知设置不存在，ID：{notificationSettingId}");
        }

        if (!notificationSetting.IsEnabled)
        {
            _logger.LogWarning("通知设置已禁用，ID：{SettingId}", notificationSettingId);
            throw new Exception($"通知设置已禁用，ID：{notificationSettingId}");
        }

        return new SendNotificationOutput
        {
            IsAllSuccess = true,
            OverallErrorMessage = "功能开发中",
            SendTime = DateTime.Now
        };
    }

    #endregion

    #region 通知模板引擎（决策点7）

    /// <summary>
    /// 验证模板语法
    /// </summary>
    [HttpPost]
    public async Task<bool> ValidateTemplateAsync(string template)
    {
        try
        {
            var result = await _templateService.ValidateTemplateAsync(new ValidateTemplateInput { Template = template });
            return result.Success;
        }
        catch (Exception ex)
        {
            _logger.LogError(ex, "验证模板语法异常");
            return false;
        }
    }

    #endregion

    #region 通知历史记录（决策点8）

    /// <summary>
    /// 查询通知历史记录
    /// </summary>
    [HttpGet]
    public async Task<NotificationHistoryOutput> GetNotificationHistoryAsync(long id)
    {
        _logger.LogInformation("开始查询通知历史记录，ID：{Id}", id);

        var entity = await _notificationHistoryRepository.Select
            .WhereDynamic(id)
            .Include(a => a.NotificationSetting)
            .ToOneAsync();

        if (entity == null)
        {
            _logger.LogWarning("通知历史记录不存在，ID：{Id}", id);
            throw new Exception($"通知历史记录不存在，ID：{id}");
        }

        var output = MapToNotificationHistoryOutput(entity);
        _logger.LogInformation("成功查询通知历史记录，ID：{Id}", id);
        return output;
    }

    /// <summary>
    /// 查询通知历史记录分页
    /// </summary>
    [HttpPost]
    public async Task<PageOutput<NotificationHistoryOutput>> GetNotificationHistoryPageAsync(PageInput<NotificationHistoryPageInput> input)
    {
        _logger.LogInformation("开始查询通知历史记录分页，页码：{Current}，页大小：{Size}", input.CurrentPage, input.PageSize);

        var query = _notificationHistoryRepository.Select
            .Include(a => a.NotificationSetting);

        // 根据搜索条件过滤
        if (input.Filter != null)
        {
            if (input.Filter.NotificationSettingId.HasValue && input.Filter.NotificationSettingId.Value > 0)
            {
                query = query.Where(a => a.NotificationSettingId == input.Filter.NotificationSettingId.Value);
            }

            if (input.Filter.RecipientPersonnelId.HasValue && input.Filter.RecipientPersonnelId.Value > 0)
            {
                query = query.Where(a => a.RecipientPersonnelId == input.Filter.RecipientPersonnelId.Value);
            }

            if (!string.IsNullOrEmpty(input.Filter.RecipientPersonnelName))
            {
                query = query.Where(a => a.RecipientPersonnelName.Contains(input.Filter.RecipientPersonnelName));
            }

            if (input.Filter.NotificationType.HasValue)
            {
                query = query.Where(a => a.NotificationType == (int)input.Filter.NotificationType.Value);
            }

            if (input.Filter.SendStatus.HasValue)
            {
                query = query.Where(a => a.SendStatus == (int)input.Filter.SendStatus.Value);
            }

            if (!string.IsNullOrEmpty(input.Filter.BusinessType))
            {
                query = query.Where(a => a.BusinessType.Contains(input.Filter.BusinessType));
            }

            if (input.Filter.StartTime.HasValue)
            {
                query = query.Where(a => a.CreatedTime >= input.Filter.StartTime.Value);
            }

            if (input.Filter.EndTime.HasValue)
            {
                query = query.Where(a => a.CreatedTime <= input.Filter.EndTime.Value);
            }
        }

        var totalCount = await query.CountAsync();
        var entities = await query
            .OrderByDescending(a => a.CreatedTime)
            .Page(input.CurrentPage, input.PageSize)
            .ToListAsync();

        var outputs = entities.Select(MapToNotificationHistoryOutput).ToList();

        _logger.LogInformation("成功查询通知历史记录分页，总数：{Total}，当前页数据：{Count}", totalCount, outputs.Count);
        return new PageOutput<NotificationHistoryOutput>
        {
            List = outputs,
            Total = totalCount
        };
    }
    
    /// <summary>
    /// 查询当前用户通知历史记录
    /// </summary>
    [HttpPost]
    public async Task<PageOutput<NotificationHistoryOutput>> GetNotificationHistoryByUserPageAsync()
    {
        var query = _notificationHistoryRepository.Select
            .Include(a => a.NotificationSetting);
        
        query = query.Where(a => a.RecipientPersonnelId == User.Id && a.NotificationType == 2 && a.IsDeleted == false);
        
        var totalCount = await query.CountAsync();
        var entities = await query
            .OrderByDescending(a => a.CreatedTime)
            .Page(1, 10)
            .ToListAsync();

        var outputs = entities.Select(MapToNotificationHistoryOutput).ToList();
        
        return new PageOutput<NotificationHistoryOutput>
        {
            List = outputs,
            Total = totalCount
        };
    }
    
    
    /// <summary>
    /// 重试失败的通知
    /// </summary>
    [HttpPost]
    public async Task<bool> RetryFailedNotificationAsync(long notificationHistoryId)
    {
        _logger.LogInformation("开始重试失败的通知，历史记录ID：{HistoryId}", notificationHistoryId);

        // 简化实现
        await Task.Delay(100);
        _logger.LogInformation("完成重试失败的通知，历史记录ID：{HistoryId}", notificationHistoryId);
        return true;
    }

    /// <summary>
    /// 批量重试失败的通知
    /// </summary>
    [HttpPost]
    public async Task<int> BatchRetryFailedNotificationsAsync(List<long> notificationHistoryIds)
    {
        _logger.LogInformation("开始批量重试失败的通知，数量：{Count}", notificationHistoryIds.Count);

        int successCount = 0;
        foreach (var historyId in notificationHistoryIds)
        {
            try
            {
                bool success = await RetryFailedNotificationAsync(historyId);
                if (success) successCount++;
            }
            catch (Exception ex)
            {
                _logger.LogError(ex, "批量重试失败通知异常，历史记录ID：{HistoryId}", historyId);
            }
        }

        _logger.LogInformation("完成批量重试失败的通知，总数：{Total}，成功：{Success}", 
            notificationHistoryIds.Count, successCount);
        return successCount;
    }

    /// <summary>
    /// 取消通知
    /// </summary>
    [HttpPost]
    public async Task<bool> CancelNotificationAsync(long notificationHistoryId)
    {
        _logger.LogInformation("开始取消通知，历史记录ID：{HistoryId}", notificationHistoryId);

        try
        {
            var history = await _notificationHistoryRepository.GetAsync(notificationHistoryId);
            if (history == null)
            {
                _logger.LogWarning("通知历史记录不存在，ID：{HistoryId}", notificationHistoryId);
                return false;
            }

            // 只有待发送状态的通知才能取消
            if (history.SendStatus != (int)NotificationStatusEnum.Pending)
            {
                _logger.LogWarning("只有待发送状态的通知才能取消，当前状态：{Status}，ID：{HistoryId}", 
                    (NotificationStatusEnum)history.SendStatus, notificationHistoryId);
                return false;
            }

            history.SendStatus = (int)NotificationStatusEnum.Cancelled;
            history.SendResult = "通知已取消";
            history.ActualSendTime = DateTime.Now;

            await _notificationHistoryRepository.UpdateAsync(history);
            _logger.LogInformation("成功取消通知，历史记录ID：{HistoryId}", notificationHistoryId);
            return true;
        }
        catch (Exception ex)
        {
            _logger.LogError(ex, "取消通知异常，历史记录ID：{HistoryId}", notificationHistoryId);
            return false;
        }
    }

    /// <summary>
    /// 批量取消通知
    /// </summary>
    [HttpPost]
    public async Task<int> BatchCancelNotificationsAsync(List<long> notificationHistoryIds)
    {
        _logger.LogInformation("开始批量取消通知，数量：{Count}", notificationHistoryIds.Count);

        int successCount = 0;
        foreach (var historyId in notificationHistoryIds)
        {
            try
            {
                bool success = await CancelNotificationAsync(historyId);
                if (success) successCount++;
            }
            catch (Exception ex)
            {
                _logger.LogError(ex, "批量取消通知异常，历史记录ID：{HistoryId}", historyId);
            }
        }

        _logger.LogInformation("完成批量取消通知，总数：{Total}，成功：{Success}", 
            notificationHistoryIds.Count, successCount);
        return successCount;
    }

    #endregion

    #region 定时任务管理（决策点6）

    /// <summary>
    /// 创建定时通知任务
    /// </summary>
    [HttpPost]
    public async Task<long> CreateScheduledNotificationTaskAsync(
        long notificationSettingId,
        string businessType,
        long? businessId = null,
        string businessData = "",
        DateTime? plannedExecutionTime = null,
        string cronExpression = "")
    {
        _logger.LogInformation("开始创建定时通知任务，通知设置ID：{SettingId}，业务类型：{BusinessType}", 
            notificationSettingId, businessType);

        // 简化实现，返回模拟任务ID
        var taskId = DateTime.Now.Ticks;
        _logger.LogInformation("成功创建定时通知任务，任务ID：{TaskId}", taskId);
        return taskId;
    }

    /// <summary>
    /// 执行定时通知任务
    /// </summary>
    [HttpPost]
    public async Task<bool> ExecuteScheduledNotificationTaskAsync(long taskId)
    {
        _logger.LogInformation("开始执行定时通知任务，任务ID：{TaskId}", taskId);
        await Task.Delay(100);
        _logger.LogInformation("成功执行定时通知任务，任务ID：{TaskId}", taskId);
        return true;
    }

    /// <summary>
    /// 获取待执行的定时任务列表
    /// </summary>
    [HttpGet]
    public async Task<List<long>> GetPendingNotificationTasksAsync()
    {
        await Task.CompletedTask;
        return new List<long>();
    }

    /// <summary>
    /// 启用/禁用定时任务
    /// </summary>
    [HttpPut]
    public async Task ToggleNotificationTaskAsync(long taskId, bool enabled)
    {
        _logger.LogInformation("开始{Action}定时任务，任务ID：{TaskId}", enabled ? "启用" : "禁用", taskId);
        await Task.CompletedTask;
        _logger.LogInformation("成功{Action}定时任务，任务ID：{TaskId}", enabled ? "启用" : "禁用", taskId);
    }

    #endregion

    #region 通知统计

    /// <summary>
    /// 获取通知发送统计信息
    /// </summary>
    [HttpPost]
    public async Task<Dictionary<string, object>> GetNotificationStatisticsAsync(
        DateTime startTime,
        DateTime endTime,
        long? notificationSettingId = null)
    {
        _logger.LogInformation("开始获取通知发送统计信息，时间范围：{StartTime} - {EndTime}", startTime, endTime);

        var statistics = new Dictionary<string, object>
        {
            ["TotalCount"] = 0,
            ["SuccessCount"] = 0,
            ["FailedCount"] = 0,
            ["PendingCount"] = 0,
            ["SuccessRate"] = 0.0,
            ["EmailCount"] = 0,
            ["SystemMessageCount"] = 0,
            ["StatisticsTime"] = DateTime.Now
        };

        _logger.LogInformation("成功获取通知发送统计信息");
        return statistics;
    }

    #endregion

    #region 私有辅助方法

    /// <summary>
    /// 用户信息DTO类
    /// </summary>
    private class UserInfo
    {
        public long Id { get; set; }
        public string Name { get; set; } = "";
        public string Email { get; set; } = "";
    }

    /// <summary>
    /// 获取用户信息字典
    /// </summary>
    private async Task<Dictionary<long, UserInfo>> GetUserInfoDictionary(List<long> personnelIds)
    {
        var userInfoDict = new Dictionary<long, UserInfo>();
        
        try
        {
            var cacheKey = CacheKeys.UserListKey;
            var cacheOrgUsers = Cache.Get<List<UserGrpcOutput>>(cacheKey);


            if (cacheOrgUsers == null || (cacheOrgUsers != null && cacheOrgUsers.Count == 0))
            {
                cacheOrgUsers = await _userService.GetUserList();
                Cache.Set(cacheKey, cacheOrgUsers, new TimeSpan(8, 0, 0));
            }

            foreach (var personnelId in personnelIds)
            {
                var cu = cacheOrgUsers.Where(x => x.Id == personnelId).FirstOrDefault();
                userInfoDict[personnelId] = new UserInfo
                {
                    Id = personnelId,
                    Name = cu?.Name,
                    Email = cu?.Email
                };
            }
        }
        catch (Exception ex)
        {
            _logger.LogError(ex, "获取用户信息异常，人员ID列表：{PersonnelIds}", string.Join(",", personnelIds));
        }

        return userInfoDict;
    }

    /// <summary>
    /// 发送单个通知
    /// </summary>
    private async Task<bool> SendSingleNotification(SendNotificationInput input, UserInfo userInfo)
    {
        try
        {
            if (input.NotificationType == NotificationTypeEnum.Email)
            {
                return await SendEmailNotification(userInfo.Email, input.Title, input.Content);
            }
            else if (input.NotificationType == NotificationTypeEnum.SystemMessage)
            {
                return true;
            }

            return false;
        }
        catch (Exception ex)
        {
            _logger.LogError(ex, "发送单个通知异常，人员ID：{PersonnelId}，通知方式：{NotificationType}", 
                userInfo.Id, input.NotificationType);
            return false;
        }
    }

    /// <summary>
    /// 发送群组邮件通知（一封邮件发送给所有人）
    /// </summary>
    private async Task SendGroupEmailNotification(SendNotificationInput input, 
        List<(long personnelId, UserInfo userInfo)> validUsers, SendNotificationOutput output)
    {
        try
        {
            // 收集所有有效的邮箱地址
            var emailAddresses = validUsers
                .Where(u => !string.IsNullOrWhiteSpace(u.userInfo.Email))
                .Select(u => u.userInfo.Email)
                .Distinct()
                .ToList();

            if (!emailAddresses.Any())
            {
                // 没有有效邮箱，标记所有用户为失败
                foreach (var (personnelId, userInfo) in validUsers)
                {
                    var sendResult = new NotificationSendResult
                    {
                        RecipientPersonnelId = personnelId,
                        RecipientPersonnelName = userInfo.Name,
                        RecipientEmail = userInfo.Email,
                        NotificationType = input.NotificationType,
                        SendStatus = NotificationStatusEnum.Failed,
                        ErrorMessage = "邮箱地址无效"
                    };
                    output.SendResults.Add(sendResult);
                    output.FailedCount++;
                }
                return;
            }

            // 创建批量邮件发送请求
            var batchEmailInput = new BatchSendEmailInput
            {
                Recipients = emailAddresses,
                Subject = input.Title,
                Content = input.Content,
                IsHtml = true
            };

            // 发送批量邮件
            var emailResult = await _emailNotificationService.BatchSendEmailAsync(batchEmailInput);
            var sendTime = DateTime.Now;

            // 为每个用户创建通知历史记录和发送结果
            foreach (var (personnelId, userInfo) in validUsers)
            {
                try
                {
                    // 创建通知历史记录
                    var historyId = await CreateNotificationHistory(input.SettingId, input, personnelId, userInfo);

                    // 判断该用户的邮件是否发送成功
                    var userEmailResult = emailResult.Results.FirstOrDefault(r => r.RecipientEmail == userInfo.Email);
                    var isSuccess = userEmailResult?.IsSuccess == true;

                    var sendResult = new NotificationSendResult
                    {
                        RecipientPersonnelId = personnelId,
                        RecipientPersonnelName = userInfo.Name,
                        RecipientEmail = userInfo.Email,
                        NotificationType = input.NotificationType,
                        NotificationHistoryId = historyId,
                        SendTime = sendTime
                    };

                    if (isSuccess)
                    {
                        sendResult.SendStatus = NotificationStatusEnum.Success;
                        sendResult.SendResult = "群组邮件发送成功";
                        output.SuccessCount++;

                        // 更新历史记录状态
                        await UpdateNotificationHistoryStatus(historyId, NotificationStatusEnum.Success, "群组邮件发送成功", null);
                    }
                    else
                    {
                        sendResult.SendStatus = NotificationStatusEnum.Failed;
                        sendResult.ErrorMessage = userEmailResult?.ErrorMessage ?? "群组邮件发送失败";
                        output.FailedCount++;

                        // 更新历史记录状态
                        await UpdateNotificationHistoryStatus(historyId, NotificationStatusEnum.Failed, null, sendResult.ErrorMessage);
                    }

                    output.SendResults.Add(sendResult);
                    output.NotificationHistoryIds.Add(historyId);
                }
                catch (Exception ex)
                {
                    _logger.LogError(ex, "处理群组邮件发送结果异常，人员ID：{PersonnelId}", personnelId);
                    
                    var sendResult = new NotificationSendResult
                    {
                        RecipientPersonnelId = personnelId,
                        RecipientPersonnelName = userInfo.Name,
                        RecipientEmail = userInfo.Email,
                        NotificationType = input.NotificationType,
                        SendStatus = NotificationStatusEnum.Failed,
                        ErrorMessage = ex.Message
                    };
                    output.SendResults.Add(sendResult);
                    output.FailedCount++;
                }
            }

            _logger.LogInformation("群组邮件发送完成，邮箱数量：{EmailCount}，用户数量：{UserCount}", 
                emailAddresses.Count, validUsers.Count);
        }
        catch (Exception ex)
        {
            _logger.LogError(ex, "发送群组邮件异常");
            throw;
        }
    }

    /// <summary>
    /// 发送个人系统消息（逐个发送）
    /// </summary>
    private async Task SendIndividualSystemMessages(SendNotificationInput input, 
        List<(long personnelId, UserInfo userInfo)> validUsers, SendNotificationOutput output)
    {
        try
        {
            foreach (var (personnelId, userInfo) in validUsers)
            {
                var sendResult = new NotificationSendResult
                {
                    RecipientPersonnelId = personnelId,
                    RecipientPersonnelName = userInfo.Name,
                    RecipientEmail = userInfo.Email,
                    NotificationType = input.NotificationType
                };

                try
                {
                    // 创建通知历史记录
                    var historyId = await CreateNotificationHistory(input.SettingId, input, personnelId, userInfo);
                    sendResult.NotificationHistoryId = historyId;

                    // 发送系统消息
                    var success = await SendSystemMessageNotification(personnelId, input.Title, input.Content);
                    
                    if (success)
                    {
                        sendResult.SendStatus = NotificationStatusEnum.Success;
                        sendResult.SendResult = "系统消息发送成功";
                        sendResult.SendTime = DateTime.Now;
                        output.SuccessCount++;

                        // 更新历史记录状态
                        await UpdateNotificationHistoryStatus(historyId, NotificationStatusEnum.Success, "系统消息发送成功", null);
                    }
                    else
                    {
                        sendResult.SendStatus = NotificationStatusEnum.Failed;
                        sendResult.ErrorMessage = "系统消息发送失败";
                        output.FailedCount++;

                        // 更新历史记录状态
                        await UpdateNotificationHistoryStatus(historyId, NotificationStatusEnum.Failed, null, "系统消息发送失败");
                    }
                }
                catch (Exception ex)
                {
                    sendResult.SendStatus = NotificationStatusEnum.Failed;
                    sendResult.ErrorMessage = ex.Message;
                    output.FailedCount++;
                    _logger.LogError(ex, "发送系统消息异常，人员ID：{PersonnelId}", personnelId);

                    // 更新历史记录状态
                    if (sendResult.NotificationHistoryId > 0)
                    {
                        await UpdateNotificationHistoryStatus(sendResult.NotificationHistoryId, 
                            NotificationStatusEnum.Failed, null, ex.Message);
                    }
                }

                output.SendResults.Add(sendResult);
                output.NotificationHistoryIds.Add(sendResult.NotificationHistoryId);
            }

            _logger.LogInformation("个人系统消息发送完成，用户数量：{UserCount}", validUsers.Count);
        }
        catch (Exception ex)
        {
            _logger.LogError(ex, "发送个人系统消息异常");
            throw;
        }
    }

    /// <summary>
    /// 发送邮件通知
    /// </summary>
    private async Task<bool> SendEmailNotification(string email, string title, string content)
    {
        try
        {
            var sendEmailInput = new SendEmailInput
            {
                RecipientEmail = email,
                Subject = title,
                Content = content
            };

            var result = await _emailNotificationService.SendEmailAsync(sendEmailInput);
            return result.IsSuccess;
        }
        catch (Exception ex)
        {
            _logger.LogError(ex, "发送邮件通知异常，邮箱：{Email}", email);
            return false;
        }
    }

    /// <summary>
    /// 发送系统消息通知
    /// </summary>
    private async Task<bool> SendSystemMessageNotification(long personnelId, string title, string content)
    {
        try
        {
            var sendMessageInput = new SendSystemMessageInput
            {
                RecipientPersonnelId = personnelId,
                Title = title,
                Content = content
            };

            var result = await _systemMessageService.SendSystemMessageAsync(sendMessageInput);
            return result.Success;
        }
        catch (Exception ex)
        {
            _logger.LogError(ex, "发送系统消息异常，人员ID：{PersonnelId}", personnelId);
            return false;
        }
    }

    /// <summary>
    /// 创建通知历史记录
    /// </summary>
    private async Task<long> CreateNotificationHistory(long? notificationSettingId, SendNotificationInput input, 
        long personnelId, UserInfo userInfo)
    {
        try
        {
            var history = new NotificationHistoryEntity
            {
                NotificationSettingId = notificationSettingId ?? 0,
                RecipientPersonnelId = personnelId,
                RecipientPersonnelName = userInfo.Name,
                RecipientEmail = userInfo.Email,
                NotificationType = (int)input.NotificationType,
                NotificationTitle = input.Title,
                NotificationContent = input.Content,
                PlannedSendTime = input.PlannedSendTime ?? DateTime.Now,
                SendStatus = (int)NotificationStatusEnum.Pending,
                MaxRetryCount = input.MaxRetryCount,
                BusinessType = input.BusinessType,
                BusinessId = input.BusinessId,
                BusinessData = input.BusinessData
            };

            history = await _notificationHistoryRepository.InsertAsync(history);
            return history.Id;
        }
        catch (Exception ex)
        {
            _logger.LogError(ex, "创建通知历史记录异常，人员ID：{PersonnelId}", personnelId);
            return 0;
        }
    }

    /// <summary>
    /// 更新通知历史记录状态
    /// </summary>
    private async Task UpdateNotificationHistoryStatus(long historyId, NotificationStatusEnum status, 
        string sendResult, string errorMessage)
    {
        try
        {
            if (historyId <= 0) return;

            var history = await _notificationHistoryRepository.GetAsync(historyId);
            if (history != null)
            {
                history.SendStatus = (int)status;
                history.SendResult = sendResult ?? "";
                history.ErrorMessage = errorMessage ?? "";
                
                if (status == NotificationStatusEnum.Success)
                {
                    history.ActualSendTime = DateTime.Now;
                }

                await _notificationHistoryRepository.UpdateAsync(history);
            }
        }
        catch (Exception ex)
        {
            _logger.LogError(ex, "更新通知历史记录状态异常，历史记录ID：{HistoryId}", historyId);
        }
    }

    /// <summary>
    /// 映射到NotificationSettingOutput
    /// </summary>
    private NotificationSettingOutput MapToNotificationSettingOutput(NotificationSettingEntity entity)
    {
        return new NotificationSettingOutput
        {
            Id = entity.Id,
            NotificationName = entity.NotificationName,
            Description = entity.Description,
            IsEnabled = entity.IsEnabled,
            IsEmailEnabled = entity.IsEmailEnabled,
            IsSystemMessageEnabled = entity.IsSystemMessageEnabled,
            StartTime = entity.StartTime,
            EndTime = entity.EndTime,
            FrequencyType = (NotificationFrequencyEnum)entity.FrequencyType,
            IntervalMinutes = entity.IntervalMinutes,
            PersonnelGroupId = entity.PersonnelGroupId,
            PersonnelGroupName = entity.PersonnelGroup?.GroupName ?? "",
            EmailSubjectTemplate = entity.EmailSubjectTemplate,
            EmailContentTemplate = entity.EmailContentTemplate,
            SystemMessageTitleTemplate = entity.SystemMessageTitleTemplate,
            SystemMessageContentTemplate = entity.SystemMessageContentTemplate,
            TriggerConditions = entity.TriggerConditions,
            CreatedTime = entity.CreatedTime ?? DateTime.MinValue,
            ModifiedTime = entity.ModifiedTime,
            LastModifiedTime = entity.LastModifiedTime
        };
    }

    /// <summary>
    /// 映射到PersonnelGroupOutput
    /// </summary>
    private PersonnelGroupOutput MapToPersonnelGroupOutput(PersonnelGroupEntity entity)
    {
        var staticPersonnelIds = JsonSerializer.Deserialize<List<long>>(entity.StaticPersonnelIds) ?? new List<long>();
        var dynamicDepartmentIds = JsonSerializer.Deserialize<List<long>>(entity.DynamicDepartmentIds) ?? new List<long>();
        var dynamicPositions = JsonSerializer.Deserialize<List<string>>(entity.DynamicPositions) ?? new List<string>();
        var excludePersonnelIds = JsonSerializer.Deserialize<List<long>>(entity.ExcludePersonnelIds) ?? new List<long>();

        return new PersonnelGroupOutput
        {
            Id = entity.Id,
            GroupName = entity.GroupName,
            Description = entity.Description,
            GroupType = (PersonnelGroupTypeEnum)entity.GroupType,
            IsEnabled = entity.IsEnabled,
            StaticPersonnelIds = staticPersonnelIds,
            DynamicDepartmentIds = dynamicDepartmentIds,
            DynamicPositions = dynamicPositions,
            OnlyActivePersonnel = entity.OnlyActivePersonnel,
            ExcludePersonnelIds = excludePersonnelIds,
            CreatedTime = entity.CreatedTime ?? DateTime.MinValue,
            ModifiedTime = entity.ModifiedTime,
            LastModifiedTime = entity.LastModifiedTime
        };
    }

    /// <summary>
    /// 映射到NotificationHistoryOutput
    /// </summary>
    private NotificationHistoryOutput MapToNotificationHistoryOutput(NotificationHistoryEntity entity)
    {
        return new NotificationHistoryOutput
        {
            Id = entity.Id,
            NotificationSettingId = entity.NotificationSettingId,
            NotificationSettingName = entity.NotificationSetting?.NotificationName ?? "",
            RecipientPersonnelId = entity.RecipientPersonnelId,
            RecipientPersonnelName = entity.RecipientPersonnelName,
            RecipientEmail = entity.RecipientEmail,
            NotificationType = (NotificationTypeEnum)entity.NotificationType,
            NotificationTitle = entity.NotificationTitle,
            NotificationContent = entity.NotificationContent,
            PlannedSendTime = entity.PlannedSendTime,
            ActualSendTime = entity.ActualSendTime,
            SendStatus = (NotificationStatusEnum)entity.SendStatus,
            SendResult = entity.SendResult,
            ErrorMessage = entity.ErrorMessage,
            RetryCount = entity.RetryCount,
            MaxRetryCount = entity.MaxRetryCount,
            NextRetryTime = entity.NextRetryTime,
            BusinessType = entity.BusinessType,
            BusinessId = entity.BusinessId,
            BusinessData = entity.BusinessData,
            CreatedTime = entity.CreatedTime ?? DateTime.MinValue
        };
    }

    #endregion

    #region 私有辅助方法验证

    /// <summary>
    /// 验证时间配置合法性
    /// </summary>
    private void ValidateTimeConfiguration(string startTime, string endTime)
    {
        if (!string.IsNullOrEmpty(startTime) && !string.IsNullOrEmpty(endTime))
        {
            if (TimeOnly.TryParse(startTime, out var start) && TimeOnly.TryParse(endTime, out var end))
            {
                if (start >= end)
                {
                    throw new Exception("开始时间不能大于等于结束时间");
                }
            }
        }
    }

    /// <summary>
    /// 验证频次配置合法性
    /// </summary>
    private void ValidateFrequencyConfiguration(NotificationFrequencyEnum frequencyType, int? intervalMinutes)
    {
        if (frequencyType == NotificationFrequencyEnum.FixedInterval && (!intervalMinutes.HasValue || intervalMinutes.Value <= 0))
        {
            throw new Exception("间隔频次时，间隔分钟数必须大于0");
        }
    }

    /// <summary>
    /// 验证模板配置合法性
    /// </summary>
    private async Task ValidateTemplateConfiguration(dynamic input)
    {
        if (!string.IsNullOrEmpty(input.EmailSubjectTemplate))
        {
            var result = await _templateService.ValidateTemplateAsync(new ValidateTemplateInput { Template = input.EmailSubjectTemplate });
            if (!result.Success)
            {
                throw new Exception($"邮件主题模板格式错误：{result.ErrorMessage}");
            }
        }
    }

    /// <summary>
    /// 验证人员组配置合法性
    /// </summary>
    private void ValidatePersonnelGroupConfiguration(PersonnelGroupCreateInput input)
    {
        var groupType = (PersonnelGroupTypeEnum)input.GroupType;
        
        if (groupType == PersonnelGroupTypeEnum.Static && (input.StaticPersonnelIds == null || !input.StaticPersonnelIds.Any()))
        {
            throw new Exception("静态人员组必须配置人员");
        }
        
        if ((groupType == PersonnelGroupTypeEnum.DynamicByDepartment || groupType == PersonnelGroupTypeEnum.Mixed) && 
            (input.DynamicDepartmentIds == null || !input.DynamicDepartmentIds.Any()))
        {
            throw new Exception("动态部门人员组必须配置部门");
        }
    }

    /// <summary>
    /// 获取动态人员ID列表
    /// </summary>
    private async Task<List<long>> GetDynamicPersonnelIds(PersonnelGroupEntity personnelGroup)
    {
        var orgUserIds = new List<long>();
        
        var dynamicDepartmentIds = JsonSerializer.Deserialize<List<long>>(personnelGroup.DynamicDepartmentIds);
        foreach (var orgId in dynamicDepartmentIds)
        {
            var cacheKey = CacheKeys.GetDynamicDepartmentKey(orgId);

            var cacheOrgUserIds = Cache.Get<List<UserOrgGrpcOutput>>(cacheKey);
            if (cacheOrgUserIds != null && cacheOrgUserIds.Any())
            {
                orgUserIds.AddRange(cacheOrgUserIds.Select(m => m.Id).ToList());
            }
            else
            {
                var orgUsers = await _userService.GetOrgUserList(orgId);
                Cache.Set(cacheKey, orgUsers, new TimeSpan(8, 0, 0));
                orgUserIds.AddRange(orgUsers.Select(m => m.Id).ToList());
            }
        }
        return orgUserIds;
    }

    #endregion
}