using System;
using System.Threading;
using System.Threading.Tasks;
using Knot.Contracts.Admin.Abstractions;
using Knot.Contracts.Auth.Domain;
using Knot.Contracts.Conversations.Abstractions;
using Knot.Contracts.Messaging.Application.Abstractions;
using Knot.Modules.Admin.Application.Admin.DTOs;
using MediatR;

namespace Knot.Modules.Admin.Application.Admin.Queries;

public record GetUserDetailsQuery(Guid UserId) : IQuery<AdminUserDto>;

internal sealed class GetUserDetailsQueryHandler : IQueryHandler<GetUserDetailsQuery, AdminUserDto>
{
    private readonly IUserRepository _userRepository;
    private readonly Knot.Contracts.Messaging.Application.Abstractions.IUserStatsService _statsService;
    private readonly IUserStatusService _statusService;

    public GetUserDetailsQueryHandler(
        IUserRepository userRepository,
        Knot.Contracts.Messaging.Application.Abstractions.IUserStatsService statsService,
        IUserStatusService statusService)
    {
        _userRepository = userRepository;
        _statsService = statsService;
        _statusService = statusService;
    }

    public async Task<Result<AdminUserDto>> Handle(GetUserDetailsQuery request, CancellationToken ct)
    {
        try
        {
            var user = await _userRepository.GetByIdAsync(request.UserId, ct);
            if (user == null)
                return Result.Failure<AdminUserDto>(new Error("Admin.GetUserDetails.NotFound", "User not found"));

            var statsMap = await _statsService.GetStatsForUsersAsync(new List<Guid> { request.UserId }, ct);
            var stats = statsMap.GetValueOrDefault(request.UserId, new Knot.Contracts.Messaging.Application.Abstractions.UserStats(0, 0L));
            var isOnline = _statusService.IsUserOnline(request.UserId.ToString());

            return Result.Success(new AdminUserDto(
                user.Id,
                user.Username ?? "unknown",
                user.DisplayName ?? "User",
                user.Email,
                user.Avatar,
                user.CreatedAt,
                isOnline,
                isOnline ? DateTime.UtcNow : (user.CreatedAt),
                user.IsBanned,
                stats.MessageCount,
                stats.StorageSize
            ));
        }
        catch (Exception ex)
        {
            return Result.Failure<AdminUserDto>(new Error("Admin.GetUserDetails.Error", $"Error getting user details: {ex.Message}"));
        }
    }
}
