# retoor <retoor@molodetz.nl>

import time
from datetime import datetime, timedelta, timezone
import requests
from tests.conftest import BASE_URL
from devplacepy.database import (
    get_table,
    get_activity_calendar,
    get_streaks,
    get_activity_heatmap,
    get_activity_months,
)
from devplacepy.utils import generate_uid, check_milestone_badges
_counter_streaks = [0]
def _make_user_streaks():
    _counter_streaks[0] += 1
    uid = generate_uid()
    name = f"stk{int(time.time() * 1000)}{_counter_streaks[0]}"
    get_table("users").insert(
        {
            "uid": uid,
            "username": name,
            "terms_version": "1",
            "email": f"{name}@t.dev",
            "role": "Member",
            "is_active": True,
            "xp": 0,
            "level": 1,
            "created_at": datetime.now(timezone.utc).isoformat(),
        }
    )
    return uid
def _insert_post(user_uid, dt):
    uid = generate_uid()
    get_table("posts").insert(
        {
            "deleted_at": None,
            "deleted_by": None,
            "uid": uid,
            "user_uid": user_uid,
            "slug": f"{uid[:8]}-streak",
            "title": None,
            "content": "streak activity",
            "topic": "random",
            "project_uid": None,
            "image": None,
            "stars": 0,
            "created_at": dt.isoformat(),
        }
    )
    return uid
def _insert_comment(user_uid, post_uid, dt):
    uid = generate_uid()
    get_table("comments").insert(
        {
            "deleted_at": None,
            "deleted_by": None,
            "uid": uid,
            "target_type": "post",
            "target_uid": post_uid,
            "post_uid": post_uid,
            "user_uid": user_uid,
            "content": "streak comment",
            "parent_uid": None,
            "created_at": dt.isoformat(),
        }
    )
    return uid


def test_consecutive_days_build_streak(app_server):
    uid = _make_user_streaks()
    today = datetime.now(timezone.utc)
    for offset in (0, 1, 2):
        _insert_post(uid, today - timedelta(days=offset))
    streaks = get_streaks(uid)
    assert streaks["current"] == 3
    assert streaks["longest"] >= 3


def test_gap_resets_current_streak(app_server):
    uid = _make_user_streaks()
    today = datetime.now(timezone.utc)
    _insert_post(uid, today)
    _insert_post(uid, today - timedelta(days=3))
    streaks = get_streaks(uid)
    assert streaks["current"] == 1


def test_yesterday_only_counts_as_current(app_server):
    uid = _make_user_streaks()
    yesterday = datetime.now(timezone.utc) - timedelta(days=1)
    _insert_post(uid, yesterday)
    assert get_streaks(uid)["current"] == 1


def test_calendar_sums_across_sources(app_server):
    uid = _make_user_streaks()
    today = datetime.now(timezone.utc)
    post_uid = _insert_post(uid, today)
    _insert_comment(uid, post_uid, today)
    calendar = get_activity_calendar(uid)
    assert calendar.get(today.date().isoformat()) == 2


def test_heatmap_shape(app_server):
    uid = _make_user_streaks()
    weeks = get_activity_heatmap(uid)
    assert len(weeks) == 53
    assert all(len(week) == 7 for week in weeks)


def test_heatmap_anchors_at_first_contribution(app_server):
    uid = _make_user_streaks()
    first = datetime.now(timezone.utc) - timedelta(days=30)
    _insert_post(uid, first)
    weeks = get_activity_heatmap(uid)
    expected = (first.date() - timedelta(days=first.date().weekday())).isoformat()
    assert weeks[0][0]["date"] == expected
    assert len(weeks) == 53


def test_activity_months_returns_six_labels(app_server):
    uid = _make_user_streaks()
    months = get_activity_months(get_activity_heatmap(uid))
    assert len(months) == 6
    assert all(len(label) == 3 for label in months)


def test_seven_day_streak_awards_on_fire_badge(app_server):
    uid = _make_user_streaks()
    today = datetime.now(timezone.utc)
    for offset in range(7):
        _insert_post(uid, today - timedelta(days=offset))
    check_milestone_badges(uid)
    assert get_table("badges").count(user_uid=uid, badge_name="On Fire") == 1
