using System;
using System.Collections.Generic;
using System.Net;
using System.Net.Http;
using static BaroSeeSDK.AuthenticationProvider;

namespace BaroSeeSDK
{
    public class BaroSeeService
    {
        #region common
        public const string API_ROOT = "https://barosee.net";
        public const string API_VERSION = "/api";
        public enum DocumentFormat { PDF, HTML };
        public enum ApiEntries
        {
            auth_token,
            auth_user,
            document_subscribe,
            document_delete, 
            document_setchange,
            document_gethtml,
            document_fileinfo,
            document_getconvertedfile
        }
               
        private static Lazy<Dictionary<ApiEntries, ApiEntry>> apis = new Lazy<Dictionary<ApiEntries, ApiEntry>>(delegate ()
        {
            Dictionary<ApiEntries, ApiEntry> values = new Dictionary<ApiEntries, ApiEntry>();
            values.Add(ApiEntries.auth_token, new ApiEntry() { Uri = "auth/token", Method = HttpMethod.Post });
            values.Add(ApiEntries.auth_user, new ApiEntry() { Uri = "auth/user", Method = HttpMethod.Post });
            values.Add(ApiEntries.document_subscribe, new ApiEntry() { Uri = API_VERSION + "/document/subscribe", Method = HttpMethod.Post });
            values.Add(ApiEntries.document_delete, new ApiEntry() { Uri = API_VERSION + "/document/delete", Method = HttpMethod.Post });
            values.Add(ApiEntries.document_setchange, new ApiEntry() { Uri = API_VERSION + "/document/setchange", Method = HttpMethod.Post });
            values.Add(ApiEntries.document_gethtml, new ApiEntry() { Uri = API_VERSION + "/document/gethtml", Method = HttpMethod.Post });
            values.Add(ApiEntries.document_fileinfo, new ApiEntry() { Uri = API_VERSION + "/document/info", Method = HttpMethod.Post });
            values.Add(ApiEntries.document_getconvertedfile, new ApiEntry() { Uri = API_VERSION + "/document/file", Method = HttpMethod.Post });
            return values;
        });

        public static Dictionary<ApiEntries, ApiEntry> Apis = apis.Value;
        #endregion
        //-------------------------------------        
        private ErrorHandler _GlobalErrorHandler;
        private void Configure(AuthenticationProvider authProvider, ErrorHandler errorHandler = null)
        {
            _GlobalErrorHandler = errorHandler;
            if (authProvider == null) errorHandler.Invoke("BaroSeeSDK", HttpStatusCode.Unauthorized, "Invalid authorization provider");
            this.AuthenticationProvider = authProvider;
            this.DocumentAPI = new DocumentAPI(authProvider);
        }

        #region public
        public BaroSeeService(string publicKey, string privateKey, ErrorHandler errorHandler = null) {
            Configure(new AuthenticationProvider(publicKey, privateKey, errorHandler));
        }
        public BaroSeeService(AccessToken token, ErrorHandler errorHandler = null) {
            Configure(new AuthenticationProvider(token, errorHandler));
        }        

        public IAuthenticationProvider AuthenticationProvider { get; private set; }
        public IDocumentAPI  DocumentAPI { get; private set; }
        #endregion
    }    

    #region Shared Classes
    public delegate void ErrorHandler(string sender, HttpStatusCode code, String message);

    public class ApiEntry
    {
        public string Uri { get; set; }
        public HttpMethod Method { get; set; }
        public string Link { get { return BaroSeeService.API_ROOT + "/" + Uri; } }
    }

    public class AccessToken
    {
        public String Value { get; set; }
        public DateTime? ExpiredAt { get; set; }
        public bool IsExpires { get { return ExpiredAt.HasValue? ExpiredAt.Value < DateTime.UtcNow : false; } }
    }
    #endregion
}
