    using Furion;
using Furion.DependencyInjection;
using Furion.RemoteRequest.Extensions;
using MessagePack;
using Nirvana.Common;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Net.Http;
using System.Text;
using System.Threading.Tasks;

namespace Waste.Application
{
    /// <summary>
    /// 苏州设备对接平台
    /// </summary>
    public class SuZhouService : ISuZhouService, ITransient
    {
        private static string ApiUrl = App.Configuration["SZDevPlatSetting:ApiUrl"];
        private static string UserId = App.Configuration["SZDevPlatSetting:UserId"];
        private static string ApiSecret = App.Configuration["SZDevPlatSetting:ApiSecret"];
        private static string ApiSecretHash = App.Configuration["SZDevPlatSetting:ApiSecretHash"];
        private readonly IHttpClientFactory _clientFactory;
        private readonly ILoggerService _loggerService;
        public SuZhouService(IHttpClientFactory clientFactory, ILoggerService loggerService)
        {
            _clientFactory = clientFactory;
            _loggerService = loggerService;
        }
        /// <summary>
        ///  分页查询当前账号下存在的地产区域数据
        /// </summary>
        /// <param name="page"></param>
        /// <param name="size"></param>
        /// <param name="search"></param>
        /// <returns></returns>
        public async Task<ResultInfo> GetEstatesAsync(int page = 1, int size = 10, string search = "")
        {

            var url = $"{ApiUrl}/api/estates?page={page}&size={size}&search={search}";
            var response = await GetDataAsync(url, 1, "");
            var resdata = await response.Content.ReadAsByteArrayAsync();
            var s2c_dto = MessagePackSerializer.Deserialize<EstatesBaseS2CDto<EstatesS2CDto>>(resdata);
            if (response.IsSuccessStatusCode)
            {
                return new ResultInfo(ResultState.SUCCESS, "success", s2c_dto);
            }
            else
            {
                var msg = await response.Content.ReadAsStringAsync();
                return new ResultInfo(ResultState.FAIL, msg);
            }
        }
        /// <summary>
        /// 查询地产区域信息
        /// </summary>
        /// <param name="id"></param>
        /// <returns></returns>
        public async Task<ResultInfo> GetEstatesByIdAsync(string id)
        {
            var url = $"{ApiUrl}/api/estates/{id}";
            var response = await GetDataAsync(url, 1, "");
            var resdata = await response.Content.ReadAsByteArrayAsync();
            var s2c_dto = MessagePackSerializer.Deserialize<EstatesS2CDto>(resdata);
            if (response.IsSuccessStatusCode)
            {
                return new ResultInfo(ResultState.SUCCESS, "success", s2c_dto);
            }
            else
            {
                var msg = await response.Content.ReadAsStringAsync();
                return new ResultInfo(ResultState.FAIL, msg);
            }
        }
        /// <summary>
        /// Hello接口GET测试
        /// </summary>
        /// <param name="greet"></param>
        /// <returns></returns>
        public async Task<ResultInfo> GetHelloAsync(string greet)
        {
            var url = $"{ApiUrl}/api/hello/{greet}";
            var response = await GetDataAsync(url, 2, greet);
            var resdata = await response.Content.ReadAsStringAsync();
            var returndata = "";
            if (response.IsSuccessStatusCode)
            {
                returndata = $"成功:{resdata}";
            }
            else
            {
                returndata = $"失败:{resdata}";
            }
            return new ResultInfo(ResultState.SUCCESS, "success", returndata);
        }
        /// <summary>
        /// 添加地产区域信息
        /// </summary>
        /// <param name="estatesC2SDto"></param>
        /// <returns></returns>
        public async Task<ResultInfo> PostEstatesAsync(EstatesC2SDto estatesC2SDto)
        {
            var url = $"{ApiUrl}/api/estates";
            string[] paramlist = new string[] {
                estatesC2SDto.Code,estatesC2SDto.Name,estatesC2SDto.Addr,estatesC2SDto.City,estatesC2SDto.Area,estatesC2SDto.Street
            };
            var response = await PostDataAsync(url, 1, estatesC2SDto, paramlist);
            var resdata = await response.Content.ReadAsByteArrayAsync();
            if (response.IsSuccessStatusCode)
            {
                var s2c_dto = MessagePackSerializer.Deserialize<EstatesS2CDto>(resdata);
                return new ResultInfo(ResultState.SUCCESS, "success", s2c_dto.id);
            }
            else
            {
                var msg = await response.Content.ReadAsStringAsync();
                return new ResultInfo(ResultState.FAIL, msg);
            }
        }
        /// <summary>
        /// 向服务端推送测试用垃圾采集数据
        /// </summary>
        /// <param name="garbageC2SDto"></param>
        /// <returns></returns>
        public async Task<ResultInfo> PostGarbagesAsync(GarbageC2SDto garbageC2SDto)
        {
            var url = $"{ApiUrl}/api/garbages";
            garbageC2SDto.ScanningTime = GetTimestamp();
            string[] paramlist = new string[] {
                garbageC2SDto.Weight.ToString(),garbageC2SDto.Trash,garbageC2SDto.Type.ToString(),garbageC2SDto.ScanningTime.ToString(),garbageC2SDto.DStatus.ToString()
            };
            int timestamp = GetTimestamp();
            int nonce = GetNonce();
            string sign = GetUserApiSign("lsBThmYBYUMrmwkl", paramlist);
            var c2s_dto = new SuZhouPostApiBaseDto<GarbageC2SDto>
            {
                Data = garbageC2SDto,
                SecretHash = "bfbaf98fb5b343b2",
                Nonce = nonce,
                Signature = sign,
                TimeStamp = timestamp,
                DeviceId = "08d9588d-4796-48f9-8c5b-f28f271b51d0"
            };
            var request = new HttpRequestMessage(HttpMethod.Post, url);
            var bytes = MessagePackSerializer.Serialize(c2s_dto);
            request.Content = new ByteArrayContent(bytes);
            request.Headers.Add("Accept", "application/x-msgpack");
            request.Content.Headers.Add("Content-Type", "application/x-msgpack");
            var client = _clientFactory.CreateClient();
            var response = await client.SendAsync(request);
            if (response.IsSuccessStatusCode)
            {
                return new ResultInfo(ResultState.SUCCESS, "success");
            }
            else
            {
                var msg = await response.Content.ReadAsStringAsync();
                return new ResultInfo(ResultState.FAIL, msg);
            }
        }
        /// <summary>
        /// Hello接口Post测试
        /// </summary>
        /// <param name="greet"></param>
        /// <returns></returns>
        public async Task<ResultInfo> PostHelloAsync(string greet)
        {
            var url = $"{ApiUrl}/api/hello";
            var hello_dto = new HelloC2SDto
            {
                Greet = greet
            };
            var response = await PostDataAsync(url, 1, hello_dto, greet);
            var resdata = await response.Content.ReadAsByteArrayAsync();
            var s2c_dto = MessagePackSerializer.Deserialize<HelloS2CDto>(resdata);
            var returndata = "";
            if (response.IsSuccessStatusCode)
            {
                returndata = $"成功:{s2c_dto.Message},{s2c_dto.Code}";
            }
            else
            {
                returndata = $"失败:{s2c_dto.Message},{s2c_dto.Code}";
            }
            return new ResultInfo(ResultState.SUCCESS, "success", returndata);
        }
        /// <summary>
        /// 获取时间戳
        /// </summary>
        /// <returns></returns>
        public  int GetTimestamp()
        {
            DateTime dateTimeStart = TimeZoneInfo.ConvertTimeToUtc(new DateTime(1970, 1, 1, 8, 0, 0));
            int timestamp = Convert.ToInt32((DateTime.Now - dateTimeStart).TotalSeconds);
            return timestamp;
        }

        /// <summary>
        /// 获取UTC时间戳
        /// </summary>
        /// <returns></returns>
        public int GetUTCTimestamp()
        {
            DateTime utcTime = TimeZoneInfo.ConvertTimeToUtc(DateTime.Now);
            DateTime utcStartTime = new DateTime(1970, 1, 1, 0, 0, 0, 0);
            int timestamp = Convert.ToInt32((utcTime - utcStartTime).TotalSeconds);
            return timestamp;
        }
        /// <summary>
        /// 获取随机数
        /// </summary>
        /// <returns></returns>
        public  int GetNonce()
        {
            var random = new Random();
            int nonce = random.Next(1, Int32.MaxValue);
            return nonce;
        }
        /// <summary>
        /// 获取签名
        /// </summary>
        /// <param name="secret"></param>
        /// <param name="dataparams"></param>
        /// <returns></returns>
        public  string GetUserApiSign(string secret, params string[] dataparams)
        {
            StringBuilder sb = new StringBuilder();
            if (dataparams != null && dataparams.Length > 0)
            {
                foreach (var item in dataparams)
                {
                    sb.Append(item);
                }
            }
            if (!string.IsNullOrEmpty(secret))
            {
                sb.Append(secret);
            }
            else
            {
                sb.Append(ApiSecret);
            }
            string str = sb.ToString();
            string sign = Md5.md5(str, 16).ToLower();
            return sign;
        }
        /// <summary>
        /// POST封装接口
        /// </summary>
        /// <param name="url">地址</param>
        /// <param name="type">1-返回参数为msgpack,2-返回参数为text</param>
        /// <param name="postdata">post的数据</param>
        /// <param name="data">加密参数</param>
        /// <returns></returns>
        private async Task<HttpResponseMessage> PostDataAsync(string url, int type, object postdata, params string[] data)
        {
            int timestamp = GetTimestamp();
            int nonce = GetNonce();

            string sign = GetUserApiSign("", data);
            var c2s_dto = new SuZhouApiBaseDto<object>
            {
                Data = postdata,
                SecretHash = ApiSecretHash,
                Nonce = nonce,
                Signature = sign,
                TimeStamp = timestamp,
                UserId = UserId
            };
            var request = new HttpRequestMessage(HttpMethod.Post, url); //发起post请求
            byte[] bytes = MessagePackSerializer.Serialize(c2s_dto); //序列化请求数据为byte
            request.Content = new ByteArrayContent(bytes); //设置请求信息体
            if (type == 2)
            {
                request.Headers.Add("Accept", "text/plain");
            }
            else
            {
                request.Headers.Add("Accept", "application/x-msgpack");
            }
            request.Content.Headers.Add("Content-Type", "application/x-msgpack");
            var client = _clientFactory.CreateClient();
            var response = await client.SendAsync(request);
            var testdata = await response.Content.ReadAsStringAsync();
            return response;
        }
        /// <summary>
        /// GET接口封装
        /// </summary>
        /// <param name="url">地址</param>
        /// <param name="type">1-返回参数为msgpack,2-返回参数为text</param>
        /// <param name="data">加密参数</param>
        /// <returns></returns>
        private async Task<HttpResponseMessage> GetDataAsync(string url, int type, params string[] data)
        {
            int timestamp = GetTimestamp();
            int nonce = GetNonce();
            string sign = GetUserApiSign("", data);
            var request = new HttpRequestMessage(HttpMethod.Get, url);
            if (type == 2)
            {
                request.Headers.Add("Accept", "text/plain");
            }
            else
            {
                request.Headers.Add("Accept", "application/x-msgpack");
            }
            request.Headers.Add("secret", ApiSecretHash);
            request.Headers.Add("nonce", nonce.ToString());
            request.Headers.Add("time", timestamp.ToString());
            request.Headers.Add("user", UserId);
            request.Headers.Add("sign", sign);
            var client = _clientFactory.CreateClient();
            var response = await client.SendAsync(request);
            var testdata = await response.Content.ReadAsStringAsync();
            return response;
        }
        /// <summary>
        /// Delete接口封装
        /// </summary>
        /// <param name="url">地址</param>
        /// <param name="type">1-返回参数为msgpack,2-返回参数为text</param>
        /// <param name="data">加密参数</param>
        /// <returns></returns>
        private async Task<HttpResponseMessage> DeleteDataAsync(string url, int type, params string[] data)
        {
            int timestamp = GetTimestamp();
            int nonce = GetNonce();
            string sign = GetUserApiSign("", data);
            var request = new HttpRequestMessage(HttpMethod.Delete, url);
            if (type == 2)
            {
                request.Headers.Add("Accept", "text/plain");
            }
            else
            {
                request.Headers.Add("Accept", "application/x-msgpack");
            }
            request.Headers.Add("secret", ApiSecretHash);
            request.Headers.Add("nonce", nonce.ToString());
            request.Headers.Add("time", timestamp.ToString());
            request.Headers.Add("user", UserId);
            request.Headers.Add("sign", sign);
            var client = _clientFactory.CreateClient();
            var response = await client.SendAsync(request);
            var testdata = await response.Content.ReadAsStringAsync();
            return response;
        }
        /// <summary>
        /// 删除地产区域
        /// </summary>
        /// <param name="id"></param>
        /// <returns></returns>
        public async Task<ResultInfo> DeleteEstates(string id)
        {
            var url = $"{ApiUrl}/api/estates/{id}";
            var response = await DeleteDataAsync(url, 2, id);
            var resdata = await response.Content.ReadAsByteArrayAsync();
            if (response.IsSuccessStatusCode)
            {
                return new ResultInfo(ResultState.SUCCESS, "删除成功");
            }
            else
            {
                var msg = await response.Content.ReadAsStringAsync();
                return new ResultInfo(ResultState.FAIL, msg);
            }
        }
        /// <summary>
        /// 删除采集点
        /// </summary>
        /// <param name="id"></param>
        /// <returns></returns>
        public async Task<ResultInfo> DeleteCollect(string id)
        {
            var url = $"{ApiUrl}/api/collectionpoints/{id}";
            var response = await DeleteDataAsync(url, 2, id);
            var resdata = await response.Content.ReadAsStringAsync();
            if (response.IsSuccessStatusCode)
            {
                return new ResultInfo(ResultState.SUCCESS, "删除成功");
            }
            else
            {
                return new ResultInfo(ResultState.FAIL, resdata);
            }
        }
        /// <summary>
        /// 添加采集点
        /// </summary>
        /// <param name="estatesC2SDto"></param>
        /// <returns></returns>
        public async Task<ResultInfo> PostCollectAsync(CollectC2SDto estatesC2SDto)
        {
            var url = $"{ApiUrl}/api/CollectionPoints";
            string[] paramlist = new string[] {
                estatesC2SDto.Code,estatesC2SDto.Name,estatesC2SDto.Addr,estatesC2SDto.Estate
            };
            var response = await PostDataAsync(url, 1, estatesC2SDto, paramlist);
            var resdata = await response.Content.ReadAsByteArrayAsync();
            if (response.IsSuccessStatusCode)
            {
                var s2c_dto = MessagePackSerializer.Deserialize<CollectS2CDto>(resdata);
                return new ResultInfo(ResultState.SUCCESS, "success", s2c_dto.id);
            }
            else
            {
                var msg = await response.Content.ReadAsStringAsync();
                return new ResultInfo(ResultState.FAIL, msg);
            }
        }
        /// <summary>
        /// 上传数据
        /// </summary>
        /// <param name="garbageC2SDto"></param>
        /// <returns></returns>
        public async Task<ResultInfo> PostGarbagesAsync(GarbagePltC2SDto garbageC2SDto)
        {
            var url = $"{ApiUrl}/api/garbages";
            string[] paramlist = new string[] {
                garbageC2SDto.Weight.ToString(),garbageC2SDto.Trash,garbageC2SDto.Type.ToString(),garbageC2SDto.ScanningTime.ToString(),garbageC2SDto.DStatus.ToString()
            };
            int timestamp = GetTimestamp();
            int nonce = GetNonce();
            string sign = GetUserApiSign(garbageC2SDto.secret, paramlist);
            var c2s_dto = new SuZhouPostApiBaseDto<GarbageC2SDto>
            {
                Data = new GarbageC2SDto
                {
                    DStatus = garbageC2SDto.DStatus,
                    ScanningTime = garbageC2SDto.ScanningTime,
                    Trash = garbageC2SDto.Trash,
                    Type = garbageC2SDto.Type,
                    Weight = garbageC2SDto.Weight
                },
                SecretHash = garbageC2SDto.secrethash,
                Nonce = nonce,
                Signature = sign,
                TimeStamp = timestamp,
                DeviceId = garbageC2SDto.deviceid
            };
            var request = new HttpRequestMessage(HttpMethod.Post, url);
            var bytes = MessagePackSerializer.Serialize(c2s_dto);
            request.Content = new ByteArrayContent(bytes);
            request.Headers.Add("Accept", "application/x-msgpack");
            request.Content.Headers.Add("Content-Type", "application/x-msgpack");
            var client = _clientFactory.CreateClient();
            var response = await client.SendAsync(request);
            if (response.IsSuccessStatusCode)
            {
                //记录日志
                _loggerService.AddLogger($"测量信息上报成功:参数:{c2s_dto.ToJson()}", 3);
                return new ResultInfo(ResultState.SUCCESS, "success");
            }
            else
            {
                var msg = await response.Content.ReadAsStringAsync();
                //记录日志
                _loggerService.AddLogger($"测量信息上报失败:参数:{c2s_dto.ToJson()}\r\n返回值:{msg}", 3);
                return new ResultInfo(ResultState.FAIL, msg);
            }
        }
    }
}
