using Radium.DataExporter.Client.Platforms;
using Radium.DataExporter.Models.Accounts;
using Radium.DataExporter.Models.Authentication;
using Radium.DataExporter.Models.Common.Enums;
using Radium.DataExporter.Models.Common.Requests;
using Radium.DataExporter.Models.Common.Results;
using Radium.DataExporter.Models.JsonContext;
using System.Net.Http.Json;
using System.Text.Json;
using TlsSpoofing;

namespace Radium.DataExporter.Client.Networking;

public class RadiumHttpClient
{
    private readonly HttpClient _httpClient;

    public RadiumHttpClient()
    {
        _httpClient = SpoofedHttpClient.Create(new TlsFingerprint
        {
            CipherSuites = TlsFingerprint.ParseHex("0xc02b, 0xc023, 0xc009, 0xc02f, 0xc027, 0xc013, 0x009c, 0x003c, 0x002f, 0x00ff"),
            SupportedGroups = TlsFingerprint.ParseHex("0x0017, 0x0018"),
            SignatureAlgorithms = TlsFingerprint.ParseHex("0x0201, 0x0301, 0x0401, 0x0501, 0x0601, 0x0202, 0x0302, 0x0402, 0x0502, 0x0602, 0x0203, 0x0303, 0x0403, 0x0503, 0x0603"),
            AlpnProtocols = [],
            MinVersion = TlsVersion.Tls12,
            MaxVersion = TlsVersion.Tls12
        });

        _httpClient.DefaultRequestHeaders.Add("User-Agent", $"Radium.DataExporter.Client/{Constants.Version}");
    }

    public async Task<List<CachedLogin>> GetUsableCachedLoginsAsync(PlatformType platformType, string platformId)
    {
        var request = await _httpClient.GetAsync($"https://auth.rec.net/cachedLogin/forPlatformId/{platformType}/{platformId}");

        if (!request.IsSuccessStatusCode)
            return [];

        var responseStream = await request.Content.ReadAsStreamAsync();

        var cachedLogins = await JsonSerializer.DeserializeAsync(responseStream, RecNetJsonContext.Default.ListCachedLogin);

        if (cachedLogins == null)
            return [];

        return [.. cachedLogins
            .Where(x => !x.RequirePassword)
            .OrderBy(x => x.LastLoginTime)];
    }

    public async Task<List<Account>> GetAccountsBulkAsync(long[] accountIds)
    {
        var formData = accountIds
            .Select(accountId => new KeyValuePair<string, string>("id", $"{accountId}"));
        var content = new FormUrlEncodedContent(formData);

        var request = await _httpClient.PostAsync($"https://accounts.rec.net/account/bulk", content);

        if (!request.IsSuccessStatusCode)
            return [];

        var responseStream = await request.Content.ReadAsStreamAsync();

        var accounts = await JsonSerializer.DeserializeAsync(responseStream, RecNetJsonContext.Default.ListAccount);

        if (accounts == null)
            return [];

        return accounts;
    }

    public async Task<CreateJobSessionResponse> CreateJobSessionAsync(string code, long accountId, string platformId, string platformAuth)
    {
        var json = JsonContent.Create(new CompleteAuthLinkRequest
        {
            Code = code,
            AccountId = accountId,
            SteamId = platformId,
            SteamTicket = platformAuth
        },
        RecNetJsonContext.Default.CompleteAuthLinkRequest);

        var response = await _httpClient.PostAsync($"{Constants.ProdUri}api/auth-link/{PlatformManager.Instance.Platform}", json);

        var responseStream = await response.Content.ReadAsStreamAsync();

        if (response.IsSuccessStatusCode)
        {
            var result = await JsonSerializer.DeserializeAsync(
                responseStream,
                RecNetJsonContext.Default.CompleteAuthLinkResult);

            return new CreateJobSessionResponse
            {
                Result = result
            };
        }

        var error = await JsonSerializer.DeserializeAsync(responseStream, RecNetJsonContext.Default.RecNetError);

        return new CreateJobSessionResponse
        {
            Error = error
        };
    }
}