using HoneyBox.Admin.Data;
using HoneyBox.Admin.Entities;
using HoneyBox.Admin.Models.Common;
using HoneyBox.Admin.Models.OperationLog;
using Microsoft.EntityFrameworkCore;
using Microsoft.Extensions.Logging;

namespace HoneyBox.Admin.Services;

/// <summary>
/// 操作日志服务实现
/// </summary>
public class OperationLogService : IOperationLogService
{
    private readonly AdminDbContext _dbContext;
    private readonly ILogger<OperationLogService> _logger;

    public OperationLogService(AdminDbContext dbContext, ILogger<OperationLogService> logger)
    {
        _dbContext = dbContext;
        _logger = logger;
    }

    /// <inheritdoc />
    public async Task LogAsync(OperationLogRequest request)
    {
        var log = new Entities.OperationLog
        {
            AdminUserId = request.AdminUserId,
            Username = request.Username,
            Module = request.Module,
            Action = request.Action,
            Method = request.Method,
            Url = request.Url,
            Ip = request.Ip,
            RequestData = request.RequestData,
            ResponseData = request.ResponseData,
            Status = request.Status,
            ErrorMsg = request.ErrorMsg,
            Duration = request.Duration,
            CreatedAt = DateTime.Now
        };

        _dbContext.OperationLogs.Add(log);
        await _dbContext.SaveChangesAsync();
    }

    /// <inheritdoc />
    public async Task<PagedResult<OperationLogDto>> GetListAsync(OperationLogQueryRequest request)
    {
        var query = _dbContext.OperationLogs.AsQueryable();

        // 管理员ID筛选
        if (request.AdminUserId.HasValue)
        {
            query = query.Where(l => l.AdminUserId == request.AdminUserId.Value);
        }

        // 用户名筛选
        if (!string.IsNullOrWhiteSpace(request.Username))
        {
            query = query.Where(l => l.Username != null && l.Username.Contains(request.Username));
        }

        // 模块筛选
        if (!string.IsNullOrWhiteSpace(request.Module))
        {
            query = query.Where(l => l.Module == request.Module);
        }

        // 操作筛选
        if (!string.IsNullOrWhiteSpace(request.Action))
        {
            query = query.Where(l => l.Action == request.Action);
        }

        // 状态筛选
        if (request.Status.HasValue)
        {
            query = query.Where(l => l.Status == request.Status.Value);
        }

        // 日期范围筛选
        if (request.StartDate.HasValue)
        {
            query = query.Where(l => l.CreatedAt >= request.StartDate.Value);
        }

        if (request.EndDate.HasValue)
        {
            var endDate = request.EndDate.Value.AddDays(1);
            query = query.Where(l => l.CreatedAt < endDate);
        }

        var total = await query.CountAsync();

        var list = await query
            .OrderByDescending(l => l.CreatedAt)
            .Skip((request.Page - 1) * request.PageSize)
            .Take(request.PageSize)
            .Select(l => new OperationLogDto
            {
                Id = l.Id,
                AdminUserId = l.AdminUserId,
                Username = l.Username,
                Module = l.Module,
                Action = l.Action,
                Method = l.Method,
                Url = l.Url,
                Ip = l.Ip,
                Status = l.Status,
                Duration = l.Duration,
                CreatedAt = l.CreatedAt
            })
            .ToListAsync();

        return new PagedResult<OperationLogDto>
        {
            List = list,
            Total = total,
            Page = request.Page,
            PageSize = request.PageSize
        };
    }

    /// <inheritdoc />
    public async Task<OperationLogDto> GetByIdAsync(long id)
    {
        var log = await _dbContext.OperationLogs.FindAsync(id);
        if (log == null)
        {
            throw new AdminException(AdminErrorCodes.InvalidParameter, "日志不存在");
        }

        return new OperationLogDto
        {
            Id = log.Id,
            AdminUserId = log.AdminUserId,
            Username = log.Username,
            Module = log.Module,
            Action = log.Action,
            Method = log.Method,
            Url = log.Url,
            Ip = log.Ip,
            RequestData = log.RequestData,
            ResponseData = log.ResponseData,
            Status = log.Status,
            ErrorMsg = log.ErrorMsg,
            Duration = log.Duration,
            CreatedAt = log.CreatedAt
        };
    }
}
