namespace OCES.Resonance.Core;

/// <summary>
/// 音频元数据验证器，验证元数据完整性和格式
/// </summary>
public class AudioFileMetaValidator
{
    /// <summary>
    /// 验证必填字段是否完整
    /// </summary>
    /// <param name="meta">音频元数据对象</param>
    /// <param name="errors">验证错误列表</param>
    /// <returns>是否验证通过</returns>
    public bool Validate(AudioFileMeta meta, out List<string> errors)
    {
        errors = new List<string>();

        if (meta == null)
        {
            errors.Add("元数据对象为空");
            return false;
        }

        // 验证必备字符串字段
        ValidateRequiredField(meta.UniqueId, "UniqueId", errors);
        ValidateRequiredField(meta.Md5, "Md5", errors);
        ValidateRequiredField(meta.Path, "Path", errors);
        ValidateRequiredField(meta.Filename, "Filename", errors);
        ValidateRequiredField(meta.Folder, "Folder", errors);
        ValidateRequiredField(meta.Directory, "Directory", errors);
        ValidateRequiredField(meta.Type, "Type", errors);

        // 验证数值字段
        ValidatePositiveValue(meta.Duration, "Duration", errors);
        ValidatePositiveValue(meta.TotalSamples, "TotalSamples", errors);
        ValidatePositiveValue(meta.BitDepth, "BitDepth", errors);
        ValidatePositiveValue(meta.Channels, "Channels", errors);
        ValidatePositiveValue(meta.SampleRate, "SampleRate", errors);

        // 验证日期字段
        ValidateRequiredField(meta.DateAdded, "DateAdded", errors);
        ValidateRequiredField(meta.OriginalModificationDate, "OriginalModificationDate", errors);
        ValidateRequiredField(meta.OriginationTime, "OriginationTime", errors);

        // 验证文件路径是否存在
        if (!File.Exists(meta.Path))
        {
            errors.Add($"文件不存在：{meta.Path}");
        }

        // 验证 MD5 格式（32 位十六进制）
        if (!IsValidMd5(meta.Md5))
        {
            errors.Add($"MD5 格式无效：{meta.Md5}");
        }

        return errors.Count == 0;
    }

    /// <summary>
    /// 验证必填字符串字段
    /// </summary>
    private static void ValidateRequiredField(string? value, string fieldName, List<string> errors)
    {
        if (string.IsNullOrWhiteSpace(value))
        {
            errors.Add($"{fieldName} 不能为空");
        }
    }

    /// <summary>
    /// 验证必填值类型字段
    /// </summary>
    private static void ValidateRequiredField<T>(T value, string fieldName, List<string> errors) where T : struct
    {
        if (EqualityComparer<T>.Default.Equals(value, default))
        {
            errors.Add($"{fieldName} 不能为空");
        }
    }

    /// <summary>
    /// 验证正数值
    /// </summary>
    private static void ValidatePositiveValue(double value, string fieldName, List<string> errors)
    {
        if (value <= 0)
        {
            errors.Add($"{fieldName} 必须为正数 (当前值：{value})");
        }
    }

    /// <summary>
    /// 验证正数整数值
    /// </summary>
    private static void ValidatePositiveValue(int value, string fieldName, List<string> errors)
    {
        if (value <= 0)
        {
            errors.Add($"{fieldName} 必须为正数 (当前值：{value})");
        }
    }

    /// <summary>
    /// 验证正数无符号整数值
    /// </summary>
    private static void ValidatePositiveValue(uint value, string fieldName, List<string> errors)
    {
        if (value <= 0)
        {
            errors.Add($"{fieldName} 必须为正数 (当前值：{value})");
        }
    }

    /// <summary>
    /// 验证 MD5 格式是否有效
    /// </summary>
    private static bool IsValidMd5(string md5)
    {
        if (string.IsNullOrWhiteSpace(md5) || md5.Length != 32)
        {
            return false;
        }

        return md5.All(c => (c >= '0' && c <= '9') || (c >= 'a' && c <= 'f') || (c >= 'A' && c <= 'F'));
    }
}
