using System;
using System.Collections.Generic;
using System.Linq;
using Knot.Shared.Kernel;
using Microsoft.EntityFrameworkCore;
using System.Threading;
using System.Threading.Tasks;
using Knot.Modules.Relations.Application.Abstractions;
using Knot.Modules.Relations.Domain;

namespace Knot.Modules.Relations.Application.Contacts;

public record SyncReplicasCommand() : ICommand;

internal sealed class SyncReplicasCommandHandler : ICommandHandler<SyncReplicasCommand>
{
    private readonly IContactsDbContext _context;
    private readonly Knot.Contracts.Auth.Infrastructure.Persistence.IAuthDbContext _authContext;

    public SyncReplicasCommandHandler(IContactsDbContext context, Knot.Contracts.Auth.Infrastructure.Persistence.IAuthDbContext authContext)
    {
        _context = context;
        _authContext = authContext;
    }

    public async Task<Result> Handle(SyncReplicasCommand request, CancellationToken cancellationToken)
    {
        // 1. Fetch ALL users from Auth (since it's a repair operation)
        var users = await _authContext.Users.ToListAsync(cancellationToken);
        
        // 2. Fetch existing IDs in Replicas
        var existingIds = await _context.UserReplicas.Select(r => r.Id).ToListAsync(cancellationToken);
        
        // 3. Find missing ones
        var missing = users.Where(u => !existingIds.Contains(u.Id)).ToList();
        
        foreach (var user in missing)
        {
            var replica = UserReplica.Create(
                user.Id,
                user.Username,
                user.DisplayName,
                user.Avatar ?? string.Empty,
                user.IsExternal,
                user.Domain
            );
            _context.UserReplicas.Add(replica);
        }

        await _context.SaveChangesAsync(cancellationToken);
        return Result.Success();
    }
}
