using Microsoft.EntityFrameworkCore;
using Monitoring.Core.Domain.AssetManagement;

namespace Monitoring.Infrastructure.Data.Configurations;

public class AssetConfiguration : IEntityTypeConfiguration<Asset>
{
	public void Configure(
		Microsoft.EntityFrameworkCore.Metadata.Builders.EntityTypeBuilder<Asset> builder
	)
	{
		_ = builder.Property(x => x.Id).IsRequired().HasConversion(x => x.Value, x => new(x));
		_ = builder.HasKey(x => x.Id);
		_ = builder.HasIndex(x => x.Id).IsUnique();

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

		_ = builder
			.Property(x => x.Description)
			.IsRequired()
			.HasMaxLength(AssetDescription.MaxLength)
			.HasConversion(x => x.Value, x => AssetDescription.Create(x));
		
		_ = builder.Property(x => x.Comment)
			.IsRequired()
			.HasMaxLength(AssetComment.MaxLength)
			.HasConversion(x => x.Value, x => AssetComment.Create(x))
			.HasColumnName("Comment");


		_ = builder
			.HasOne(x => x.Organization)
			.WithMany(x => x.Assets)
			.HasForeignKey(x => x.OrganizationId)
			.IsRequired()
			.OnDelete(DeleteBehavior.Cascade);

		_ = builder.ComplexProperty(
			x => x.Address,
			builder =>
			{
				_ = builder
					.Property(x => x.Country)
					.IsRequired()
					.HasMaxLength(AssetName.MaxLength)
					.HasColumnName("Country");

				_ = builder
					.Property(x => x.Region)
					.IsRequired()
					.HasMaxLength(AssetName.MaxLength)
					.HasColumnName("Region");

				_ = builder
					.Property(x => x.City)
					.IsRequired()
					.HasMaxLength(AssetName.MaxLength)
					.HasColumnName("City");

				_ = builder
					.Property(x => x.Street)
					.IsRequired()
					.HasMaxLength(AssetName.MaxLength)
					.HasColumnName("Street");

				_ = builder
					.Property(x => x.House)
					.IsRequired()
					.HasMaxLength(AssetName.MaxLength)
					.HasColumnName("House");

				_ = builder
					.Property(x => x.Building)
					.IsRequired()
					.HasMaxLength(AssetName.MaxLength)
					.HasColumnName("Building");

				_ = builder
					.Property(x => x.Apartment)
					.IsRequired()
					.HasMaxLength(AssetName.MaxLength)
					.HasColumnName("Apartment");

				_ = builder
					.Property(x => x.GateCode)
					.IsRequired()
					.HasMaxLength(AssetName.MaxLength)
					.HasColumnName("GateCode");

				_ = builder
					.Property(x => x.IntercomCode)
					.IsRequired()
					.HasMaxLength(AssetName.MaxLength)
					.HasColumnName("IntercomCode");
			}
		);

		_ = builder.ComplexProperty(
			x => x.Owner,
			builder =>
			{
				_ = builder
					.Property(x => x.Name)
					.IsRequired()
					.HasMaxLength(AssetName.MaxLength)
					.HasColumnName("OwnerName");

				_ = builder
					.Property(x => x.Password)
					.IsRequired()
					.HasMaxLength(AssetName.MaxLength)
					.HasColumnName("OwnerPassword");

				_ = builder
					.Property(x => x.Phone1)
					.IsRequired()
					.HasMaxLength(AssetName.MaxLength)
					.HasColumnName("OwnerPhone1");

				_ = builder
					.Property(x => x.Phone2)
					.IsRequired()
					.HasMaxLength(AssetName.MaxLength)
					.HasColumnName("OwnerPhone2");
			}
		);

		_ = builder.ComplexProperty(
			x => x.Passwords,
			builder =>
			{
				_ = builder
					.Property(x => x.IdentificationPassword)
					.IsRequired()
					.HasMaxLength(AssetName.MaxLength)
					.HasColumnName("IdentificationPassword");

				_ = builder
					.Property(x => x.DuressPassword)
					.IsRequired()
					.HasMaxLength(AssetName.MaxLength)
					.HasColumnName("DuressPassword");
			}
		);

		_ = builder.ComplexProperty(
			x => x.Coordinates,
			builder =>
			{
				_ = builder.Property(x => x.Latitude).HasColumnName("Latitude");

				_ = builder.Property(x => x.Longitude).HasColumnName("Longitude");
			}
		);

		_ = builder.HasMany(x => x.Groups).WithMany(x => x.Assets);

		_ = builder
			.Property(x => x.IsOnline)
			.IsRequired()
			.HasColumnName("IsOnline")
			.HasDefaultValue(false);

		_ = builder
			.HasOne(x => x.ServiceOrganization)
			.WithMany(s => s.Assets)
			.HasForeignKey(x => x.ServiceOrganizationId)
			.OnDelete(DeleteBehavior.SetNull);

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

		_ = builder.Property(x => x.LastStatusChange).HasColumnName("LastStatusChange");

		_ = builder
			.Property(x => x.RowVersion)
			.IsRequired()
			.IsRowVersion()
			.HasColumnName("RowVersion");
	}
}
