using System.Globalization;
using MySqlConnector;

namespace ApiDenuncias.Services;

public sealed class UserComplaintAccessService
{
    private readonly MySqlConnectionStringProvider _connectionStringProvider;

    public UserComplaintAccessService(MySqlConnectionStringProvider connectionStringProvider)
    {
        _connectionStringProvider = connectionStringProvider;
    }

    public async Task<HashSet<int>> GetAllowedComplaintIdsAsync(string username, CancellationToken cancellationToken = default)
    {
        if (string.IsNullOrWhiteSpace(username))
        {
            return [];
        }

        const string sql = """
            SELECT DISTINCT ir.imported_complaint_report_id
            FROM inbox_reports ir
            INNER JOIN user_inbox_reports uir ON uir.inbox_report_id = ir.id
            INNER JOIN app_users au ON au.id = uir.app_user_id
            WHERE au.username = @username
              AND ir.imported_complaint_report_id IS NOT NULL
              AND uir.download_count > 0;
            """;

        var connectionString = await _connectionStringProvider.GetConnectionStringAsync(cancellationToken);
        await using var connection = new MySqlConnection(connectionString);
        await connection.OpenAsync(cancellationToken);

        await using var command = new MySqlCommand(sql, connection);
        command.Parameters.AddWithValue("@username", username.Trim());

        var result = new HashSet<int>();
        await using var reader = await command.ExecuteReaderAsync(cancellationToken);
        while (await reader.ReadAsync(cancellationToken))
        {
            result.Add(Convert.ToInt32(reader.GetValue(0), CultureInfo.InvariantCulture));
        }

        return result;
    }

    public async Task<bool> CanAccessComplaintAsync(string username, int complaintId, CancellationToken cancellationToken = default)
    {
        var allowedIds = await GetAllowedComplaintIdsAsync(username, cancellationToken);
        return allowedIds.Contains(complaintId);
    }
}
