using BBWY.Common.Extensions;
using BBWY.Common.Http;
using BBWY.Common.Models;
using BBWY.Server.API.Filters;
using BBWY.Server.API.Middlewares;
using BBWY.Server.Business;
using BBWY.Server.Model;
using BBWY.Server.Model.Dto;
using Microsoft.AspNetCore.Builder;
using Microsoft.AspNetCore.Hosting;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Hosting;
using Microsoft.Extensions.Options;
using Microsoft.OpenApi.Models;
using Newtonsoft.Json.Linq;
using Newtonsoft.Json.Serialization;
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Reflection;
using Yitter.IdGenerator;

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

        public IConfiguration Configuration { get; }

        // This method gets called by the runtime. Use this method to add services to the container.
        public void ConfigureServices(IServiceCollection services)
        {
            services.AddMemoryCache();

            var idOption = new IdGeneratorOptions(1);
            var idGenerator = new DefaultIdGenerator(idOption);
            services.AddSingleton(typeof(IIdGenerator), idGenerator);


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

            var fsql2 = new FreeSql.FreeSqlBuilder().UseConnectionString(FreeSql.DataType.MySql, Configuration.GetConnectionString("MDSDB")).Build();
            var fsql3 = new FreeSql.FreeSqlBuilder().UseConnectionString(FreeSql.DataType.MySql, Configuration.GetConnectionString("JDXX")).Build();

            services.AddSingleton(new FreeSqlMultiDBManager()
            {
                BBWYfsql = fsql,
                MDSfsql = fsql2,
                JDXXfsql = fsql3
            });
            services.AddSingleton<NLogManager>();
            services.AddSingleton(typeof(NLog.ILogger), NLog.LogManager.GetCurrentClassLogger());
            services.AddSingleton<RestApiService>();
            services.AddSingleton<TaskSchedulerManager>();
            services.AddMemoryCache();
            services.AddControllers();
            services.AddHttpContextAccessor();
            services.AddHttpClient();
            services.AddCors(options =>
            {
                options.AddPolicy("cors", 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.BatchRegisterServices(new Assembly[] { Assembly.Load("BBWY.Server.Business") }, typeof(IDenpendency));
            services.AddSingleton<PlatformSDKBusiness, JDBusiness>();
            services.AddSingleton<PlatformSDKBusiness, _1688Business>();

            //var stores = Configuration.GetSection("Stores").Get<IList<Store>>();

            services.Configure<GlobalConfig>(Configuration.GetSection("GlobalSetting"));
            services.AddMapper(new MappingProfiles());

            services.AddSwaggerGen(c =>
            {
                c.SwaggerDoc("v1", new OpenApiInfo
                {
                    Version = "v1.0.0",
                    Title = "����Ϊӯ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();
            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.UseCors("cors");

            app.UseAuthorization();

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