using Microsoft.EntityFrameworkCore.Metadata.Builders;
using Microsoft.EntityFrameworkCore.Metadata.Conventions;
using System.ComponentModel.DataAnnotations;

namespace IRaCIS.Core.Infra.EFCore;

/// <summary>
/// Efcore 最新支持批量配置字符串类型长度作为保底的    官网参考：https://learn.microsoft.com/zh-cn/ef/core/modeling/bulk-configuration#conventions
/// 设置不标注，默认长度，然后标注了与默认长度不一致，那么就是以标注的为准，同时如果标注了MaxLength  ，对于mssql 那就是nvarcharMax,对于pgsql 就是text
/// </summary>
public class DefaultStringLengthConvention : IModelFinalizingConvention
{
    private readonly int _defaultLenth;

    public DefaultStringLengthConvention(int defaultLenth)
    {
        _defaultLenth = defaultLenth;
    }

    public void ProcessModelFinalizing(IConventionModelBuilder modelBuilder, IConventionContext<IConventionModelBuilder> context)
    {
        foreach (var property in modelBuilder.Metadata.GetEntityTypes()
                     .SelectMany(
                         entityType => entityType.GetDeclaredProperties()
                             .Where(
                                 property => property.ClrType == typeof(string))))
        {

            // 获取 MaxLength 特性
            var maxLengthAttribute = property.PropertyInfo?.GetCustomAttributes(typeof(MaxLengthAttribute), false)
                                   .FirstOrDefault() as MaxLengthAttribute;

            // 获取 StringLength 特性
            var stringLengthAttribute = property.PropertyInfo?.GetCustomAttributes(typeof(StringLengthAttribute), false)
                                      .FirstOrDefault() as StringLengthAttribute;

            // 输出调试信息，看看是哪种特性生效
            if (stringLengthAttribute != null)
            {
                //Console.WriteLine($"{property.Name}: StringLength({stringLengthAttribute.MaximumLength})");
                property.Builder.HasMaxLength(stringLengthAttribute.MaximumLength);
            }
            else if (maxLengthAttribute != null)
            {
                //Console.WriteLine($"{property.Name}: MaxLength (no specific length, allowing max)");
            }
            else
            {
                //Console.WriteLine($"{property.Name}: Default length 200");
                property.Builder.HasMaxLength(_defaultLenth);
            }
        }
    }
}
