using System.Security.Cryptography;
using ATL;

namespace OCES.Resonance.Core;

/// <summary>
/// 音频元数据读取器，使用 ATL 库读取音频文件的技术参数和元数据
/// </summary>
public class AudioMetadataReader
{
    /// <summary>
    /// 从音频文件读取元数据
    /// </summary>
    /// <param name="audioFile">音频文件路径</param>
    /// <returns>音频元数据对象</returns>
    public AudioFileMeta ReadMetadata(FileInfo audioFile)
    {
        if (!audioFile.Exists)
        {
            throw new FileNotFoundException($"文件不存在：{audioFile}");
        }

        Track track = new(audioFile.FullName);

        // 映射 ATL 元数据到 AudioFileMeta
        AudioFileMeta meta = new()
        {
            // 必备条目
            Id = 0, // 自增 ID，由数据库生成
            UniqueId = GenerateUuid(),
            Md5 = CalculateMd5(audioFile.FullName),
            Path = audioFile.FullName,
            Filename = audioFile.Name,
            Folder = audioFile.Directory?.Name ?? string.Empty,
            Directory = audioFile.DirectoryName ?? string.Empty,
            Duration = track.DurationMs / 1000,
            BitDepth = track.BitDepth,
            Channels = track.ChannelsArrangement.NbChannels,
            SampleRate = track.SampleRate,
            Type = audioFile.Extension.TrimStart('.').ToUpperInvariant(),
            DateAdded = DateTime.Now,
            OriginalModificationDate = audioFile.LastWriteTime,
            OriginationTime = audioFile.CreationTime,

            // 可选条目
            Bpm = track.BPM > 0 ? track.BPM : null,
            Description = track.Description,
            Genre = track.Genre,
            Artist = track.Artist,
            Composer = track.Composer,
            Comments = track.Comment,
            Publisher = track.Publisher,
            Copyright = track.Copyright,
            CdTitle = track.Album,
            DiscNumber = track.DiscNumber,
            TrackTitle = track.Title,
            ReleaseDate = track.OriginalReleaseDate,
            TrackYear = track.Year,
            TrackNumber = track.TrackNumber,
            Group = track.Group,
            
            
            // BWF 特定字段 (通过附加数据获取)
            CodingHistory = GetBwfField(track, "CodingHistory"),
            BwfOriginator = GetBwfField(track, "BwfOriginator"),
            BwfOriginatorRef = GetBwfField(track, "BwfOriginatorRef"),
        };

        return meta;
    }

    /// <summary>
    /// 获取 BWF 字段值
    /// </summary>
    private static string? GetBwfField(Track track, string fieldName)
    {
        try
        {
            if (track.AdditionalFields != null && track.AdditionalFields.TryGetValue(fieldName, out string? field))
            {
                return field;
            }
        }
        catch
        {
            // 忽略 BWF 字段读取错误
        }
        return null;
    }

    /// <summary>
    /// 计算文件 MD5 值
    /// </summary>
    /// <param name="filePath">文件路径</param>
    /// <returns>MD5 哈希值（十六进制字符串）</returns>
    static string CalculateMd5(string filePath)
    {
        using MD5 md5 = MD5.Create();
        using FileStream stream = File.OpenRead(filePath);
        
        byte[] hash = md5.ComputeHash(stream);
        return Convert.ToHexStringLower(hash);
    }

    /// <summary>
    /// 生成 UUID
    /// </summary>
    /// <returns>UUID 字符串</returns>
    static string GenerateUuid()
    {
        return Guid.NewGuid().ToString();
    }
}
