using System.IO;
using GxPress.Api.ServiceExtensions;
using GxPress.Common.AppOptions;
using GxPress.Common.Tools;
using GxPress.Service.Implement;
using GxPress.Service.Implement.PlatformData;
using GxPress.Service.Interface;
using GxPress.Service.Interface.PlatformData;
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.FileProviders;
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)
        {
            // DbContext.ConnectionString = Configuration.GetConnectionString("DefaultConnection");
            // services.AddSingleton(new SqlSugarClient(new ConnectionConfig
            // {
            //     ConnectionString = "server=47.95.221.96;uid=root;pwd=siteservercms88;database=ccpph_tede;MultipleActiveResultSets=true",//必填, 数据库连接字符串
            //     DbType = DbType.MySql,         //必填, 数据库类型
            //     IsAutoCloseConnection = true,       //默认false, 时候知道关闭数据库连接, 设置为true无需使用using或者Close操作
            //     InitKeyType = InitKeyType.SystemTable    //默认SystemTable, 字段信息读取, 如：该属性是不是主键，是不是标识列等等信息
            // }));
            services.AddSingleton<IHttpContextAccessor, HttpContextAccessor>();
            services.AddSingleton<ISchedulerFactory, StdSchedulerFactory>();
            // services.AddSingleton<IUserService, UserService>();
            services.AddSingleton<IApiLogService, ApiLogService>();
            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)
        {
            //var provider = new FileExtensionContentTypeProvider();
            // // Add new mappings
            // provider.Mappings[".epub"] = "application/octet-stream";
            if (env.IsDevelopment())
            {
                app.UseDeveloperExceptionPage();
            }
            //最上层的自定义异常处理中间件
            app.UseMiddleware<ExceptionMiddleware>();
            app.UseRouting();
            app.UseJwtAuthorization();
            var cachePeriod = env.IsDevelopment() ? "600" : "604800";
            app.UseStaticFiles(new StaticFileOptions
            {
                //ContentTypeProvider = provider,
                //非标准类型
                ServeUnknownFileTypes = true,
                //返回类型
                DefaultContentType = "application/octet-stream",
                OnPrepareResponse = ctx =>
                {
                    // Requires the following import:
                    // using Microsoft.AspNetCore.Http;
                    ctx.Context.Response.Headers.Append("Cache-Control", $"public, max-age={cachePeriod}");
                    ctx.Context.Response.Headers.Append("Access-Control-Allow-Headers", $"X-Requested-With");
                    ctx.Context.Response.Headers.Append("Access-Control-Allow-Origin", $"*");
                    ctx.Context.Response.Headers.Append("Access-Control-Allow-Methods", $"GET,POST,OPTIONS");
                    ctx.Context.Response.Headers.Append("Connection", $"keep-alive");
                }
            });
            // app.UseStaticFiles(new StaticFileOptions
            // {
            //     FileProvider = new PhysicalFileProvider(
            // Path.Combine(Directory.GetCurrentDirectory(), "wwwroot")),
            //     RequestPath = "",
            //     ContentTypeProvider = provider
            // });
            app.UseDirectoryBrowser(new DirectoryBrowserOptions
            {
                FileProvider = new PhysicalFileProvider(
            Path.Combine(Directory.GetCurrentDirectory(), "wwwroot")),
                RequestPath = "/MyImages"
            });
            app.UseCors("AllowAny");
            app.UseSwashbuckle();

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