using Microsoft.EntityFrameworkCore;

using Monitoring.Core.Domain;
using Monitoring.Core.Domain.RolePrimitives;
using Monitoring.Core.Domain.UserPrimitives;
using Monitoring.Infrastructure.Abstractions;

namespace Monitoring.Infrastructure.Data.Configurations;

public class UserConfiguration(
	IPasswordService passwordService
) : IEntityTypeConfiguration<User>
{
	public void Configure(Microsoft.EntityFrameworkCore.Metadata.Builders.EntityTypeBuilder<User> builder)
	{
		_ = builder.HasKey(x => x.Id);
		_ = builder.Property(x => x.Id)
			.IsRequired()
			.HasConversion(x => x.Value, x => new UserId(x));

		_ = builder.Property(x => x.Username)
			.IsRequired()
			.HasMaxLength(UserName.MaxLength)
			.HasConversion(x => x.Value, x => UserName.Create(x));

		_ = builder.Property(x => x.UpperCaseUsername)
			.IsRequired()
			.HasMaxLength(UserUpperCaseName.MaxLength)
			.HasConversion(x => x.Value, x => UserUpperCaseName.Create(x));

		_ = builder.Property(x => x.PasswordHash)
			.IsRequired()
			.HasMaxLength(PasswordHash.MaxLength)
			.HasConversion(x => x.Value, x => PasswordHash.Create(x));

		_ = builder.HasOne(x => x.Role)
			.WithMany(x => x.Users)
			.HasForeignKey(x => x.RoleId)
			.OnDelete(DeleteBehavior.NoAction);
		_ = builder.Property(x => x.RoleId)
			.HasConversion(x => x.Value, x => new(x));

		// don't change it, because it's used for password hashing
		const string fixedSalt = "$2a$11$KqE5dEUpwM1gV6l3UBT3eu";
		var password = Password.Create("qweQWE123!@#");
		var salt = PasswordSalt.Create(fixedSalt);
		_ = builder.HasData([
			User.Create(
				new UserId(new Guid("E9BF7E86-FBE3-4C28-B6CC-B27DC62684DF")),
				UserName.Create("admin"),
				passwordService.HashWithFixedSalt(password, salt),
				new RoleId(new Guid("60782519-2571-4153-9010-312463165300"))
			)
		]);
	}
}
