using System.Diagnostics;
using System.Text;
using WCS.BLL;
using WCS.BLL.DbModels;
using WCS.DAL.Db;
using WCS.Model;

namespace WCS.WebApi.Controllers
{
    public class RequestResponseLoggingMiddleware
    {
        private readonly RequestDelegate _next;

        public RequestResponseLoggingMiddleware(RequestDelegate next)
        {
            _next = next;
        }

        public async Task InvokeAsync(HttpContext context)
        {
            var stopwatch = Stopwatch.StartNew();

            var requestBody = string.Empty;
            var responseBody = string.Empty;
            var originalRequestBody = context.Request.Body;
            var requestTime = DateTime.Now;

            // 可以选择只记录特定的Content-RequestType //只记录json类型的请求
            if (context.Request.ContentType != null && !context.Request.ContentType.Contains("application/json", StringComparison.OrdinalIgnoreCase))
            {
                ;
            }
            try
            {
                ////读取Request Body
                //// 保存原始的Request Body
                var requestBodyStream = new MemoryStream();
                await originalRequestBody.CopyToAsync(requestBodyStream);
                originalRequestBody.Dispose();
                requestBodyStream.Position = 0; // 将流的位置重置回开始处  
                requestBody = await new StreamReader(requestBodyStream).ReadToEndAsync();
                // 替换Request.Body以便后续中间件可以读取  
                requestBodyStream.Position = 0;// 将流的位置重置回开始处  
                context.Request.Body = requestBodyStream;


                // 保存原始的Response Body
                var originalResponseBodyStream = context.Response.Body;
                using (var memStream = new MemoryStream())
                {
                    context.Response.Body = memStream;

                    // 继续处理请求
                    await _next(context);

                    memStream.Seek(0, SeekOrigin.Begin);
                    responseBody = await new StreamReader(memStream).ReadToEndAsync();

                    memStream.Seek(0, SeekOrigin.Begin);
                    await memStream.CopyToAsync(originalResponseBodyStream);
                }
            }
            catch (Exception e)
            {

                //return new ResponseCommon()
                //{
                //    Code = 300,
                //    Message = $"操作失败：{e.Message}"
                //};
            }

            finally
            {
                var guid = Guid.NewGuid();
                //TO DO如何将记日志的 和不记日志的分开 解耦
                if (!context.Request.Path.ToString().Contains("getInterfaceRecord") && !context.Request.Path.ToString().Contains("getShelfStatus"))
                {
                    try
                    {
                        Logs.Write($"[记录接口日志]{guid}，开始记录{context.Request.Path.ToString()}", LogsType.Api);
                        var logRecord = new SystemApiLogRecord()
                        {
                            DeviceIp = context?.Connection?.RemoteIpAddress?.ToString(),
                            RequestUrl = context.Request?.Path.ToString(),
                            RequestBody = requestBody,
                            QueryString = context.Request?.QueryString.ToString(),
                            IsResponse = true,
                            ResponseJson = responseBody,
                            RequestTime = requestTime,
                            ResponseTime = DateTime.Now,
                            ExecutionTime = stopwatch.ElapsedMilliseconds
                        };
                        Task.Run(() =>
                        {
                            try
                            {
                                DbHelp.dbLog.Insertable(logRecord).ExecuteCommand();
                            }
                            catch (Exception ex)
                            {
                                Logs.Write($"[记录接口日志]{guid}保存数据失败！发生异常：" + ex.Message, LogsType.Api);
                            }

                        });
                    }
                    catch (Exception e)
                    {
                        Logs.Write($"[记录接口日志]{guid}失败！发生异常：" + e.Message, LogsType.Api);
                    }
                }
                else
                    Logs.Write($"[记录接口日志]{guid}，不记录getInterfaceRecord", LogsType.Api);
            }
        }
    }
}
