using MemberCenter.Application.Abstractions;
using MemberCenter.Application.Constants;
using MemberCenter.Domain.Entities;
using MemberCenter.Infrastructure.Persistence;

namespace MemberCenter.Infrastructure.Services;

public sealed class UserConsentService : IUserConsentService
{
    private readonly MemberCenterDbContext _dbContext;
    private readonly IAuditLogWriter _auditLogWriter;

    public UserConsentService(MemberCenterDbContext dbContext, IAuditLogWriter auditLogWriter)
    {
        _dbContext = dbContext;
        _auditLogWriter = auditLogWriter;
    }

    public async Task RecordRegistrationConsentAsync(
        Guid userId,
        string registrationMethod,
        string? ipAddress,
        string? userAgent,
        CancellationToken cancellationToken = default)
    {
        var consent = new UserConsent
        {
            Id = Guid.NewGuid(),
            UserId = userId,
            TermsVersion = ConsentVersions.TermsVersion,
            PrivacyVersion = ConsentVersions.PrivacyVersion,
            RegistrationMethod = registrationMethod,
            IpAddress = Truncate(ipAddress, 100),
            UserAgent = Truncate(userAgent, 500),
            AcceptedAt = DateTimeOffset.UtcNow
        };

        _dbContext.UserConsents.Add(consent);
        await _dbContext.SaveChangesAsync(cancellationToken);

        await _auditLogWriter.WriteAsync("user", userId, "account.consent_accepted", new
        {
            user_id = userId,
            terms_version = consent.TermsVersion,
            privacy_version = consent.PrivacyVersion,
            registration_method = consent.RegistrationMethod
        });
    }

    private static string? Truncate(string? value, int maxLength)
    {
        if (string.IsNullOrWhiteSpace(value))
        {
            return null;
        }

        value = value.Trim();
        return value.Length <= maxLength ? value : value[..maxLength];
    }
}
