using Domain.Entities.Members;
using Domain.Entities.Wallets;
using Microsoft.EntityFrameworkCore;
using Microsoft.EntityFrameworkCore.Metadata.Builders;

namespace Infrastructure.Persistence.Configurations.Members;

public sealed class MemberConfiguration : IEntityTypeConfiguration<Member>
{
    public void Configure(EntityTypeBuilder<Member> builder)
    {
        builder.HasIndex(x => x.SID).IsUnique();
        builder.HasIndex(x => x.Email).IsUnique();
        builder.HasIndex(x => x.Name).IsUnique();
        builder.HasIndex(x => x.FullName);
        builder.HasIndex(x => x.Gender);
        builder.HasIndex(x => x.Phone);
        builder.HasIndex(x => x.IsEmailVerified);
        builder.HasIndex(x => x.IsAuthCertified);
        builder.HasIndex(x => x.IsDenied);
        builder.HasIndex(x => x.IsAdmin);
        builder.HasIndex(x => x.IsWithdraw);
        builder.HasIndex(x => x.IsCreator);
        builder.HasIndex(x => x.CreatedAt);
        builder.HasIndex(x => x.DeletedAt);

        // 회원 등급
        builder.HasOne(x => x.MemberGrade).WithMany().HasForeignKey(x => x.MemberGradeID).OnDelete(DeleteBehavior.SetNull);

        // 회원 알림/승인 정보
        builder.HasOne(x => x.MemberApprove).WithOne(x => x.Member).HasForeignKey<MemberApprove>(x => x.MemberID).OnDelete(DeleteBehavior.Cascade);

        // 회원 활동 집계 정보
        builder.HasOne(x => x.MemberStats).WithOne(x => x.Member).HasForeignKey<MemberStats>(x => x.MemberID).OnDelete(DeleteBehavior.Cascade);

        // 지갑 정보
        builder.HasOne(x => x.Wallet).WithOne(x => x.Member).HasForeignKey<Wallet>(x => x.MemberID).OnDelete(DeleteBehavior.Cascade);

        // 채널 정보
        builder.HasOne(x => x.Channel).WithOne(x => x.Member).HasForeignKey<Channel>(x => x.MemberID).OnDelete(DeleteBehavior.Cascade);

        builder.ToTable(nameof(Member), x => x.HasComment("회원 정보"));
        builder.HasKey(x => x.ID);
        builder.Property(x => x.ID).ValueGeneratedOnAdd().HasComment("PK");
        builder.Property(x => x.MemberGradeID).HasComment("회원등급 PK");
        builder.Property(x => x.SID).HasMaxLength(20).IsRequired().HasComment("SID");
        builder.Property(x => x.Email).HasMaxLength(60).IsRequired().HasComment("이메일");
        builder.Property(x => x.Name).HasMaxLength(20).HasComment("별명");
        builder.Property(x => x.FullName).HasMaxLength(40).HasComment("본명");
        builder.Property(x => x.FirstName).HasMaxLength(20).HasComment("본명(성)");
        builder.Property(x => x.LastName).HasMaxLength(40).HasComment("본명(이름)");
        builder.Property(x => x.Password).HasMaxLength(255).HasComment("비밀번호");
        builder.Property(x => x.Intro).HasMaxLength(1000).HasComment("자기소개");
        builder.Property(x => x.Summary).HasMaxLength(50).HasComment("한마디");
        builder.Property(x => x.Phone).HasMaxLength(15).HasComment("연락처");
        builder.Property(x => x.Birthday).HasComment("생년월일");
        builder.Property(x => x.Gender).HasConversion<int?>().HasComment("성별");
        builder.Property(x => x.Thumb).HasMaxLength(255).HasComment("썸네일");
        builder.Property(x => x.Icon).HasMaxLength(255).HasComment("아이콘");
        builder.Property(x => x.IsEmailVerified).IsRequired().HasComment("이메일 인증 여부");
        builder.Property(x => x.IsAuthCertified).IsRequired().HasComment("본인 인증 여부");
        builder.Property(x => x.IsDenied).IsRequired().HasComment("차단 여부");
        builder.Property(x => x.IsAdmin).IsRequired().HasComment("운영진 여부");
        builder.Property(x => x.IsWithdraw).IsRequired().HasComment("탈퇴 여부");
        builder.Property(x => x.IsCreator).IsRequired().HasComment("크리에이터 여부");
        builder.Property(x => x.DeviceInfo).HasMaxLength(400).HasComment("로그인 단말기 정보");
        builder.Property(x => x.SignupIP).HasMaxLength(15).HasComment("회원가입 시 IP");
        builder.Property(x => x.LastLoginIp).HasMaxLength(15).HasComment("마지막 로그인 IP");
        builder.Property(x => x.IpAddress).HasMaxLength(45).HasComment("IP Address");
        builder.Property(x => x.UserAgent).HasMaxLength(255).HasComment("User-agent");
        builder.Property(x => x.LastLoginAt).HasComment("마지막 로그인 일시");
        builder.Property(x => x.LastEmailChangedAt).HasComment("마지막 이메일 변경 일시");
        builder.Property(x => x.LastNameChangedAt).HasComment("마지막 별명 변경 일시");
        builder.Property(x => x.LastSummaryChangedAt).HasComment("마지막 한마디 변경 일시");
        builder.Property(x => x.LastIntroChangedAt).HasComment("마지막 자기소개 변경 일시");
        builder.Property(x => x.EmailVerifiedAt).HasComment("이메일 인증 일시");
        builder.Property(x => x.AuthCertifiedAt).HasComment("본인인증 일시");
        builder.Property(x => x.PasswordUpdatedAt).HasComment("비밀번호 변경 일시");
        builder.Property(x => x.CreatedAt).IsRequired().HasComment("가입 일시");
        builder.Property(x => x.UpdatedAt).HasComment("수정 일시");
        builder.Property(x => x.DeletedAt).HasComment("탈퇴 일시");
        builder.Property(x => x.DeniedAt).HasComment("차단 일시");
    }
}