using Microsoft.AspNetCore.Authentication.JwtBearer;
using Microsoft.EntityFrameworkCore;
using Microsoft.EntityFrameworkCore.Infrastructure;
using Microsoft.EntityFrameworkCore.Storage;
using Microsoft.IdentityModel.Tokens;
using System.Text;
using DocumentFormat.OpenXml.Office2010.Drawing.Charts;
using FamilyTreeAPI.Authorization;
using FamilyTreeAPI.Entities;
using FamilyTreeAPI.GraphQL.Query;
using FamilyTreeAPI.Interface;
using FamilyTreeAPI.Models;
using FamilyTreeAPI.Repository;

var builder = WebApplication.CreateBuilder(args);

// Add services to the container.
#region Services
var services = builder.Services;
services.AddCors();
services.AddControllers();
// Learn more about configuring Swagger/OpenAPI at https://aka.ms/aspnetcore/swashbuckle
services.AddEndpointsApiExplorer();
services.AddSwaggerGen();

var appSettingsSection = builder.Configuration.GetSection("AppSettings");
services.Configure<AppSettings>(appSettingsSection);
var appSettings = appSettingsSection.Get<AppSettings>();
var key = Encoding.ASCII.GetBytes(appSettings.Secret);

services.AddAuthentication(x =>
{

    x.DefaultAuthenticateScheme = JwtBearerDefaults.AuthenticationScheme;
    x.DefaultChallengeScheme = JwtBearerDefaults.AuthenticationScheme;
})
 .AddJwtBearer(x =>
    {
        x.RequireHttpsMetadata = false;
        x.SaveToken = true;
        x.TokenValidationParameters = new TokenValidationParameters
        {
            ValidateIssuerSigningKey = true,
            IssuerSigningKey = new SymmetricSecurityKey(key),
            ValidateIssuer = false,
            ValidateAudience = false
        };
 });
services.AddHttpContextAccessor();
services.AddScoped<IJwtUtils, JwtUtils>();
services.AddScoped<ImportPersonRepository>();
services.AddDbContext<FamilyTreeDBContext>(options =>
{
   
    //  options.LogTo(s => Console.WriteLine(s));
    //options.UseNpgsql(appSettings.SQLConnectionString);
    string? conn = builder.Configuration.GetValue<string>("AppSettings:SQLConnectionString");
    // options.LogTo(s => Console.WriteLine(s));
    if (conn != null)
        options.UseNpgsql(conn);
});

services.AddGraphQLServer()
    .AddFiltering()
    .AddSorting()
    .AddProjections()
    .RegisterDbContextFactory<FamilyTreeDBContext>()

    .AddQueryType<QueryFamilyTree>();
    

services.AddScoped<ILookup, LookupRepository>();
services.AddScoped<IStaff, StaffRepository>();

services.AddScoped<IRelationShipd,RelationShipRepository>();
services.AddScoped<IPerson, PersonRepository>();
services.AddScoped<IUserService, UserServiceRepository>();
services.AddScoped<IReport, ReportRepository>();
services.AddScoped<Seed>();
/*
 
  public FamilyTreeDBContext(DbContextOptions<FamilyTreeDBContext> options)
            : base(options)
        {
            AppContext.SetSwitch("Npgsql.EnableLegacyTimestampBehavior", true);
        }
services.AddScoped<IAdminUser, AdminUserRepository>();

services.AddScoped<IMotorVehicles, MotorVehiclesRepository>();
*/

#endregion

#region app
var app = builder.Build();


using (var scope = app.Services.CreateScope())
{
    try
    {
        var context = scope.ServiceProvider.GetRequiredService<FamilyTreeDBContext>();
        var db = context.Database;
        if (db != null)
        { 
            
            db.Migrate();
            db.EnsureCreated();
            var staff = context.GetService<Seed>();
            int id = staff.InsertOneUser();
            if (id < 0)
            {
                var databaseCreator = (context.GetService<IDatabaseCreator>() as RelationalDatabaseCreator);
                if (databaseCreator != null)
                {
                    //if (!databaseCreator.Exists())
                    databaseCreator.CreateTables();
                }
                id = staff.InsertOneUser();
            }
            
        }

      
    }
    catch (Exception e)
    {
        Console.WriteLine(e.ToString());
    }

}


app.UseMiddleware<JwtMiddleware>();
// Configure the HTTP request pipeline.
//if (app.Environment.IsDevelopment())//
//{
    app.UseSwagger();
    app.UseSwaggerUI();
//}
// global cors policy
app.UseCors(x => x
        .SetIsOriginAllowed(origin => true)
        .AllowAnyMethod()
        .AllowAnyHeader()
        .WithExposedHeaders("Content-Disposition")
        .AllowCredentials());

app.UseRouting();
app.UseAuthentication();
app.UseAuthorization();
app.MapGraphQL();
app.MapControllers();
app.Run();

#endregion

/*
 https://www.youtube.com/watch?v=WQFx2m5Ub9M


https://csharptotypescript.azurewebsites.net/
\ services.AddDbContext<BloggingContext>(options =>
            options.UseNpgsql(Configuration.GetConnectionString("BloggingContext")));
dotnet ef dbcontext scaffold "host=postgresdb;port=5432;Database=FamilyTreeDB;Username=postgres;password=Positive~1" Npgsql.EntityFrameworkCore.PostgreSQL -Schemas schema1  --output-dir Models 
PM> Scaffold-DbContext "Host=postgresdb;Port=5432;database=FamilyTreeDB;user id=postgres;Password=Positive~1" Npgsql.EntityFrameworkCore.PostgreSQL  -OutputDir Models 
 */

/*
 graphql
https://www.youtube.com/watch?v=HnXA8RI7Tvc

query {
  family {
        nodes{
        id
        firstname
        lastname
        email
        
        }
    }
  }
*/