﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Transactions;
using AspNetCore.Identity.Mongo;
using AspNetCore.Identity.Mongo.Model;
using Microsoft.AspNetCore.Authentication.JwtBearer;
using Microsoft.AspNetCore.Builder;
using Microsoft.AspNetCore.Hosting;
using Microsoft.AspNetCore.HttpsPolicy;
using Microsoft.AspNetCore.Identity;
using Microsoft.AspNetCore.Mvc;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Logging;
using Microsoft.Extensions.Options;
using Microsoft.IdentityModel.Tokens;
using MongoDB.Driver;
using Todolist.Service.Auth.Configuration;
using Todolist.Service.Auth.Models;
using Todolist.Service.Auth.Services;

namespace Todolist.Service.Auth
{
    public class Startup
    {
        private readonly static Action<BinderOptions> SettingsBinder = o => o.BindNonPublicProperties = true;

        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)
        {
            var section = Configuration.GetSection(nameof(AppSettings));
            services.Configure<AppSettings>(section, SettingsBinder);

            var appSettings = section.Get<AppSettings>(SettingsBinder);

            services.AddMvc().SetCompatibilityVersion(CompatibilityVersion.Version_2_1);
            services.AddIdentityMongoDbProvider<User, Role>(
                settings =>
                {
                    settings.Password.RequireNonAlphanumeric = false;
                    settings.Password.RequireUppercase = false;
                },
                options =>
                {
                    var connection = Configuration.GetConnectionString("MongoDb");
                    options.ConnectionString = connection;
                });

            services.AddAuthentication(options =>
                {
                    options.DefaultScheme = JwtBearerDefaults.AuthenticationScheme;
                    options.DefaultAuthenticateScheme = JwtBearerDefaults.AuthenticationScheme;
                    options.DefaultChallengeScheme = JwtBearerDefaults.AuthenticationScheme;
                })
                .AddJwtBearer(options =>
                {
                    options.RequireHttpsMetadata = false;
                    options.SaveToken = true;
                    options.TokenValidationParameters = new TokenValidationParameters
                    {
                        ValidateIssuerSigningKey = true,
                        IssuerSigningKey = new SymmetricSecurityKey(appSettings.JwtSecret),
                        ValidateIssuer = false,
                        ValidateAudience = false
                    };
                });

            //DI 
            services.AddTransient<IAccountService, DefaultAccountService>();
        }

        // This method gets called by the runtime. Use this method to configure the HTTP request pipeline.
        public void Configure(IApplicationBuilder app, IHostingEnvironment env, UserManager<User> userManager, RoleManager<Role> roleManager)
        {
            if (env.IsDevelopment())
            {
                app.UseDeveloperExceptionPage();
            }
            else
            {
                app.UseHsts();
            }

            roleManager.SeedRoles();
            userManager.SeedUsers();

            app.UseHttpsRedirection();
            app.UseMvc();
        }
    }
}