using Newtonsoft.Json;
using System;
using System.Linq;
using System.Net.Http;
using System.Net.Http.Headers;
using System.Text;
using System.Threading.Tasks;
using System.Net;
using System.Collections.Generic;
using Knoks.Framework.Extentions;
using Microsoft.Extensions.Logging;

namespace Knoks.Framework.Services
{
    public class PlivoSmsService : ISmsService, IDisposable
    {
        private class SendMessageResponse
        {
            [JsonProperty("message")]
            public string Message { get; set; }
            [JsonProperty("error")]
            public string Error { get; set; }
            [JsonProperty("api_id")]
            public string ApiId { get; set; }
            [JsonProperty("message_uuid")]
            public IList<string> MessageUuid { get; set; }

            private string _json;
            [JsonIgnore]
            public string Json { get { return _json ?? (_json = JsonConvert.SerializeObject(this, Formatting.Indented)); } }

            public override string ToString() { return Json; }
        }

        private ILogger<PlivoSmsService> _logger;
        private HttpClient _httpClient;
        
        public PlivoSmsService(ILogger<PlivoSmsService> logger, PlivoSmsSettings settings)
        {
            _logger = logger;
            _httpClient = new HttpClient();
            _httpClient.BaseAddress = new Uri(settings.BaseAddress.TrimEnd('/') + $"/{settings.AuthId}/");
            _httpClient.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Basic", Convert.ToBase64String(ASCIIEncoding.UTF8.GetBytes($"{settings.AuthId}:{settings.AuthToken}")));
        }

        public void Dispose()
        {
            if (_httpClient != null)
                _httpClient.Dispose();
        }

        public async Task<bool> SendMessage(string text, string srcNumber, params string[] dstNumbers)
        {
            try
            {
                var res = await _httpClient.PostAsync("Message/", new StringContent(JsonConvert.SerializeObject(new
                {
                    src = srcNumber.RemoveNonDigits(),
                    dst = string.Join("<", dstNumbers.Select(number => number.RemoveNonDigits())),
                    text = text
                }), Encoding.UTF8, "application/json"));

                if (res.StatusCode != HttpStatusCode.Accepted)
                {
                    //Log error result.
                    //var response = JsonConvert.DeserializeObject<SendMessageResponse>(await res.Content.ReadAsStringAsync());
                    return false;
                }

                return true;
            }
            catch(Exception ex)
            {
                _logger.LogError(ex.Message);
                return false;
            }
        }
    }
}
