using System.Text.Json;
using Microsoft.AspNetCore.Identity;
using Microsoft.EntityFrameworkCore;
using NexusIdentity.Api.Models;

namespace NexusIdentity.Api.Data;

public static class SeedData
{
    private static readonly PasswordHasher<string> Hasher = new();

    public static readonly string[] DefaultRoles =
    [
        "User",
        "Administrator",
        "MasterDeveloper",
    ];

    public static readonly (string Id, string Name)[] DefaultOrganizations =
    [
        ("ORG-NINJA-PLATFORME", "Ninja Platforme ApS"),
        ("ORG-NINJAKERNEN", "Ninjakernen Holding ApS"),
        ("ORG-RENNINJA", "Renninja ApS"),
    ];

    public static readonly (string Email, string Password, string DisplayName, string Theme, string Role, string? OrganizationId)[] PocUsers =
    [
        ("admin@nexus.local", "NexusAdmin1!", "Admin Bruger", "dark", "MasterDeveloper", "ORG-NINJAKERNEN"),
        ("user@nexus.local", "NexusUser1!", "Test Bruger", "light", "User", "ORG-RENNINJA"),
    ];

    public static async Task InitializeAsync(IdentityDbContext db, bool seedPocUsers)
    {
        await DatabaseInitializer.EnsureSchemaAsync(db);
        await SeedRolesAsync(db);
        await SeedOrganizationsAsync(db);
        await SeedPoliciesAsync(db);

        if (!seedPocUsers || await db.Users.AnyAsync())
        {
            return;
        }

        foreach (var (email, password, displayName, theme, role, organizationId) in PocUsers)
        {
            db.Users.Add(new UserEntity
            {
                Id = Guid.NewGuid(),
                Email = email,
                PasswordHash = Hasher.HashPassword(email, password),
                DisplayName = displayName,
                Theme = theme,
                Role = role,
                OrganizationId = organizationId,
                IsActive = true,
                CreatedAt = DateTime.UtcNow,
            });
        }

        db.AuditLogs.Add(new AuditLogEntity
        {
            Id = Guid.NewGuid(),
            EventType = "Seed",
            Message = "POC users seeded (POC credentials only — not for production).",
            CreatedAt = DateTime.UtcNow,
        });

        await db.SaveChangesAsync();
    }

    private static async Task SeedRolesAsync(IdentityDbContext db)
    {
        foreach (var roleName in DefaultRoles)
        {
            if (await db.Roles.AnyAsync(r => r.Name == roleName))
            {
                continue;
            }

            db.Roles.Add(new RoleEntity
            {
                Id = Guid.NewGuid(),
                Name = roleName,
            });
        }

        await db.SaveChangesAsync();
    }

    private static async Task SeedOrganizationsAsync(IdentityDbContext db)
    {
        foreach (var (id, name) in DefaultOrganizations)
        {
            if (await db.Organizations.AnyAsync(o => o.Id == id))
            {
                continue;
            }

            db.Organizations.Add(new OrganizationEntity
            {
                Id = id,
                Name = name,
                CreatedAtUtc = DateTime.UtcNow,
                IsActive = true,
            });
        }

        await db.SaveChangesAsync();
    }

    private static async Task SeedPoliciesAsync(IdentityDbContext db)
    {
        var platformPolicies = new[]
        {
            new PolicyEntity
            {
                Id = "policy-platform-lock",
                Name = "Platform Lock (POC)",
                Scope = "platform",
                IsEnabled = true,
                Summary = "Requires safe-POC mode for overlay shell lockdown.",
                RulesJson = JsonSerializer.Serialize(new { requireSafePoc = true }),
            },
            new PolicyEntity
            {
                Id = "policy-device-trust",
                Name = "Device Trust Required",
                Scope = "device",
                IsEnabled = true,
                Summary = "Devices must be Trusted before full platform access.",
                RulesJson = JsonSerializer.Serialize(new { requiredTrustStatus = "Trusted" }),
            },
            new PolicyEntity
            {
                Id = "policy-enrollment-approval",
                Name = "Enrollment Approval",
                Scope = "enrollment",
                IsEnabled = true,
                Summary = "Remote enrollments require admin approval (POC).",
                RulesJson = JsonSerializer.Serialize(new { requireAdminApproval = true }),
            },
        };

        foreach (var policy in platformPolicies)
        {
            if (await db.Policies.AnyAsync(p => p.Id == policy.Id))
            {
                continue;
            }

            db.Policies.Add(policy);
        }

        await db.SaveChangesAsync();
    }
}
