# Generate-SeedSql.ps1
# Generates seed_admins.sql with properly hashed passwords for ASP.NET Core Identity.
#
# Usage:
#   .\Generate-SeedSql.ps1
#
# Requires: PowerShell 5.1+ on .NET Framework 4.7.2+ OR PowerShell 7+

function New-IdentityPasswordHash {
    param([string]$Password)

    # 16-byte random salt
    $salt = [byte[]]::new(16)
    $rng  = [System.Security.Cryptography.RandomNumberGenerator]::Create()
    $rng.GetBytes($salt)
    $rng.Dispose()

    # PBKDF2-HMAC-SHA256, 100,000 iterations, 32-byte output
    $pbkdf2 = [System.Security.Cryptography.Rfc2898DeriveBytes]::new(
        $Password, $salt, 100000,
        [System.Security.Cryptography.HashAlgorithmName]::SHA256)
    $subkey = $pbkdf2.GetBytes(32)
    $pbkdf2.Dispose()

    # ASP.NET Core Identity v3 wire format (61 bytes):
    # [0]    = 0x01 (version marker)
    # [1-4]  = 0x00000001 (PRF = HMACSHA256, big-endian uint32)
    # [5-8]  = 0x000186A0 (iterations = 100000, big-endian uint32)
    # [9-12] = 0x00000010 (salt length = 16, big-endian uint32)
    # [13-28] = salt bytes
    # [29-60] = subkey bytes
    $buf = [byte[]]::new(61)
    $buf[0]  = 0x01
    $buf[1]  = 0x00; $buf[2]  = 0x00; $buf[3]  = 0x00; $buf[4]  = 0x01
    $buf[5]  = 0x00; $buf[6]  = 0x01; $buf[7]  = 0x86; $buf[8]  = 0xA0
    $buf[9]  = 0x00; $buf[10] = 0x00; $buf[11] = 0x00; $buf[12] = 0x10
    [Array]::Copy($salt,   0, $buf, 13, 16)
    [Array]::Copy($subkey, 0, $buf, 29, 32)

    return [Convert]::ToBase64String($buf)
}

# ---- Generate GUIDs and hashes -----------------------------------------------

$roleSuperAdmin = [Guid]::NewGuid().ToString()
$roleAdmin      = [Guid]::NewGuid().ToString()
$roleManager    = [Guid]::NewGuid().ToString()
$roleEmployee   = [Guid]::NewGuid().ToString()
$roleShopFloor  = [Guid]::NewGuid().ToString()
$roleReadOnly   = [Guid]::NewGuid().ToString()

$user1Id       = [Guid]::NewGuid().ToString()
$user2Id       = [Guid]::NewGuid().ToString()
$user1Stamp    = [Guid]::NewGuid().ToString()
$user2Stamp    = [Guid]::NewGuid().ToString()
$user1Security = [Guid]::NewGuid().ToString()
$user2Security = [Guid]::NewGuid().ToString()

$now = (Get-Date).ToUniversalTime().ToString("yyyy-MM-dd HH:mm:ss")

Write-Host "Hashing SuperAdmin123! ..." -ForegroundColor Cyan
$hash1 = New-IdentityPasswordHash "SuperAdmin123!"
Write-Host "Hashing Admin123! ..." -ForegroundColor Cyan
$hash2 = New-IdentityPasswordHash "Admin123!"
Write-Host "Done. Writing SQL file..." -ForegroundColor Cyan

# ---- Build SQL ---------------------------------------------------------------

$outFile = Join-Path $PSScriptRoot "seed_admins.sql"

$lines = [System.Collections.Generic.List[string]]::new()

$lines.Add("-- =============================================================================")
$lines.Add("-- PowderCoating App - Initial Seed SQL")
$lines.Add("-- Generated: $now UTC")
$lines.Add("--")
$lines.Add("-- Run this against your Azure SQL database when startup seeding fails.")
$lines.Add("-- All inserts are guarded with IF NOT EXISTS and are safe to re-run.")
$lines.Add("-- =============================================================================")
$lines.Add("")
$lines.Add("SET NOCOUNT ON;")
$lines.Add("GO")
$lines.Add("")
$lines.Add("-- 1. Default Company")
$lines.Add("")
$lines.Add("IF NOT EXISTS (SELECT 1 FROM Companies WHERE CompanyCode = 'DEMO')")
$lines.Add("BEGIN")
$lines.Add("    SET IDENTITY_INSERT Companies ON;")
$lines.Add("")
$lines.Add("    INSERT INTO Companies (")
$lines.Add("        Id, CompanyId, CompanyName, CompanyCode,")
$lines.Add("        PrimaryContactName, PrimaryContactEmail, Phone,")
$lines.Add("        Address, City, State, ZipCode,")
$lines.Add("        IsActive, SubscriptionPlan, SubscriptionStatus,")
$lines.Add("        SubscriptionStartDate, TimeZone,")
$lines.Add("        CreatedAt, IsDeleted")
$lines.Add("    ) VALUES (")
$lines.Add("        1, 1, 'Demo Company', 'DEMO',")
$lines.Add("        'Admin User', 'admin@demo.com', '(555) 123-4567',")
$lines.Add("        '123 Demo Street', 'Demo City', 'CA', '90210',")
$lines.Add("        1, 2, 0,")
$lines.Add("        '$now', 'America/New_York',")
$lines.Add("        '$now', 0")
$lines.Add("    );")
$lines.Add("")
$lines.Add("    SET IDENTITY_INSERT Companies OFF;")
$lines.Add("    PRINT 'Company inserted.';")
$lines.Add("END")
$lines.Add("ELSE")
$lines.Add("    PRINT 'Company already exists - skipped.';")
$lines.Add("GO")
$lines.Add("")
$lines.Add("-- 2. Roles")
$lines.Add("")
$lines.Add("IF NOT EXISTS (SELECT 1 FROM AspNetRoles WHERE NormalizedName = 'SUPERADMIN')")
$lines.Add("    INSERT INTO AspNetRoles (Id, Name, NormalizedName, ConcurrencyStamp)")
$lines.Add("    VALUES ('$roleSuperAdmin', 'SuperAdmin', 'SUPERADMIN', NEWID());")
$lines.Add("")
$lines.Add("IF NOT EXISTS (SELECT 1 FROM AspNetRoles WHERE NormalizedName = 'ADMINISTRATOR')")
$lines.Add("    INSERT INTO AspNetRoles (Id, Name, NormalizedName, ConcurrencyStamp)")
$lines.Add("    VALUES ('$roleAdmin', 'Administrator', 'ADMINISTRATOR', NEWID());")
$lines.Add("")
$lines.Add("IF NOT EXISTS (SELECT 1 FROM AspNetRoles WHERE NormalizedName = 'MANAGER')")
$lines.Add("    INSERT INTO AspNetRoles (Id, Name, NormalizedName, ConcurrencyStamp)")
$lines.Add("    VALUES ('$roleManager', 'Manager', 'MANAGER', NEWID());")
$lines.Add("")
$lines.Add("IF NOT EXISTS (SELECT 1 FROM AspNetRoles WHERE NormalizedName = 'EMPLOYEE')")
$lines.Add("    INSERT INTO AspNetRoles (Id, Name, NormalizedName, ConcurrencyStamp)")
$lines.Add("    VALUES ('$roleEmployee', 'Employee', 'EMPLOYEE', NEWID());")
$lines.Add("")
$lines.Add("IF NOT EXISTS (SELECT 1 FROM AspNetRoles WHERE NormalizedName = 'SHOPFLOOR')")
$lines.Add("    INSERT INTO AspNetRoles (Id, Name, NormalizedName, ConcurrencyStamp)")
$lines.Add("    VALUES ('$roleShopFloor', 'ShopFloor', 'SHOPFLOOR', NEWID());")
$lines.Add("")
$lines.Add("IF NOT EXISTS (SELECT 1 FROM AspNetRoles WHERE NormalizedName = 'READONLY')")
$lines.Add("    INSERT INTO AspNetRoles (Id, Name, NormalizedName, ConcurrencyStamp)")
$lines.Add("    VALUES ('$roleReadOnly', 'ReadOnly', 'READONLY', NEWID());")
$lines.Add("")
$lines.Add("PRINT 'Roles inserted.';")
$lines.Add("GO")
$lines.Add("")
$lines.Add("-- 3. SuperAdmin Users")
$lines.Add("")
$lines.Add("-- User 1: superadmin@powdercoating.com / SuperAdmin123!")
$lines.Add("IF NOT EXISTS (SELECT 1 FROM AspNetUsers WHERE NormalizedEmail = 'SUPERADMIN@POWDERCOATING.COM')")
$lines.Add("BEGIN")
$lines.Add("    INSERT INTO AspNetUsers (")
$lines.Add("        Id, UserName, NormalizedUserName, Email, NormalizedEmail,")
$lines.Add("        EmailConfirmed, PasswordHash, SecurityStamp, ConcurrencyStamp,")
$lines.Add("        PhoneNumber, PhoneNumberConfirmed, TwoFactorEnabled,")
$lines.Add("        LockoutEnd, LockoutEnabled, AccessFailedCount,")
$lines.Add("        CompanyId, CompanyRole,")
$lines.Add("        FirstName, LastName, EmployeeNumber,")
$lines.Add("        HireDate, IsActive,")
$lines.Add("        Department, Position, HourlyRate,")
$lines.Add("        Theme, DateFormat, TimeZone, SidebarColor,")
$lines.Add("        CanViewShopFloor, CanManageJobs, CanManageInventory, CanManageCustomers,")
$lines.Add("        CanCreateQuotes, CanApproveQuotes, CanManageCalendar, CanViewCalendar,")
$lines.Add("        CanManageProducts, CanViewProducts, CanManageEquipment,")
$lines.Add("        CanManageSuppliers, CanManageMaintenance,")
$lines.Add("        CreatedAt")
$lines.Add("    ) VALUES (")
$lines.Add("        '$user1Id',")
$lines.Add("        'superadmin@powdercoating.com', 'SUPERADMIN@POWDERCOATING.COM',")
$lines.Add("        'superadmin@powdercoating.com', 'SUPERADMIN@POWDERCOATING.COM',")
$lines.Add("        1, '$hash1', '$user1Security', '$user1Stamp',")
$lines.Add("        NULL, 0, 0, NULL, 1, 0,")
$lines.Add("        1, NULL,")
$lines.Add("        'Super', 'Admin', 'SA-001',")
$lines.Add("        '$now', 1,")
$lines.Add("        'Platform', 'Super Administrator', 0,")
$lines.Add("        'light', 'MM/dd/yyyy', 'America/New_York', 'ocean',")
$lines.Add("        1, 1, 1, 1,")
$lines.Add("        1, 1, 1, 1,")
$lines.Add("        1, 1, 1,")
$lines.Add("        1, 1,")
$lines.Add("        '$now'")
$lines.Add("    );")
$lines.Add("    PRINT 'User superadmin@powdercoating.com inserted.';")
$lines.Add("END")
$lines.Add("ELSE")
$lines.Add("    PRINT 'User superadmin@powdercoating.com already exists - skipped.';")
$lines.Add("GO")
$lines.Add("")
$lines.Add("-- User 2: admin@powdercoating.com / Admin123!")
$lines.Add("IF NOT EXISTS (SELECT 1 FROM AspNetUsers WHERE NormalizedEmail = 'ADMIN@POWDERCOATING.COM')")
$lines.Add("BEGIN")
$lines.Add("    INSERT INTO AspNetUsers (")
$lines.Add("        Id, UserName, NormalizedUserName, Email, NormalizedEmail,")
$lines.Add("        EmailConfirmed, PasswordHash, SecurityStamp, ConcurrencyStamp,")
$lines.Add("        PhoneNumber, PhoneNumberConfirmed, TwoFactorEnabled,")
$lines.Add("        LockoutEnd, LockoutEnabled, AccessFailedCount,")
$lines.Add("        CompanyId, CompanyRole,")
$lines.Add("        FirstName, LastName, EmployeeNumber,")
$lines.Add("        HireDate, IsActive,")
$lines.Add("        Department, Position, HourlyRate,")
$lines.Add("        Theme, DateFormat, TimeZone, SidebarColor,")
$lines.Add("        CanViewShopFloor, CanManageJobs, CanManageInventory, CanManageCustomers,")
$lines.Add("        CanCreateQuotes, CanApproveQuotes, CanManageCalendar, CanViewCalendar,")
$lines.Add("        CanManageProducts, CanViewProducts, CanManageEquipment,")
$lines.Add("        CanManageSuppliers, CanManageMaintenance,")
$lines.Add("        CreatedAt")
$lines.Add("    ) VALUES (")
$lines.Add("        '$user2Id',")
$lines.Add("        'admin@powdercoating.com', 'ADMIN@POWDERCOATING.COM',")
$lines.Add("        'admin@powdercoating.com', 'ADMIN@POWDERCOATING.COM',")
$lines.Add("        1, '$hash2', '$user2Security', '$user2Stamp',")
$lines.Add("        NULL, 0, 0, NULL, 1, 0,")
$lines.Add("        1, NULL,")
$lines.Add("        'Admin', 'User', 'SA-002',")
$lines.Add("        '$now', 1,")
$lines.Add("        'Platform', 'Platform Administrator', 0,")
$lines.Add("        'light', 'MM/dd/yyyy', 'America/New_York', 'ocean',")
$lines.Add("        1, 1, 1, 1,")
$lines.Add("        1, 1, 1, 1,")
$lines.Add("        1, 1, 1,")
$lines.Add("        1, 1,")
$lines.Add("        '$now'")
$lines.Add("    );")
$lines.Add("    PRINT 'User admin@powdercoating.com inserted.';")
$lines.Add("END")
$lines.Add("ELSE")
$lines.Add("    PRINT 'User admin@powdercoating.com already exists - skipped.';")
$lines.Add("GO")
$lines.Add("")
$lines.Add("-- 4. Assign SuperAdmin role to both users")
$lines.Add("")
$lines.Add("DECLARE @roleId   NVARCHAR(450) = (SELECT Id FROM AspNetRoles WHERE NormalizedName = 'SUPERADMIN');")
$lines.Add("DECLARE @u1Id     NVARCHAR(450) = (SELECT Id FROM AspNetUsers  WHERE NormalizedEmail = 'SUPERADMIN@POWDERCOATING.COM');")
$lines.Add("DECLARE @u2Id     NVARCHAR(450) = (SELECT Id FROM AspNetUsers  WHERE NormalizedEmail = 'ADMIN@POWDERCOATING.COM');")
$lines.Add("")
$lines.Add("IF @u1Id IS NOT NULL AND @roleId IS NOT NULL")
$lines.Add("    AND NOT EXISTS (SELECT 1 FROM AspNetUserRoles WHERE UserId = @u1Id AND RoleId = @roleId)")
$lines.Add("BEGIN")
$lines.Add("    INSERT INTO AspNetUserRoles (UserId, RoleId) VALUES (@u1Id, @roleId);")
$lines.Add("    PRINT 'Role assigned to superadmin@powdercoating.com.';")
$lines.Add("END")
$lines.Add("")
$lines.Add("IF @u2Id IS NOT NULL AND @roleId IS NOT NULL")
$lines.Add("    AND NOT EXISTS (SELECT 1 FROM AspNetUserRoles WHERE UserId = @u2Id AND RoleId = @roleId)")
$lines.Add("BEGIN")
$lines.Add("    INSERT INTO AspNetUserRoles (UserId, RoleId) VALUES (@u2Id, @roleId);")
$lines.Add("    PRINT 'Role assigned to admin@powdercoating.com.';")
$lines.Add("END")
$lines.Add("GO")
$lines.Add("")
$lines.Add("PRINT '================================================';")
$lines.Add("PRINT 'Seed complete.';")
$lines.Add("PRINT 'Login 1: superadmin@powdercoating.com / SuperAdmin123!';")
$lines.Add("PRINT 'Login 2: admin@powdercoating.com / Admin123!';")
$lines.Add("PRINT '================================================';")
$lines.Add("GO")

$lines | Set-Content -Path $outFile -Encoding UTF8

Write-Host ""
Write-Host "SQL file written to: $outFile" -ForegroundColor Green
Write-Host ""
Write-Host "Run it against your Azure SQL database using:" -ForegroundColor Yellow
Write-Host "  sqlcmd -S <server>.database.windows.net -d PowderCoatingDb -U <user> -P <password> -i seed_admins.sql" -ForegroundColor White
Write-Host "  OR paste it into Azure Portal > Query Editor" -ForegroundColor White
Write-Host ""
Write-Host "Login 1: superadmin@powdercoating.com / SuperAdmin123!" -ForegroundColor Cyan
Write-Host "Login 2: admin@powdercoating.com / Admin123!" -ForegroundColor Cyan
