namespace MontoyaTech.Rest.Net.Example;

using System;
using System.Net;
using System.Net.Http;
using Newtonsoft.Json;

public class Client
{
    public string BaseUrl;

    public CookieContainer CookieContainer;

    public HttpClientHandler ClientHandler;

    public HttpClient HttpClient;

    public TestApi Test;

    public AuthApi Auth;

    public Client(string baseUrl)
    {
        if (string.IsNullOrWhiteSpace(baseUrl))
            throw new ArgumentException("baseUrl must not be null or whitespace.");

        if (baseUrl.EndsWith('/'))
            baseUrl = baseUrl.Substring(0, baseUrl.Length - 1);

        this.BaseUrl = baseUrl;

        this.CookieContainer = new CookieContainer();

        this.ClientHandler = new HttpClientHandler()
        {
            AllowAutoRedirect = true,
            UseCookies = true,
            CookieContainer = this.CookieContainer,
            AutomaticDecompression = DecompressionMethods.GZip | DecompressionMethods.Deflate
        };

        this.HttpClient = new HttpClient(this.ClientHandler);

        this.HttpClient.DefaultRequestHeaders.Add("Accept", "*/*");

        this.HttpClient.DefaultRequestHeaders.Add("Connection", "keep-alive");

        this.HttpClient.DefaultRequestHeaders.Add("Accept-Encoding", "identity");

        this.Test = new TestApi(this);

        this.Auth = new AuthApi(this);
    }

    public class TestApi
    {
        public Client Client;

        public TestApi(Client client)
        {
            this.Client = client;
        }

        public string Status()
        {
            var message = new HttpRequestMessage(HttpMethod.Get, $"{this.Client.BaseUrl}/status");

            var response = this.Client.HttpClient.Send(message);

            if (response.StatusCode == HttpStatusCode.OK)
                return JsonConvert.DeserializeObject<string>(response.Content.ReadAsStringAsync().GetAwaiter().GetResult());
            else
                throw new Exception("Unexpected Http Response StatusCode:" + response.StatusCode);
        }

        public string Add(double a, double b)
        {
            var message = new HttpRequestMessage(HttpMethod.Post, $"{this.Client.BaseUrl}/add/{a}/{b}");

            var response = this.Client.HttpClient.Send(message);

            if (response.StatusCode == HttpStatusCode.OK)
                return JsonConvert.DeserializeObject<string>(response.Content.ReadAsStringAsync().GetAwaiter().GetResult());
            else
                throw new Exception("Unexpected Http Response StatusCode:" + response.StatusCode);
        }
    }

    public class AuthApi
    {
        public Client Client;

        public AuthApi(Client client)
        {
            this.Client = client;
        }

        public bool UserExists(string name)
        {
            var message = new HttpRequestMessage(HttpMethod.Get, $"{this.Client.BaseUrl}/auth/{name}");

            var response = this.Client.HttpClient.Send(message);

            if (response.StatusCode == HttpStatusCode.OK)
                return bool.Parse(response.Content.ReadAsStringAsync().GetAwaiter().GetResult());
            else
                throw new Exception("Unexpected Http Response StatusCode:" + response.StatusCode);
        }

        public void Signup(User request)
        {
            var message = new HttpRequestMessage(HttpMethod.Post, $"{this.Client.BaseUrl}/auth/signup");

            message.Content = new StringContent(JsonConvert.SerializeObject(request));

            var response = this.Client.HttpClient.Send(message);

            if (response.StatusCode != HttpStatusCode.OK)
                throw new Exception("Unexpected Http Response StatusCode:" + response.StatusCode);
        }

        public User Get()
        {
            var message = new HttpRequestMessage(HttpMethod.Get, $"{this.Client.BaseUrl}/auth");

            var response = this.Client.HttpClient.Send(message);

            if (response.StatusCode == HttpStatusCode.OK)
                return JsonConvert.DeserializeObject<User>(response.Content.ReadAsStringAsync().GetAwaiter().GetResult());
            else
                throw new Exception("Unexpected Http Response StatusCode:" + response.StatusCode);
        }
    }

    public class User
    {
        public string Name;

        public System.Collections.Generic.List<string> List;

        public ulong Property { get; set; }
    }
}