using Microsoft.AspNetCore.DataProtection.EntityFrameworkCore;
using Microsoft.AspNetCore.Identity;
using Microsoft.AspNetCore.Identity.EntityFrameworkCore;

namespace Fast.Shared.Database;

public partial class MyDbContext : IdentityDbContext<AppUser, IdentityRole<int>, int>, IDataProtectionKeyContext
{
    partial void OnModelCreatingPartial(ModelBuilder modelBuilder)
    {
        //base.OnModelCreating is needed so that the Identity tables are created
        base.OnModelCreating(modelBuilder);

        foreach (var entity in modelBuilder.Model.GetEntityTypes())
        {
            if (IsAspEntity(entity))
                RenameAspEntity(entity);
        }
    }

    private readonly Dictionary<string, string> AspEntityNames = new()
    {
        { "AppUser", "app_user" },
        { "AspRole", "asp_role" },
        { "AspRoleClaim", "asp_role_claim" },
        { "AspUserClaim", "asp_user_claim" },
        { "AspUserLogin", "asp_user_login" },
        { "AspUserRole", "asp_user_role" },
        { "AspUserToken", "asp_user_token" },
        { "Fast.Shared.Database.Models.AppUser", "app_user" },
        { "Fast.Shared.Database.Models.AspRole", "asp_role" },
        { "Fast.Shared.Database.Models.AspRoleClaim", "asp_role_claim" },
        { "Fast.Shared.Database.Models.AspUserClaim", "asp_user_claim" },
        { "Fast.Shared.Database.Models.AspUserLogin", "asp_user_login" },
        { "Fast.Shared.Database.Models.AspUserRole", "asp_user_role" },
        { "Fast.Shared.Database.Models.AspUserToken", "asp_user_token" }
    };

    private bool IsAspEntity(Microsoft.EntityFrameworkCore.Metadata.IMutableEntityType entity)
    {
        if (AspEntityNames.ContainsKey(entity.Name))
            return true;
        return false;
    }

    private void RenameAspEntity(Microsoft.EntityFrameworkCore.Metadata.IMutableEntityType entity)
    {
        var newTableName = AspEntityNames[entity.Name];
        entity.SetTableName(newTableName);


        if (newTableName == "app_user")
        {
            var properties = entity.GetProperties().ToList();
            foreach (var property in properties)
                property.SetColumnName(property.Name.ToSnakeCase());
        }
    }
}
