from pathlib import Path

from mjr_am_backend.features.browser import list_filesystem_browser_entries, list_visible_subfolders


def test_list_visible_subfolders_filters_dot_hidden(tmp_path: Path) -> None:
    root = tmp_path / "root"
    root.mkdir()
    (root / "visible_a").mkdir()
    (root / ".hidden_a").mkdir()

    res = list_visible_subfolders(root, "", "rid-1")
    assert res.ok
    items = res.data or []
    names = {str(i.get("filename")) for i in items}
    assert "visible_a" in names
    assert ".hidden_a" not in names
    assert all(str(i.get("kind")) == "folder" for i in items)


def test_list_visible_subfolders_rejects_traversal(tmp_path: Path) -> None:
    root = tmp_path / "root"
    root.mkdir()
    outside = tmp_path / "outside"
    outside.mkdir()

    res = list_visible_subfolders(root, "../outside", "rid-1")
    assert not res.ok
    assert res.code == "INVALID_INPUT"


def test_browser_entries_roots_mode_ok() -> None:
    res = list_filesystem_browser_entries("", "*", 100, 0)
    assert res.ok
    data = res.data or {}
    assert isinstance(data.get("assets"), list)


def test_browser_entries_deep_nested_directory(tmp_path: Path) -> None:
    deep_dir = tmp_path / "a" / "b" / "c" / "d"
    deep_dir.mkdir(parents=True)
    media = deep_dir / "image.png"
    media.write_bytes(b"\x89PNG\r\n\x1a\n")

    root_res = list_filesystem_browser_entries(str(tmp_path), "*", 200, 0)
    assert root_res.ok
    root_assets = (root_res.data.get("assets") or []) if isinstance(root_res.data, dict) else []
    assert any(str(item.get("filename")) == "a" and str(item.get("kind")) == "folder" for item in root_assets)

    level2_res = list_filesystem_browser_entries(str(tmp_path / "a" / "b"), "*", 200, 0)
    assert level2_res.ok
    level2_assets = (level2_res.data.get("assets") or []) if isinstance(level2_res.data, dict) else []
    assert any(str(item.get("filename")) == "c" and str(item.get("kind")) == "folder" for item in level2_assets)

    level4_res = list_filesystem_browser_entries(str(deep_dir), "*", 200, 0)
    assert level4_res.ok
    level4_assets = (level4_res.data.get("assets") or []) if isinstance(level4_res.data, dict) else []
    assert any(str(item.get("filename")) == "image.png" for item in level4_assets)


def test_browser_entries_size_filters_apply_in_browser_mode(tmp_path: Path) -> None:
    small = tmp_path / "small.png"
    big = tmp_path / "big.png"
    small.write_bytes(b"\x89PNG\r\n\x1a\n" + b"a" * 8)
    big.write_bytes(b"\x89PNG\r\n\x1a\n" + b"b" * 4096)

    res = list_filesystem_browser_entries(
        str(tmp_path),
        "*",
        200,
        0,
        min_size_bytes=1024,
    )
    assert res.ok
    assets = (res.data.get("assets") or []) if isinstance(res.data, dict) else []
    names = {str(item.get("filename")) for item in assets if str(item.get("kind")) != "folder"}
    assert "big.png" in names
    assert "small.png" not in names


def test_browser_entries_size_max_lt_min_is_normalized(tmp_path: Path) -> None:
    f = tmp_path / "x.png"
    f.write_bytes(b"\x89PNG\r\n\x1a\n" + b"x" * 2048)
    res = list_filesystem_browser_entries(
        str(tmp_path),
        "*",
        200,
        0,
        min_size_bytes=1024,
        max_size_bytes=10,
    )
    assert res.ok


def test_browser_entries_dimension_filters_exclude_unknown_dimensions(tmp_path: Path) -> None:
    f = tmp_path / "x.png"
    f.write_bytes(b"\x89PNG\r\n\x1a\n" + b"x" * 128)

    res = list_filesystem_browser_entries(
        str(tmp_path),
        "*",
        200,
        0,
        min_width=1,
    )
    assert res.ok
    assets = (res.data.get("assets") or []) if isinstance(res.data, dict) else []
    file_names = {str(item.get("filename")) for item in assets if str(item.get("kind")) != "folder"}
    assert "x.png" not in file_names
