using Indotalent.Data.Entities;
using Indotalent.Infrastructure.Database.Demo;
using Microsoft.AspNetCore.Identity;
using Microsoft.EntityFrameworkCore;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.DependencyInjection;

namespace Indotalent.Infrastructure.Database;

public static class DatabaseSeederDemo
{
    public static async Task SeedAsync(IServiceProvider serviceProvider)
    {
        var roleManager = serviceProvider.GetRequiredService<RoleManager<IdentityRole>>();
        var userManager = serviceProvider.GetRequiredService<UserManager<ApplicationUser>>();
        var configuration = serviceProvider.GetRequiredService<IConfiguration>();
        var context = serviceProvider.GetRequiredService<AppDbContext>();

        // Get the Demo Tenant ID (already created in DatabaseSeeder)
        var demoTenant = await context.Set<Tenant>().FirstOrDefaultAsync(t => t.Name == "Demo Tenant");
        var demoTenantId = demoTenant?.Id;

        // 1. Master Data (Must be first)
        await UserSeeder.GenerateDataAsync(userManager, context, configuration, demoTenantId);
        await UnitMeasureSeeder.GenerateDataAsync(context);
        await WarehouseSeeder.GenerateDataAsync(context);
        await PaymentMethodSeeder.GenerateDataAsync(context);

        // 2. Customer & Vendor Related
        await CustomerCategorySeeder.GenerateDataAsync(context);
        await CustomerGroupSeeder.GenerateDataAsync(context);
        await CustomerSeeder.GenerateDataAsync(context);
        await CustomerContactSeeder.GenerateDataAsync(context);

        await VendorCategorySeeder.GenerateDataAsync(context);
        await VendorGroupSeeder.GenerateDataAsync(context);
        await VendorSeeder.GenerateDataAsync(context);
        await VendorContactSeeder.GenerateDataAsync(context);

        // 3. Product Related
        await ProductGroupSeeder.GenerateDataAsync(context);
        await ProductSeeder.GenerateDataAsync(context);

        // 4. Sales & CRM Related
        await SalesTeamSeeder.GenerateDataAsync(context);
        await SalesRepresentativeSeeder.GenerateDataAsync(context);
        await CampaignSeeder.GenerateDataAsync(context);
        await LeadSeeder.GenerateDataAsync(context);
        await LeadContactSeeder.GenerateDataAsync(context);
        await LeadActivitySeeder.GenerateDataAsync(context);
        await SalesQuotationSeeder.GenerateDataAsync(context);
        await SalesOrderSeeder.GenerateDataAsync(context);

        // 5. Purchase Related
        await PurchaseRequisitionSeeder.GenerateDataAsync(context);
        await PurchaseOrderSeeder.GenerateDataAsync(context);

        // 6. Inventory Operations
        await DeliveryOrderSeeder.GenerateDataAsync(context);
        await SalesReturnSeeder.GenerateDataAsync(context);
        await GoodsReceiveSeeder.GenerateDataAsync(context);
        await PurchaseReturnSeeder.GenerateDataAsync(context);
        await TransferOutSeeder.GenerateDataAsync(context);
        await TransferInSeeder.GenerateDataAsync(context);
        await PositiveAdjustmentSeeder.GenerateDataAsync(context);
        await NegativeAdjustmentSeeder.GenerateDataAsync(context);
        await ScrappingSeeder.GenerateDataAsync(context);
        await StockCountSeeder.GenerateDataAsync(context);

        // 7. Finance & Project Related
        await InvoiceSeeder.GenerateDataAsync(context);
        await CreditNoteSeeder.GenerateDataAsync(context);
        await PaymentReceiveSeeder.GenerateDataAsync(context);
        await BillSeeder.GenerateDataAsync(context);
        await DebitNoteSeeder.GenerateDataAsync(context);
        await PaymentDisburseSeeder.GenerateDataAsync(context);
        await BudgetSeeder.GenerateDataAsync(context);
        await ExpenseSeeder.GenerateDataAsync(context);

        await BookingGroupSeeder.GenerateDataAsync(context);
        await BookingResourceSeeder.GenerateDataAsync(context);
        await BookingSeeder.GenerateDataAsync(context);
        await ProgramManagerResourceSeeder.GenerateDataAsync(context);
        await ProgramManagerSeeder.GenerateDataAsync(context);
    }
}