using MediatR;
using SocialService.Domain.AggregatesModel.RelationshipAggregate;
using SocialService.Domain.AggregatesModel.UserBlockAggregate;
using SocialService.Domain.Exceptions;

namespace SocialService.API.Application.Commands;

/// <summary>
/// EN: Handler for SendFriendRequestCommand.
/// VI: Handler cho SendFriendRequestCommand.
/// </summary>
public class SendFriendRequestCommandHandler : IRequestHandler<SendFriendRequestCommand, SendFriendRequestResult>
{
    private readonly IRelationshipRepository _relationshipRepository;
    private readonly IUserBlockRepository _userBlockRepository;
    private readonly ILogger<SendFriendRequestCommandHandler> _logger;

    public SendFriendRequestCommandHandler(
        IRelationshipRepository relationshipRepository,
        IUserBlockRepository userBlockRepository,
        ILogger<SendFriendRequestCommandHandler> logger)
    {
        _relationshipRepository = relationshipRepository;
        _userBlockRepository = userBlockRepository;
        _logger = logger;
    }

    public async Task<SendFriendRequestResult> Handle(SendFriendRequestCommand request, CancellationToken cancellationToken)
    {
        // EN: Check if users have blocked each other
        // VI: Kiểm tra xem users có block lẫn nhau không
        var hasBlock = await _userBlockRepository.HasBlockBetweenAsync(request.RequesterId, request.AddresseeId);
        if (hasBlock)
        {
            throw new SocialDomainException("Cannot send friend request to blocked user");
        }

        // EN: Check if relationship already exists
        // VI: Kiểm tra xem quan hệ đã tồn tại chưa
        var existingRelationship = await _relationshipRepository.GetByUsersAndTypeAsync(
            request.RequesterId, 
            request.AddresseeId, 
            RelationshipType.Friendship);

        if (existingRelationship != null)
        {
            if (existingRelationship.StatusId == RelationshipStatus.Accepted.Id)
            {
                throw new SocialDomainException("Users are already friends");
            }
            if (existingRelationship.StatusId == RelationshipStatus.Pending.Id)
            {
                throw new SocialDomainException("Friend request already pending");
            }
        }

        // EN: Check if reverse relationship exists (other user sent request)
        // VI: Kiểm tra xem quan hệ ngược có tồn tại không (user khác đã gửi yêu cầu)
        var reverseRelationship = await _relationshipRepository.GetByUsersAndTypeAsync(
            request.AddresseeId, 
            request.RequesterId,
            RelationshipType.Friendship);

        if (reverseRelationship != null && reverseRelationship.StatusId == RelationshipStatus.Pending.Id)
        {
            // EN: Auto-accept if the other user already sent a request
            // VI: Tự động chấp nhận nếu user kia đã gửi yêu cầu
            reverseRelationship.Accept();
            _relationshipRepository.Update(reverseRelationship);
            await _relationshipRepository.UnitOfWork.SaveEntitiesAsync(cancellationToken);

            _logger.LogInformation("Auto-accepted mutual friend request between {RequesterId} and {AddresseeId}",
                request.RequesterId, request.AddresseeId);

            return new SendFriendRequestResult(reverseRelationship.Id, "Accepted");
        }

        // EN: Create new friend request
        // VI: Tạo yêu cầu kết bạn mới
        var relationship = new Relationship(
            request.RequesterId, 
            request.AddresseeId, 
            RelationshipType.Friendship);

        _relationshipRepository.Add(relationship);
        await _relationshipRepository.UnitOfWork.SaveEntitiesAsync(cancellationToken);

        _logger.LogInformation("Friend request sent from {RequesterId} to {AddresseeId}",
            request.RequesterId, request.AddresseeId);

        return new SendFriendRequestResult(relationship.Id, "Pending");
    }
}
