# retoor <retoor@molodetz.nl>

from datetime import datetime, timezone
from devplacepy.database import (
    get_table,
    get_users_by_uids,
    get_vote_counts,
    get_user_votes,
    get_comment_counts_by_post_uids,
    resolve_by_slug,
    get_user_stars,
    get_user_rank,
    build_pagination,
)
from devplacepy.utils import generate_uid
def _now_db_helpers():
    return datetime.now(timezone.utc).isoformat()
def _user_db_helpers():
    uid = generate_uid()
    get_table("users").insert(
        {
            "uid": uid,
            "username": f"dbh_{uid[:8]}",
            "email": f"{uid[:8]}@t.dev",
            "created_at": _now_db_helpers(),
        }
    )
    return uid
def _post(owner, **extra):
    uid = generate_uid()
    get_table("posts").insert(
        {
            "uid": uid,
            "user_uid": owner,
            "slug": f"{uid[:8]}-post",
            "title": None,
            "content": "db helper post body",
            "topic": "random",
            "project_uid": None,
            "image": None,
            "stars": 0,
            "created_at": _now_db_helpers(),
            "deleted_at": None,
            "deleted_by": None,
            **extra,
        }
    )
    return uid
def _comment(owner, target_uid):
    uid = generate_uid()
    get_table("comments").insert(
        {
            "uid": uid,
            "user_uid": owner,
            "target_uid": target_uid,
            "target_type": "post",
            "content": "db helper comment",
            "created_at": _now_db_helpers(),
            "deleted_at": None,
            "deleted_by": None,
        }
    )
    return uid
def _vote(target_type, target_uid, value):
    get_table("votes").insert(
        {
            "uid": generate_uid(),
            "user_uid": generate_uid(),
            "target_uid": target_uid,
            "target_type": target_type,
            "value": value,
            "created_at": _now_db_helpers(),
            "deleted_at": None,
            "deleted_by": None,
        }
    )
from uuid import uuid4
from tests.conftest import BASE_URL
from devplacepy.database import get_table


def test_get_users_by_uids_dedupes(local_db):
    a, b = generate_uid(), generate_uid()
    users = get_table("users")
    users.insert({"uid": a, "username": f"u_{a[:6]}", "created_at": _now_db_helpers()})
    users.insert({"uid": b, "username": f"u_{b[:6]}", "created_at": _now_db_helpers()})
    result = get_users_by_uids([a, b, a])
    assert set(result.keys()) == {a, b}


def test_get_vote_counts_groups_up_and_down(local_db):
    target = generate_uid()
    votes = get_table("votes")
    for value in (1, 1, -1):
        votes.insert(
            {
                "uid": generate_uid(),
                "user_uid": generate_uid(),
                "target_uid": target,
                "target_type": "post",
                "value": value,
                "created_at": _now_db_helpers(),
                "deleted_at": None,
                "deleted_by": None,
            }
        )
    ups, downs = get_vote_counts([target])
    assert ups[target] == 2
    assert downs[target] == 1


def test_get_user_votes_returns_user_value(local_db):
    target = generate_uid()
    user = generate_uid()
    get_table("votes").insert(
        {
            "uid": generate_uid(),
            "user_uid": user,
            "target_uid": target,
            "target_type": "post",
            "value": 1,
            "created_at": _now_db_helpers(),
            "deleted_at": None,
            "deleted_by": None,
        }
    )
    assert get_user_votes(user, [target]) == {target: 1}


def test_get_comment_counts_by_post_uids(local_db):
    post = generate_uid()
    comments = get_table("comments")
    for _ in range(2):
        comments.insert(
            {
                "uid": generate_uid(),
                "user_uid": generate_uid(),
                "target_type": "post",
                "target_uid": post,
                "content": "hi",
                "created_at": _now_db_helpers(),
                "deleted_at": None,
                "deleted_by": None,
            }
        )
    assert get_comment_counts_by_post_uids([post]) == {post: 2}


def test_resolve_by_slug_finds_by_slug_or_uid(local_db):
    owner = _user_db_helpers()
    uid = _post(owner)
    posts = get_table("posts")
    slug = posts.find_one(uid=uid)["slug"]
    assert resolve_by_slug(posts, slug)["uid"] == uid
    assert resolve_by_slug(posts, uid)["uid"] == uid
    assert resolve_by_slug(posts, "missing-slug-xyz") is None


def test_get_user_stars_counts_all_votable_contributions(local_db):
    user = _user_db_helpers()
    post_uid = _post(user)
    for _ in range(7):
        _vote("post", post_uid, 1)
    comment_uid = _comment(user, post_uid)
    _vote("comment", comment_uid, 1)
    _vote("comment", comment_uid, 1)
    _vote("comment", comment_uid, -1)
    assert get_user_stars(user) == 8


def test_get_user_rank_unknown_user_is_none(local_db):
    assert get_user_rank(generate_uid()) is None


def test_build_pagination_metadata():
    first = build_pagination(1, 100, 25)
    assert first["total_pages"] == 4
    assert first["has_prev"] is False
    assert first["has_next"] is True
    middle = build_pagination(2, 100, 25)
    assert middle["has_prev"] is True
    assert middle["has_next"] is True
    clamped = build_pagination(99, 10, 25)
    assert clamped["page"] == 1
    assert clamped["total_pages"] == 1


def test_interleave_by_author_spreads_consecutive_runs():
    from devplacepy.database import interleave_by_author

    rows = [
        {"uid": 1, "user_uid": "a"},
        {"uid": 2, "user_uid": "a"},
        {"uid": 3, "user_uid": "a"},
        {"uid": 4, "user_uid": "b"},
        {"uid": 5, "user_uid": "b"},
        {"uid": 6, "user_uid": "c"},
    ]
    spread = interleave_by_author(rows)
    authors = [r["user_uid"] for r in spread]
    assert len(spread) == len(rows)
    assert all(authors[i] != authors[i + 1] for i in range(len(authors) - 1))


def test_interleave_by_author_preserves_per_author_order():
    from devplacepy.database import interleave_by_author

    rows = [
        {"uid": 1, "user_uid": "a"},
        {"uid": 2, "user_uid": "a"},
        {"uid": 3, "user_uid": "a"},
        {"uid": 4, "user_uid": "b"},
    ]
    spread = interleave_by_author(rows)
    a_order = [r["uid"] for r in spread if r["user_uid"] == "a"]
    assert a_order == [1, 2, 3]


def test_interleave_by_author_single_author_keeps_order():
    from devplacepy.database import interleave_by_author

    rows = [{"uid": i, "user_uid": "a"} for i in range(4)]
    spread = interleave_by_author(rows)
    assert [r["uid"] for r in spread] == [0, 1, 2, 3]
