using GxPress.Api.ServiceExtensions;
using GxPress.Common.AppOptions;
using GxPress.Common.Middleware;
using GxPress.Common.Tools;
using Microsoft.AspNetCore.Builder;
using Microsoft.AspNetCore.Hosting;
using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Http.Features;
using Microsoft.AspNetCore.Mvc;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Hosting;
using Newtonsoft.Json;
using Newtonsoft.Json.Serialization;
using Quartz;
using Quartz.Impl;

namespace GxPress.Api
{
    public class Startup
    {
        public IConfiguration Configuration { get; }
        public Startup(IConfiguration configuration)
        {
            Configuration = configuration;
            ConfigHelper.Configs = Configuration;
        }
        // This method gets called by the runtime. Use this method to add services to the container.
        // For more information on how to configure your application, visit https://go.microsoft.com/fwlink/?LinkID=398940
        public void ConfigureServices(IServiceCollection services)
        {
             services.AddSingleton<IHttpContextAccessor,HttpContextAccessor>();
            services.AddSingleton<ISchedulerFactory, StdSchedulerFactory>();
            services.AddControllers().AddNewtonsoftJson(options =>
            {
                options.SerializerSettings.ContractResolver = new DefaultContractResolver();
                //options.UseCamelCasing(true);
                options.SerializerSettings.DateFormatString = "yyyy-MM-dd HH:mm:ss";
                //// 忽略循环引用
                //options.SerializerSettings.ReferenceLoopHandling = ReferenceLoopHandling.Ignore;
                //// 如字段为null值，该字段不会返回到前端
                // options.SerializerSettings.NullValueHandling = NullValueHandling.Include;
            }).AddJsonOptions(options =>
            {
                options.JsonSerializerOptions.PropertyNamingPolicy = null;
            }).SetCompatibilityVersion(CompatibilityVersion.Version_3_0);

            //文件上传限制60MB
            services.Configure<FormOptions>(options =>
            {
                options.MultipartBodyLengthLimit = 60000000;
            });

            //数据库
            var databaseSection = Configuration.GetSection("Database");
            var cacheSection = Configuration.GetSection("Cache:ConnectionString");
            var storageOptions = Configuration.GetSection("Storage").Get<StorageOptions>();

            services.Configure<DatabaseOptions>(databaseSection);
            services.AddDistributedCache(cacheSection.Value);
            services.AddStorage(storageOptions);

            services.Configure<ApiBehaviorOptions>(o =>
            {
                o.InvalidModelStateResponseFactory = actionContext =>
                    new BadRequestObjectResult(JsonConvert.SerializeObject(new
                    {
                        Message = "参数错误",
                        StackTrace = JsonConvert.SerializeObject(actionContext.ModelState)
                    }));
            });


            // var client = new CSRedisClient(redisSection.Value);
            // //初始化 RedisHelper
            // RedisHelper.Initialization(client);
            // //注册分布式缓存

            // var options = Options.Create(new Microsoft.Extensions.Caching.Redis.RedisCacheOptions
            // {
            //     Configuration = redisSection.Value,
            //     InstanceName = string.Empty,
            // });

            // services.AddSingleton<IDistributedCache>(new RedisCache(options));

            services.AddRepositories();
            services.AddServices();
            services.AddMappers();
            services.AddJwtAuthentication(Configuration);
            services.AddCors(options =>
            {
                options.AddPolicy(
                    "AllowAny",
                    x =>
                    {
                        x.AllowAnyHeader()
                            .AllowAnyMethod()
                            .SetIsOriginAllowed(_ => true)
                            .AllowCredentials();
                    });
            });

            services.AddSwashbuckle();
        }

        // This method gets called by the runtime. Use this method to configure the HTTP request pipeline.
        public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
        {
            if (env.IsDevelopment())
            {
                app.UseDeveloperExceptionPage();
            }

            //最上层的自定义异常处理中间件
            app.UseMiddleware<ExceptionMiddleware>();
            app.UseRouting();
            app.UseJwtAuthorization();
            app.UseStaticFiles();
            app.UseCors("AllowAny");
            app.UseSwashbuckle();

            app.UseEndpoints(endpoints =>
            {
                endpoints.MapControllers();
                endpoints.MapControllerRoute("default", "{controller=Home}/{action=Index}/{id?}");
            });
        }
    }
}
