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 FollowUserCommand.
/// VI: Handler cho FollowUserCommand.
/// </summary>
public class FollowUserCommandHandler : IRequestHandler<FollowUserCommand, FollowUserResult>
{
    private readonly IRelationshipRepository _relationshipRepository;
    private readonly IUserBlockRepository _userBlockRepository;
    private readonly ILogger<FollowUserCommandHandler> _logger;

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

    public async Task<FollowUserResult> Handle(FollowUserCommand request, CancellationToken cancellationToken)
    {
        // EN: Cannot follow yourself
        // VI: Không thể tự follow chính mình
        if (request.FollowerId == request.FolloweeId)
        {
            throw new SocialDomainException("Cannot follow yourself");
        }

        // 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.FollowerId, request.FolloweeId);
        if (hasBlock)
        {
            throw new SocialDomainException("Cannot follow blocked user");
        }

        // EN: Check if already following
        // VI: Kiểm tra xem đã follow chưa
        var existingFollow = await _relationshipRepository.GetByUsersAndTypeAsync(
            request.FollowerId, 
            request.FolloweeId, 
            RelationshipType.Following);

        if (existingFollow != null && existingFollow.StatusId == RelationshipStatus.Accepted.Id)
        {
            throw new SocialDomainException("Already following this user");
        }

        // EN: Create new following relationship (auto-accepted)
        // VI: Tạo quan hệ following mới (tự động chấp nhận)
        var relationship = new Relationship(
            request.FollowerId, 
            request.FolloweeId, 
            RelationshipType.Following);
        
        // EN: Following is auto-accepted (no approval needed)
        // VI: Following được tự động chấp nhận (không cần phê duyệt)
        relationship.Accept();

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

        _logger.LogInformation("User {FollowerId} started following {FolloweeId}",
            request.FollowerId, request.FolloweeId);

        return new FollowUserResult(relationship.Id, true);
    }
}
