using Hncore.Infrastructure.Service;
using Hncore.Pass.Vpn.Domain;
using Hncore.Pass.Vpn.Request.Product;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Net.Http;
using System.Threading.Tasks;
using Hncore.Infrastructure.Extension;
using Hncore.Infrastructure.WebApi;
using System.Diagnostics;
using System.IO;
using System.Net;
using Microsoft.EntityFrameworkCore;
using Hncore.Pass.Vpn.Model;

namespace Hncore.Pass.Vpn.Service
{
    public abstract class AgentClientBaseService
    {
        protected string BaseUrl { get; set; }
        protected string Token { get; set; }
        string LoginUrl { get; set; }
        string LoginCodeUrl { get; set; }
        string RefrushTokenUrl { get; set; }
        string SingleAddUrl { get; set; }
        string SingleReAddUrl { get; set; }
        string MuiltAddUrl { get; set; }
        string RefundUrl { get; set; }
        string OnlineUrl { get; set; }
        string KIllUrl { get; set; }
        string UpdateUrl { get; set; }
        public string ClientName { get; set; }
        public string Raw { get; set; }

        IHttpClientFactory m_HttpClientFactory;       
        public AgentClientBaseService(IHttpClientFactory httpClientFactory)
        {
            m_HttpClientFactory = httpClientFactory;         
        }

        public ProductEntity Product { get; set; }

        public void Init(string BaseUrl,string Token)
        {
            this.BaseUrl = BaseUrl;
            this.Token = Token;
        }

        public virtual string GetOpTitle(string op,string account)
        {
            return $"{this.ClientName}_{op}_{account}";
        }
 
        protected virtual HttpClient CreateHttpClient(bool autoCooke = true)
        {
            var client = m_HttpClientFactory.CreateClient("agentClient");
            client.BaseAddress = new System.Uri(this.BaseUrl);

          

            if (this.Token.Has()&& autoCooke)
            {
                AddCookie(client, this.Token);
            }        
            return client;
        }

        public virtual string MD5(string password) {
           byte[] textBytes = System.Text.Encoding.Default.GetBytes(password);
            try {
                System.Security.Cryptography.MD5CryptoServiceProvider cryptHandler;
                cryptHandler = new System.Security.Cryptography.MD5CryptoServiceProvider();
                byte[] hash = cryptHandler.ComputeHash (textBytes);
                string ret = "";
                foreach (byte a in hash) {
                    if (a<16)
                        ret += "0" + a.ToString ("x");
                    else
                        ret += a.ToString ("x");
                }
                return ret ;
            }
            catch {
                throw;
            } 

        } 

        protected virtual void AddCookie(HttpClient client, string cookie)
        {
            client.DefaultRequestHeaders.Remove("Cookie");
            client.DefaultRequestHeaders.Add("Cookie", cookie);
            client.DefaultRequestHeaders.Add("Authorization", "Bearer " + cookie);
        }
        public string GetCookie(HttpResponseMessage resp, string name)
        {
            if (resp.Headers.TryGetValues("Set-Cookie", out IEnumerable<string> cookies))
            {
                foreach (var cookie in cookies)
                {
                    var ret = cookie.Split(";").FirstOrDefault(m => m.IndexOf(name) != -1);
                    if (ret.Has())
                        return ret;
                }
            }
            return "";
        }
        public string GetCookies(HttpResponseMessage resp)
        {
            if (resp.Headers.TryGetValues("Set-Cookie", out IEnumerable<string> cookies))
            {              
                return string.Join(";", cookies);
            }
            return "";
        }
        protected string GetCookieValue(string cookies, string name)
        {
            foreach (var item in cookies.Split(";"))
            {
                var token = item.Split("=");
                if (token.Length == 2 && token[0] == name)
                {
                    return token[1];
                }
            }
            return "";
        }

        public virtual async Task<int> RefrushStatus()
        {
            return 0;
        }
        public virtual async Task<(byte[], string)> GetCode()
        {
            return (null, "");
        }
        public virtual async Task<ApiResult> Login(AgentLoginRequest request)
        {            
            return new ApiResult();
        }
        public virtual bool CheckAccount(int productId,List<string> accounts)
        {
            return false;
        }

        /// <summary>
        /// 新开
        /// </summary>
        /// <param name="packageId"></param>
        /// <param name="account"></param>
        /// <param name="pwd"></param>
        /// <returns></returns>
        public virtual async Task<ApiResult> NewAccount(string  packageKey, string account,string pwd,int connCount=1,int accountType=1, int payCount = 1)
        {
            return new ApiResult();
        }
        public virtual async Task<ApiResult> NewMuiltAccount(string packageKey, string account, string pwd, int connCount = 1, int accountType = 1, int startNum = 0, int endNum = 1)
        {
            return new ApiResult();
        }


        /// <summary>
        /// 续费
        /// </summary>
        /// <param name="productId"></param>
        /// <param name="account"></param>
        /// <param name="pwd"></param>
        /// <returns></returns>
        public virtual async Task<ApiResult> NewReAccount(string packageKey,string account,int connCount, int payCount = 1)
        {
            return new ApiResult();
        }
        /// <summary>
        /// 删除账号
        /// </summary>
        /// <param name="productId"></param>
        /// <param name="account"></param>
        /// <returns></returns>
        public virtual async Task<bool> DeleteAccount(string account)
        {
            return true;
        }
        /// <summary>
        /// 得到账号信息
        /// </summary>
        /// <param name="productId"></param>
        /// <param name="account"></param>
        /// <returns></returns>
        public virtual async Task<ApiResult<OriginAccountModel>> GetAccountInfo(string account, bool isTest = false)
        {
            return new ApiResult<OriginAccountModel>();
        }
        /// <summary>
        /// 修改账号密码
        /// </summary>
        /// <param name="productId"></param>
        /// <param name="account"></param>
        /// <param name="pwd"></param>
        /// <returns></returns>
        public virtual async Task<bool> UpdateAccountPwd(string account,string pwd)
        {
            return true;
        }
        /// <summary>
        /// 退款
        /// </summary>
        /// <param name="packageId"></param>
        /// <param name="account"></param>
        /// <returns></returns>
        public virtual async Task<ApiResult> Refund(string account, string packageKey, int days)
        {
            return new ApiResult();
        }
        /// <summary>
        /// 是否在线
        /// </summary>
        /// <param name="productId"></param>
        /// <param name="account"></param>
        /// <returns></returns>
        public virtual async Task<ApiResult<List<OriginAccountOnlineModel>>> OnLine(string account)
        {
            return new ApiResult<List<OriginAccountOnlineModel>>();
        }
        /// <summary>
        /// 踢号
        /// </summary>
        /// <param name="productId"></param>
        /// <param name="account"></param>
        /// <returns></returns>
        public virtual async Task<bool> KillOut(string account)
        {
            return true;
        }
        /// <summary>
        /// 是否存在
        /// </summary>      
        /// <param name="account"></param>
        /// <returns></returns>
        public virtual async Task<bool> Exist(string account)
        {           
            return true;
        }
    }
}
