using System.Data.SQLite;
using FluentAssertions;

namespace OCES.Resonance.Core.Tests;

/// <summary>
/// Database 单元测试
/// </summary>
public class DatabaseTests : IDisposable
{
    readonly string _testDbName;
    readonly string _testDbPath;

    public DatabaseTests()
    {
        _testDbName = $"test_{Guid.NewGuid():N}";
        _testDbPath = $"{_testDbName}.db";
    }

    public void Dispose()
    {
        if (File.Exists(_testDbPath))
        {
            File.Delete(_testDbPath);
        }
    }

    [Fact]
    public void GetConnection_返回有效连接()
    {
        // Act
        using var connection = Database.GetConnection(_testDbName);

        // Assert
        connection.Should().NotBeNull();
        connection.Should().BeOfType<SQLiteConnection>();
    }

    [Fact]
    public void InitializeDatabase_创建表结构()
    {
        // Act
        Database.InitializeDatabase();

        // Assert - 验证表已创建（通过尝试查询）
        using var connection = Database.GetConnection();
        connection.Open();
        var command = connection.CreateCommand();
        command.CommandText = "SELECT COUNT(*) FROM audio_files;";
        var count = command.ExecuteScalar();
        count.Should().NotBeNull();
    }

    [Fact]
    public void AddEntry_添加有效记录_返回True()
    {
        // Arrange
        Database.InitializeDatabase();
        var meta = CreateTestMeta();

        // Act
        var result = Database.AddEntry(meta);

        // Assert
        result.Should().BeTrue();
    }

    [Fact]
    public void AddEntry_添加记录后_可以查询到()
    {
        // Arrange
        Database.InitializeDatabase();
        var meta = CreateTestMeta();

        // Act
        Database.AddEntry(meta);

        // Assert
        using var connection = Database.GetConnection();
        connection.Open();
        var command = connection.CreateCommand();
        command.CommandText = "SELECT filename FROM audio_files WHERE unique_id = @id;";
        var param = command.CreateParameter();
        param.ParameterName = "@id";
        param.Value = meta.UniqueId;
        command.Parameters.Add(param);
        var filename = command.ExecuteScalar() as string;
        filename.Should().Be(meta.Filename);
    }

    [Fact]
    public void AddEntries_批量添加_返回正确数量()
    {
        // Arrange
        Database.InitializeDatabase();
        var entries = new List<AudioFileMeta>
        {
            CreateTestMeta("file1.wav"),
            CreateTestMeta("file2.wav"),
            CreateTestMeta("file3.wav"),
        };

        // Act
        var count = Database.AddEntries(entries);

        // Assert
        count.Should().Be(3);
    }

    [Fact]
    public void EntryExists_记录存在_返回True()
    {
        // Arrange
        Database.InitializeDatabase();
        var meta = CreateTestMeta();
        Database.AddEntry(meta);

        // Act
        var exists = Database.EntryExists(meta.Md5, meta.Path);

        // Assert
        exists.Should().BeTrue();
    }

    [Fact]
    public void EntryExists_记录不存在_返回False()
    {
        // Arrange
        Database.InitializeDatabase();

        // Act
        var exists = Database.EntryExists("non_existent_md5", "/non/existent/path.wav");

        // Assert
        exists.Should().BeFalse();
    }

    [Fact]
    public void AddEntry_重复UniqueId_第二次添加失败()
    {
        // Arrange
        Database.InitializeDatabase();
        var meta1 = CreateTestMeta();
        var meta2 = CreateTestMeta();
        meta2.UniqueId = meta1.UniqueId; // 使用相同的 UniqueId
        Database.AddEntry(meta1);

        // Act
        var result = Database.AddEntry(meta2);

        // Assert
        result.Should().BeFalse();
    }

    static AudioFileMeta CreateTestMeta(string filename = "test.wav")
    {
        return new AudioFileMeta
        {
            Id = 0, // 自增 ID，由数据库生成
            UniqueId = Guid.NewGuid().ToString("N"),
            Md5 = Guid.NewGuid().ToString("N"),
            Path = $"/test/path/{filename}",
            Filename = filename,
            Folder = "test",
            Directory = "/test/path",
            Duration = 10.5,
            TotalSamples = 441000,
            BitDepth = 24,
            Channels = 2,
            SampleRate = 44100,
            Type = "WAV",
            DateAdded = DateTime.Now,
            OriginalModificationDate = DateTime.Now.AddDays(-1),
            OriginationTime = DateTime.Now.AddDays(-1),
        };
    }
}
