using Microsoft.Extensions.Logging;
using QYZH.InteractiveMagazine.IService;
using QYZH.InteractiveMagazine.Models.Common;
using QYZH.InteractiveMagazine.Models.Dto;
using QYZH.InteractiveMagazine.Models.Entity;
using QYZH.InteractiveMagazine.Repository;
using Serilog.Core;
using SqlSugar;

namespace QYZH.InteractiveMagazine.Service;

/// <summary>
/// 操作日志服务实现
/// </summary>
public class OperationLogService(
        BaseRepository<OperationLog> operationLogRepository,
        BaseRepository<AdminUser> adminUserRepository,
        BaseRepository<Users> usersRepository,
        ILogger<OperationLogService> logger) : BaseRepository<OperationLog>, IOperationLogService
{


    /// <summary>
    /// 记录操作日志
    /// </summary>
    public async Task LogAsync(long operatorId, string operatorName, string actionType, string targetType, long targetId, string? targetName = null, string? detail = null, string? ipAddress = null)
    {
        try
        {
            var log = new OperationLog
            {
                OperatorId = operatorId,
                OperatorName = operatorName,
                ActionType = actionType,
                TargetType = targetType,
                TargetId = targetId,
                TargetName = targetName,
                Detail = detail,
                IpAddress = ipAddress,
                IsDeleted = false,
                CreatedBy = operatorName,
                CreatedAt = DateTime.Now,
                UpdatedBy = operatorName,
                UpdatedAt = DateTime.Now
            };

            await operationLogRepository.InsertAsync(log);

            logger.LogInformation(
                "记录操作日志，Operator: {Operator}, Action: {Action}, Target: {TargetType}/{TargetId}",
                operatorName, actionType, targetType, targetId);
        }
        catch (Exception ex)
        {
            // 日志记录不应影响主业务流程
            logger.LogError(ex, "记录操作日志失败，Operator: {Operator}, Action: {Action}", operatorName, actionType);
        }
    }

    /// <summary>
    /// 分页查询操作日志
    /// </summary>
    public async Task<PageListModel<OperationLogOutput>> GetListAsync(OperationLogQueryInput input)
    {
        if (input.PageIndex <= 0)
            input.PageIndex = 1;

        if (input.PageSize <= 0 || input.PageSize > 100)
            input.PageSize = 10;

        RefAsync<int> totalNumber = 0;

        var pageResult = await operationLogRepository.Queryable()
            .WhereIF(!string.IsNullOrWhiteSpace(input.OperatorName), l => l.OperatorName.Contains(input.OperatorName))
            .WhereIF(!string.IsNullOrWhiteSpace(input.ActionType), l => l.ActionType == input.ActionType)
            .WhereIF(!string.IsNullOrWhiteSpace(input.TargetType), l => l.TargetType == input.TargetType)
            .WhereIF(input.TargetId.HasValue, l => l.TargetId == input.TargetId.Value)
            .OrderByDescending(l => l.CreatedAt)
            .Select(l => new OperationLogOutput
            {
                Id = l.Id,
                OperatorId = l.OperatorId,
                OperatorName = l.OperatorName,
                ActionType = l.ActionType,
                TargetType = l.TargetType,
                TargetId = l.TargetId,
                TargetName = l.TargetName,
                Detail = l.Detail,
                IpAddress = l.IpAddress,
                CreatedAt = l.CreatedAt
            })
            .ToPageListAsync(input.PageIndex, input.PageSize, totalNumber);

        return new PageListModel<OperationLogOutput>(pageResult, input.PageIndex, input.PageSize, totalNumber);
    }

    /// <summary>
    /// 获取操作日志详情
    /// </summary>
    public async Task<OperationLogDetailOutput> GetDetailAsync(long id)
    {
        var log = await operationLogRepository.Queryable()
            .Where(l => l.Id == id && !l.IsDeleted)
            .FirstAsync();

        if (log == null)
        {
            throw new BusinessException("操作日志记录不存在", ResultCode.NOT_FOUND);
        }

        var result = new OperationLogDetailOutput
        {
            Id = log.Id,
            ActionType = log.ActionType,
            TargetType = log.TargetType,
            TargetId = log.TargetId,
            TargetName = log.TargetName,
            Detail = log.Detail,
            IpAddress = log.IpAddress,
            CreatedAt = log.CreatedAt,
            OperatorName = log.OperatorName
        };

        // 查询操作人详细信息
        var adminUser = await adminUserRepository.GetByIdAsync(log.OperatorId);
        if (adminUser != null)
        {
            result.OperatorRole = adminUser.Type.ToString();
        }

        // 当目标类型为用户时，查询被操作人信息
        if (log.TargetType == OperationLogTargetType.User)
        {
            var targetUser = await usersRepository.GetByIdAsync(log.TargetId);
            if (targetUser != null)
            {
                result.TargetUserName = targetUser.Name;
                result.TargetUserAvatar = targetUser.AvatarUrl;

                // Phone 已迁移到 WxUser 表，通过 WxUserId 关联查询
                var wxUser = await usersRepository.Context.Queryable<WxUser>()
                    .Where(w => w.Id == targetUser.WxUserId && !w.IsDeleted)
                    .FirstAsync();
                result.TargetUserPhone = wxUser?.Phone;
            }
        }

        return result;
    }
}
