using Microsoft.AspNetCore.Identity;
using Microsoft.Extensions.DependencyInjection;
using NexusReader.Domain.Entities;
using System;
using System.Linq;
using System.Threading.Tasks;
using System.Collections.Generic;
using Microsoft.EntityFrameworkCore;

namespace NexusReader.Data.Persistence;

public static class DbInitializer
{
    public static async Task SeedAsync(IServiceProvider serviceProvider)
    {
        using var scope = serviceProvider.CreateScope();
        var passwordHasher = scope.ServiceProvider.GetRequiredService<IPasswordHasher<NexusUser>>();
        var dbContextFactory = scope.ServiceProvider.GetRequiredService<IDbContextFactory<AppDbContext>>();
        using var dbContext = await dbContextFactory.CreateDbContextAsync();

        try
        {
            Console.WriteLine("[Seeder] Starting database seeding...");

            // Seed Subscription Plans
            if (!dbContext.SubscriptionPlans.Any())
            {
                dbContext.SubscriptionPlans.AddRange(new List<SubscriptionPlan>
                {
                    new SubscriptionPlan { Id = SubscriptionPlan.FreeId, PlanName = SubscriptionPlan.FreeName, AITokenLimit = 5000, IsUnlimitedTokens = false, MonthlyPrice = 0, StripeProductId = "prod_Free789" },
                    new SubscriptionPlan { Id = SubscriptionPlan.ProId, PlanName = SubscriptionPlan.ProName, AITokenLimit = 50000, IsUnlimitedTokens = false, MonthlyPrice = 19, StripeProductId = "prod_Pro123" },
                    new SubscriptionPlan { Id = SubscriptionPlan.EnterpriseId, PlanName = SubscriptionPlan.EnterpriseName, AITokenLimit = 1000000000, IsUnlimitedTokens = true, MonthlyPrice = 99, StripeProductId = "prod_Enterprise456" }
                });
                await dbContext.SaveChangesAsync();
                Console.WriteLine("[Seeder] Subscription plans seeded.");
            }

            // Seed Roles
            string[] roleNames = { "Admin", "User" };
            foreach (var roleName in roleNames)
            {
                var roleExist = dbContext.Roles.Any(r => r.Name == roleName);
                if (!roleExist)
                {
                    dbContext.Roles.Add(new IdentityRole { Name = roleName, NormalizedName = roleName.ToUpper() });
                    Console.WriteLine($"[Seeder] Created role: {roleName}");
                }
            }
            await dbContext.SaveChangesAsync();

            // Seed Admin User
            var adminEmail = "admin@nexus.com";
            var normalizedEmail = adminEmail.ToUpper();
            var adminUser = await dbContext.Users.FirstOrDefaultAsync(u => u.NormalizedEmail == normalizedEmail);

            if (adminUser == null)
            {
                adminUser = new NexusUser
                {
                    UserName = adminEmail,
                    NormalizedUserName = normalizedEmail,
                    Email = adminEmail,
                    NormalizedEmail = normalizedEmail,
                    EmailConfirmed = true,
                    SubscriptionPlanId = SubscriptionPlan.EnterpriseId,
                    AITokenLimit = 1000000,
                    TenantId = Guid.NewGuid().ToString(),
                    SecurityStamp = Guid.NewGuid().ToString()
                };

                var adminPassword = Environment.GetEnvironmentVariable("NEXUS_ADMIN_PASSWORD") ?? "Admin123!";
                adminUser.PasswordHash = passwordHasher.HashPassword(adminUser, adminPassword);

                dbContext.Users.Add(adminUser);
                await dbContext.SaveChangesAsync();

                var adminRole = await dbContext.Roles.FirstAsync(r => r.Name == "Admin");
                dbContext.UserRoles.Add(new IdentityUserRole<string> { UserId = adminUser.Id, RoleId = adminRole.Id });
                await dbContext.SaveChangesAsync();

                Console.WriteLine($"[Seeder] Admin user created successfully: {adminEmail}");

                // Seed Sample Author
                var author = await dbContext.Authors.FirstOrDefaultAsync(a => a.Name == "Giorgio Vasari");
                if (author == null)
                {
                    author = new Author { Name = "Giorgio Vasari" };
                    dbContext.Authors.Add(author);
                    await dbContext.SaveChangesAsync();
                }

                // Seed Sample Ebook
                if (!dbContext.Ebooks.Any(e => e.UserId == adminUser.Id))
                {
                    dbContext.Ebooks.Add(new Ebook
                    {
                        Title = "Lives of the Most Excellent Painters, Sculptors, and Architects",
                        AuthorId = author.Id,
                        UserId = adminUser.Id,
                        FilePath = "wwwroot/assets/book.epub",
                        AddedDate = DateTime.UtcNow,
                        LastReadDate = DateTime.UtcNow,
                        Progress = 0,
                        LastChapter = "Introduction"
                    });
                    await dbContext.SaveChangesAsync();
                    Console.WriteLine("[Seeder] Sample book seeded for admin.");
                }
            }
            else
            {
                Console.WriteLine("[Seeder] Admin user already exists.");
            }
        }
        catch (Exception ex)
        {
            Console.WriteLine($"[Seeder] Critical error during seeding: {ex.Message}");
        }
    }
}
