using System.Net.Http.Headers;
using System.Net.Http.Json;
using System.Text.Json;

namespace RelayClient;

public class ServerAPI
{
    static HttpClient client = new HttpClient { BaseAddress = new Uri("http://localhost:5000/") };
    
    public static void setupClient()
    {
        client.DefaultRequestHeaders.Accept.Clear();
        client.DefaultRequestHeaders.Accept.Add(
            new MediaTypeWithQualityHeaderValue("application/json"));
    }
    
    public static async Task<Uri> PostOfferAsync(DBOffer offer)
    {
        HttpResponseMessage response = await client.PostAsJsonAsync(
            "api/rtc/offer", offer);
        response.EnsureSuccessStatusCode();
        return response.Headers.Location;
    }

    public static async Task<Uri> GetAllOffersAsync()
    {
        HttpResponseMessage response = await client.GetAsync("api/rtc/offers");
        response.EnsureSuccessStatusCode();
        return response.Headers.Location;
    }

    public static async Task<bool> GetIsChannelActiveAsync(string channelId)
    {
        HttpResponseMessage response = await client.GetAsync($"api/rtc/active/{channelId}");
        response.EnsureSuccessStatusCode();
        return  bool.Parse(response.Content.ReadAsStringAsync().Result);
    }

    public static async Task<RtcDescription> GetOffersForChannelAsync(string channelId)
    {
        HttpResponseMessage response = await client.GetAsync($"api/rtc/offers/{channelId}");
        response.EnsureSuccessStatusCode();
        RtcDescription? offer = JsonSerializer.Deserialize<RtcDescription>(await response.Content.ReadAsStringAsync());
        return offer;
    }

    public static async Task<Uri?> PostAnswerAsync(DBOffer answer)
    {
        HttpResponseMessage response = await client.PostAsJsonAsync("api/rtc/answer", answer);
        var body = await response.Content.ReadAsStringAsync();

        Console.WriteLine("PostAnswerAsync status: " + response.StatusCode);
        Console.WriteLine("PostAnswerAsync body: " + body);

        response.EnsureSuccessStatusCode();
        return response.Headers.Location;
    }

    public static async Task<Uri> GetAnswersForChannelAsync(string channelId)
    {
        HttpResponseMessage response = await client.GetAsync($"api/rtc/answers/{channelId}");
        response.EnsureSuccessStatusCode();
        return response.Headers.Location;
    }

    public static async Task<Uri> GetLatestAnswerForChannelAsync(string channelId)
    {
        HttpResponseMessage response = await client.GetAsync($"api/rtc/latest/{channelId}");
        response.EnsureSuccessStatusCode();
        return response.Headers.Location;
    }

    public static async Task<Uri> PostIceCandidateAsync(DBIceCandidate candidate)
    {
        HttpResponseMessage response = await client.PostAsJsonAsync("api/rtc/candidate", candidate);
        response.EnsureSuccessStatusCode();
        return response.Headers.Location;
    }

    public static async Task<Uri> GetIceCandidatesForChannelAsync(string channelId)
    {
        HttpResponseMessage response = await client.GetAsync($"api/rtc/candidates/{channelId}");
        response.EnsureSuccessStatusCode();
        return response.Headers.Location;
    }

    public static async Task<Uri> GetIceCandidatesForChannelByUserAsync(string channelId, string userId, string directions)
    {
        HttpResponseMessage response = await client.GetAsync($"api/rtc/candidates/{channelId}/{userId}/{directions}");
        response.EnsureSuccessStatusCode();
        return response.Headers.Location;
    }

    public static async Task<Uri> PostLeave(RtcLeave leave)
    {
        HttpResponseMessage response = await client.PostAsJsonAsync("api/rtc/leave", leave);
        response.EnsureSuccessStatusCode();
        return response.Headers.Location;
    }
    
    public static async Task<RtcDescription?> GetAnswerForChannelAsync(string? channelId)
    {
        if (string.IsNullOrWhiteSpace(channelId))
            return null;

        HttpResponseMessage response = await client.GetAsync($"api/rtc/answer/{channelId}");
        if (!response.IsSuccessStatusCode)
            return null;

        var json = await response.Content.ReadAsStringAsync();
        return JsonSerializer.Deserialize<RtcDescription>(json);
    }
    
    public static async Task<List<string>> GetRtcParticipantsAsync(string? channelId)
    {
        if (string.IsNullOrWhiteSpace(channelId))
            return new List<string>();

        HttpResponseMessage response = await client.GetAsync($"api/rtc/participants/{channelId}");
        response.EnsureSuccessStatusCode();

        var json = await response.Content.ReadAsStringAsync();

        return JsonSerializer.Deserialize<List<string>>(json) ?? new List<string>();
    }
}

public class RtcDescription
{
    public string type { get; set; }
    public string sdp { get; set; }
}

public class DBOffer
{
    public required string ChannelId { get; set; }
    public required string Username { get; set; }
    public required RtcDescription SessionDescription { get; set; }
}
public class IceCandidate
{
    public required string candidate { get; set; }
    public required string sdpMid { get; set; }
    public required int sdpMLineIndex { get; set; }
    public required string usernameFragment { get; set; }
    
}

public class DBIceCandidate
{
    public required string ChannelId { get; set; }
    public required string Username { get; set; }
    public required IceCandidate Candidate { get; set; }
}

public class RtcLeave
{
    public string ChannelId { get; set; }
    public string Username { get; set; }
}