using OF_DL.Services;

namespace OF_DL.Tests.Services;

public class FileNameServiceTests
{
    [Fact]
    public async Task GetFilename_ReturnsExpectedValues()
    {
        TestInfo info = new() { Id = 7, Text = "<div>hello <b>world</b></div>", CreatedAt = new DateTime(2024, 1, 2) };
        TestMedia media = new()
        {
            Id = 99,
            Files = new TestMediaFiles
            {
                Full = new TestMediaFull { Url = "https://cdn.test/file-name.jpg" }, Drm = new object()
            }
        };
        TestAuthor author = new() { Id = 123 };
        FileNameService service = new(new FakeAuthService());

        List<string> selectedProperties = ["mediaId", "filename", "username", "text", "createdAt", "id"];
        Dictionary<string, string> values =
            await service.GetFilename(info, media, author, selectedProperties, "creator");

        Assert.Equal("99", values["mediaId"]);
        Assert.Equal("file-name", values["filename"]);
        Assert.Equal("creator", values["username"]);
        Assert.Equal("hello world", values["text"]);
        Assert.Equal("2024-01-02", values["createdAt"]);
        Assert.Equal("7", values["id"]);
    }

    [Fact]
    public async Task GetFilename_TruncatesTextTo100Chars()
    {
        string longText = new('a', 120);
        TestInfo info = new() { Text = $"<p>{longText}</p>" };
        TestMedia media = new()
        {
            Id = 1,
            Files = new TestMediaFiles
            {
                Full = new TestMediaFull { Url = "https://cdn.test/short.jpg" }, Drm = null
            }
        };
        FileNameService service = new(new FakeAuthService());

        Dictionary<string, string> values =
            await service.GetFilename(info, media, new TestAuthor(), ["text"], "creator");

        Assert.Equal(100, values["text"].Length);
        Assert.Equal(new string('a', 100), values["text"]);
    }

    [Fact]
    public async Task GetFilename_UsesUserLookupWhenUsernameMissing()
    {
        TestAuthor author = new() { Id = 55 };
        Dictionary<string, long> users = new() { { "mapped", 55 } };
        FileNameService service = new(new FakeAuthService());

        Dictionary<string, string> values =
            await service.GetFilename(new TestInfo(), new TestMedia(), author, ["username"], "", users);

        Assert.Equal("mapped", values["username"]);
    }

    [Fact]
    public async Task BuildFilename_ReplacesTokensAndRemovesInvalidChars()
    {
        FileNameService service = new(new FakeAuthService());
        Dictionary<string, string> values = new() { { "username", "creator" }, { "mediaId", "99" } };

        string result = await service.BuildFilename("{username}_{mediaId}:*?", values);

        Assert.Equal("creator_99", result);
    }

    [Fact]
    public async Task GetFilename_UsesDrmFilenameWhenFullUrlMissing()
    {
        TestMedia media = new()
        {
            Id = 99,
            Files = new TestMediaFiles
            {
                Full = null,
                Drm = new { Manifest = new { Dash = "https://cdn.test/drm-name.mpd" } }
            }
        };
        FileNameService service = new(new FakeAuthService());

        Dictionary<string, string> values =
            await service.GetFilename(new TestInfo(), media, new TestAuthor(), ["filename"], "creator");

        Assert.Equal("drm-name_source", values["filename"]);
    }
}
