using BBWY.Common.Http;
using BBWY.Server.Business;
using JD.API.Filters;
using JD.API.Middlewares;
using Microsoft.AspNetCore.Builder;
using Microsoft.AspNetCore.Hosting;
using Microsoft.AspNetCore.Mvc;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Hosting;
using Microsoft.Extensions.Logging;
using Microsoft.OpenApi.Models;
using Newtonsoft.Json.Serialization;
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Reflection;
using System.Threading.Tasks;

namespace JD.API
{
    public class Startup
    {
        public Startup(IConfiguration configuration)
        {
            Configuration = configuration;
        }

        public IConfiguration Configuration { get; }

        private bool isEnableSwagger;

        // This method gets called by the runtime. Use this method to add services to the container.
        public void ConfigureServices(IServiceCollection services)
        {
            isEnableSwagger = Convert.ToBoolean(Configuration.GetSection("IsEnableSwagger").Value);

            services.AddHttpContextAccessor();
            services.AddHttpClient();
            services.AddMemoryCache();

            services.AddSingleton<NLogManager>();
            services.AddSingleton<TaskSchedulerManager>();
            //services.AddSingleton(typeof(NLog.ILogger), NLog.LogManager.GetCurrentClassLogger());

            var fsql = new FreeSql.FreeSqlBuilder().UseConnectionString(FreeSql.DataType.MySql, Configuration.GetConnectionString("DB")).Build();
            services.AddSingleton(typeof(IFreeSql), fsql);

            services.AddCors(options =>
            {
                options.AddDefaultPolicy(p =>
                {
                    p.AllowAnyOrigin().AllowAnyMethod().AllowAnyHeader();
                });
            });

            services.AddControllers(configure =>
            {
                configure.Filters.Add<ResultFilter>();
            }).AddNewtonsoftJson(setupAction =>
            {
                setupAction.SerializerSettings.ContractResolver = new DefaultContractResolver();
                setupAction.SerializerSettings.DateFormatString = "yyyy-MM-dd HH:mm:ss";
                //setupAction.SerializerSettings.NullValueHandling = Newtonsoft.Json.NullValueHandling.Include;
                //setupAction.SerializerSettings.DefaultValueHandling = Newtonsoft.Json.DefaultValueHandling.Include;
            });
            services.AddSingleton<YunDingFilter>();
            services.AddSingleton<RestApiService>();
            services.AddSingleton<PlatformSDKBusiness, JDBusiness>();
            services.AddSingleton<PlatformSDKBusiness, _1688Business>();
            services.AddSingleton<YunDingBusiness>();

            if (isEnableSwagger)
            {
                services.AddSwaggerGen(c =>
                {
                    c.SwaggerDoc("v1", new OpenApiInfo
                    {
                        Version = "v1.0.0",
                        Title = "JD�ƶ�API",
                        Description = "ע������\r\n1.���ز������Ʋ��ô��շ�����\r\n2.ApiResponseΪ�������ض���(Code,Data,Message),�ӿ������еķ���ֵ������Data����\r\n3.��������Code=200"
                    });
                    // JWT��֤                                                 
                    //c.AddSecurityDefinition(JwtBearerDefaults.AuthenticationScheme, new OpenApiSecurityScheme
                    //{
                    //    Scheme = JwtBearerDefaults.AuthenticationScheme,
                    //    BearerFormat = "JWT",
                    //    Type = SecuritySchemeType.ApiKey,
                    //    Name = "Authorization",
                    //    In = ParameterLocation.Header,
                    //    Description = "Authorization:Bearer {your JWT token}<br/>",
                    //});
                    //c.AddSecurityRequirement(new OpenApiSecurityRequirement
                    // {
                    //    {
                    //        new OpenApiSecurityScheme{Reference = new OpenApiReference
                    //            {
                    //                Type = ReferenceType.SecurityScheme,
                    //                Id = JwtBearerDefaults.AuthenticationScheme
                    //            }
                    //        },
                    //        new string[] { }
                    //    }
                    // });

                    var executingAssembly = Assembly.GetExecutingAssembly();
                    var assemblyNames = executingAssembly.GetReferencedAssemblies().Union(new AssemblyName[] { executingAssembly.GetName() }).ToArray();
                    Array.ForEach(assemblyNames, (assemblyName) =>
                    {
                        //var xmlFile = $"{Assembly.GetExecutingAssembly().GetName().Name}.xml";
                        var xmlFile = $"{assemblyName.Name}.xml";
                        var xmlPath = Path.Combine(AppContext.BaseDirectory, xmlFile);
                        if (!File.Exists(xmlPath))
                            return;
                        c.IncludeXmlComments(xmlPath, true);
                    });
                });
            }
        }

        // This method gets called by the runtime. Use this method to configure the HTTP request pipeline.
        public void Configure(IApplicationBuilder app, IWebHostEnvironment env, YunDingBusiness yunDingBusiness)
        {
            yunDingBusiness.RefreshKey();
            if (isEnableSwagger)
            {
                app.UseSwagger(c => c.SerializeAsV2 = true)
              .UseSwaggerUI(c =>
              {
                  c.SwaggerEndpoint("/swagger/v1/swagger.json", "BBWY API");
                  c.RoutePrefix = string.Empty;
              });
            }

            //if (env.IsDevelopment())
            //{
            //    app.UseDeveloperExceptionPage();
            //}

            app.UseMiddleware<CustomExceptionMiddleWare>();

            app.UseRouting();

            app.UseAuthorization();

            app.UseEndpoints(endpoints =>
            {
                endpoints.MapControllers();
            });
        }
    }
}