# retoor <retoor@molodetz.nl>

import time
import requests
from tests.conftest import BASE_URL
def _session_validation():
    s = requests.Session()
    name = f"val_{int(time.time() * 1000)}"
    s.post(
        f"{BASE_URL}/auth/signup",
        data={
            "username": name,
            "email": f"{name}@t.dev",
            "password": "secret123",
            "confirm_password": "secret123",
            "birth_date": "1990-01-01",
            "accept_terms": "1",
        },
        allow_redirects=True,
    )
    return s
from datetime import datetime, timezone
from devplacepy.database import get_table
from devplacepy.utils import generate_uid
_counter_votes = [0]
AJAX_votes = {"X-Requested-With": "fetch"}
def _session_votes():
    _counter_votes[0] += 1
    name = f"vot{int(time.time() * 1000)}{_counter_votes[0]}"
    s = requests.Session()
    s.post(
        f"{BASE_URL}/auth/signup",
        data={
            "username": name,
            "email": f"{name}@t.dev",
            "password": "secret123",
            "confirm_password": "secret123",
            "birth_date": "1990-01-01",
            "accept_terms": "1",
        },
        allow_redirects=True,
    )
    return s, name
def _uid_votes(username):
    return get_table("users").find_one(username=username)["uid"]
def _make_post_votes(owner_uid):
    uid = generate_uid()
    get_table("posts").insert(
        {
            "deleted_at": None,
            "deleted_by": None,
            "uid": uid,
            "user_uid": owner_uid,
            "slug": f"{uid[:8]}-vote-post",
            "title": None,
            "content": "vote target content",
            "topic": "random",
            "project_uid": None,
            "image": None,
            "stars": 0,
            "created_at": datetime.now(timezone.utc).isoformat(),
        }
    )
    return uid


def test_vote_bad_value_is_handled_not_500(app_server):
    s = _session_validation()
    r = s.post(
        f"{BASE_URL}/votes/post/nonexistent",
        data={"value": "abc"},
        allow_redirects=False,
    )
    assert r.status_code != 500
    assert r.status_code in (302, 303, 400)


def test_upvote_returns_ajax_payload(app_server):
    s_a, a_name = _session_votes()
    s_b, _ = _session_votes()
    post_uid = _make_post_votes(_uid_votes(a_name))
    r = s_b.post(f"{BASE_URL}/votes/post/{post_uid}", data={"value": "1"}, headers=AJAX_votes)
    assert r.json() == {"net": 1, "up": 1, "down": 0, "value": 1}


def test_repeated_vote_toggles_off(app_server):
    s_a, a_name = _session_votes()
    s_b, _ = _session_votes()
    post_uid = _make_post_votes(_uid_votes(a_name))
    s_b.post(f"{BASE_URL}/votes/post/{post_uid}", data={"value": "1"}, headers=AJAX_votes)
    r = s_b.post(f"{BASE_URL}/votes/post/{post_uid}", data={"value": "1"}, headers=AJAX_votes)
    assert r.json()["net"] == 0
    assert r.json()["value"] == 0


def test_switch_upvote_to_downvote(app_server):
    s_a, a_name = _session_votes()
    s_b, _ = _session_votes()
    post_uid = _make_post_votes(_uid_votes(a_name))
    s_b.post(f"{BASE_URL}/votes/post/{post_uid}", data={"value": "1"}, headers=AJAX_votes)
    r = s_b.post(
        f"{BASE_URL}/votes/post/{post_uid}", data={"value": "-1"}, headers=AJAX_votes
    )
    assert r.json()["net"] == -1
    assert r.json()["value"] == -1


def test_upvote_notifies_owner_and_awards_xp(app_server):
    s_a, a_name = _session_votes()
    s_b, _ = _session_votes()
    a_uid = _uid_votes(a_name)
    post_uid = _make_post_votes(a_uid)
    before = get_table("users").find_one(uid=a_uid).get("xp", 0) or 0
    s_b.post(f"{BASE_URL}/votes/post/{post_uid}", data={"value": "1"}, headers=AJAX_votes)
    assert get_table("notifications").count(user_uid=a_uid, type="vote") == 1
    after = get_table("users").find_one(uid=a_uid).get("xp", 0) or 0
    assert after - before == 5


def test_self_vote_does_not_notify(app_server):
    s_a, a_name = _session_votes()
    a_uid = _uid_votes(a_name)
    post_uid = _make_post_votes(a_uid)
    before = get_table("notifications").count(user_uid=a_uid, type="vote")
    s_a.post(f"{BASE_URL}/votes/post/{post_uid}", data={"value": "1"}, headers=AJAX_votes)
    after = get_table("notifications").count(user_uid=a_uid, type="vote")
    assert after == before


def test_non_ajax_vote_redirects_to_referer(app_server):
    s_a, a_name = _session_votes()
    s_b, _ = _session_votes()
    post_uid = _make_post_votes(_uid_votes(a_name))
    r = s_b.post(
        f"{BASE_URL}/votes/post/{post_uid}",
        data={"value": "1"},
        headers={"Referer": f"{BASE_URL}/gists"},
        allow_redirects=False,
    )
    assert r.status_code == 302
    assert r.headers["location"] == "/gists"
