using System.Security.Cryptography;
using ATL;

namespace OCES.Resonance.Core;

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

        var track = new Track(filePath);
        var fileInfo = new FileInfo(filePath);

        // 获取音频技术参数
        var durationSeconds = track.DurationMs / 1000.0;
        var sampleRate = track.SampleRate;
        var channels = track.ChannelsArrangement?.NbChannels ?? 2;
        var bitDepth = GetBitDepth(track);
        var totalSamples = (uint)(durationSeconds * sampleRate);

        // 提取路径信息
        var fileName = Path.GetFileName(filePath);
        var folder = Path.GetDirectoryName(filePath) ?? string.Empty;
        var directory = Path.GetDirectoryName(filePath) ?? string.Empty;
        var folderName = new DirectoryInfo(folder).Name;

        // 生成唯一标识
        var md5 = CalculateMd5(filePath);
        var uniqueId = GenerateUuid();

        // 获取文件修改时间
        var lastWriteTime = fileInfo.LastWriteTime;
        var createTime = fileInfo.CreationTime;

        // 获取文件扩展名作为类型
        var fileType = Path.GetExtension(filePath).TrimStart('.').ToUpperInvariant();

        // 映射 ATL 元数据到 AudioFileMeta
        var meta = new AudioFileMeta
        {
            // 必备条目
            Id = 0, // 自增 ID，由数据库生成
            UniqueId = uniqueId,
            Md5 = md5,
            Path = Path.GetFullPath(filePath),
            Filename = fileName,
            Folder = folderName,
            Directory = directory,
            Duration = durationSeconds,
            TotalSamples = totalSamples,
            BitDepth = bitDepth,
            Channels = channels,
            SampleRate = (int)sampleRate,
            Type = fileType,
            DateAdded = DateTime.Now,
            OriginalModificationDate = lastWriteTime,
            OriginationTime = createTime,

            // 可选条目
            Bpm = track.BPM > 0 ? track.BPM : null,
            Description = track.Description,
            Genre = track.Genre,
            Artist = track.Artist,
            Composer = track.Composer,
            Publisher = track.Publisher,
            Copyright = track.Copyright,
            
            // BWF 特定字段 (通过附加数据获取)
            CodingHistory = GetBwfField(track, "CodingHistory"),
            Originator = GetBwfField(track, "Originator"),
            OriginatorRef = GetBwfField(track, "OriginatorRef"),
        };

        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>
    /// 获取自定义字段值
    /// </summary>
    private static string? GetCustomField(Track track, int index)
    {
        try
        {
            string fieldName = $"User{index}";
            if (track.AdditionalFields != null && track.AdditionalFields.TryGetValue(fieldName, out string? field))
            {
                return field;
            }
        }
        catch
        {
            // 忽略自定义字段读取错误
        }
        return null;
    }

    /// <summary>
    /// 获取音频位深度
    /// </summary>
    private static int GetBitDepth(Track track)
    {
        // ATL 可能通过不同方式提供位深信息
        if (track.BitDepth > 0)
        {
            return track.BitDepth;
        }

        // 根据格式推断默认位深
        var extension = Path.GetExtension(track.Path).ToLowerInvariant();
        return extension switch
        {
            ".wav" or ".bwf" or ".wav64" => 24, // 现代 WAV 通常 24bit
            ".flac" => 24,
            ".aiff" or ".aif" => 16,
            ".mp3" => 16, // MP3 实际没有位深概念，默认 16
            _ => 16
        };
    }

    /// <summary>
    /// 计算文件 MD5 值
    /// </summary>
    /// <param name="filePath">文件路径</param>
    /// <returns>MD5 哈希值（十六进制字符串）</returns>
    private static string CalculateMd5(string filePath)
    {
        using var md5 = MD5.Create();
        using var stream = File.OpenRead(filePath);
        
        var hash = md5.ComputeHash(stream);
        return BitConverter.ToString(hash).Replace("-", "").ToLowerInvariant();
    }

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