# retoor <retoor@molodetz.nl>

import json
import time

import requests

from tests.conftest import BASE_URL

JSON = {"Accept": "application/json"}

_counter = [0]

CHOICE = {
    "kind": "single_choice",
    "prompt": "Which journal mode allows concurrent readers?",
    "points": 2,
    "options": "DELETE\nWAL\nMEMORY",
    "correct_indexes": "1",
}

NUMERIC = {
    "kind": "numeric",
    "prompt": "How many bytes are in a kibibyte?",
    "points": 1,
    "numeric_value": "1024",
    "numeric_tolerance": "0",
}

TRUE_FALSE = {
    "kind": "true_false",
    "prompt": "A partial index can carry a WHERE clause.",
    "points": 1,
    "correct_boolean": "1",
}

FREE_TEXT = {
    "kind": "free_text",
    "prompt": "Why does a partial index help here?",
    "points": 3,
    "expected_answer": "It keeps the live query off a one bucket index.",
    "grading_criteria": "Accept any answer that mentions the planner.",
}

DOCUMENT = {
    "title": "Imported quiz",
    "description": "Created from a document.",
    "settings": {"reveal_answers": True, "pass_percent": 60, "allow_review": True},
    "questions": [
        {
            "kind": "single_choice",
            "prompt": "Which journal mode allows concurrent readers?",
            "points": 2,
            "options": [{"label": "DELETE"}, {"label": "WAL", "is_correct": True}],
        },
        {
            "kind": "numeric",
            "prompt": "How many bytes are in a kibibyte?",
            "points": 1,
            "numeric_value": 1024,
        },
    ],
}


def signup(prefix="qz"):
    _counter[0] += 1
    name = f"{prefix}{int(time.time() * 1000)}{_counter[0]}"
    session = requests.Session()
    session.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 session, name


def create_quiz(session, title="Test quiz", **settings):
    payload = {"title": title, "description": "A quiz."}
    payload.update(settings)
    response = session.post(f"{BASE_URL}/quizzes/create", data=payload, headers=JSON)
    return response.json()["data"]["slug"]


def add_question(session, slug, payload):
    return session.post(f"{BASE_URL}/quizzes/{slug}/questions", data=payload, headers=JSON)


def publish(session, slug):
    return session.post(f"{BASE_URL}/quizzes/{slug}/publish", headers=JSON)


def build_published(session, questions=(CHOICE, NUMERIC), title="Playable quiz", **settings):
    slug = create_quiz(session, title, **settings)
    for question in questions:
        add_question(session, slug, question)
    publish(session, slug)
    return slug


def import_quiz(session, document=None):
    payload = {"document": json.dumps(document or DOCUMENT)}
    response = session.post(f"{BASE_URL}/quizzes/import", data=payload, headers=JSON)
    return response


def start_attempt(session, slug):
    response = session.post(f"{BASE_URL}/quizzes/{slug}/attempts", headers=JSON)
    return response.json()["data"]["uid"]


def attempt_state(session, slug, attempt_uid):
    return session.get(
        f"{BASE_URL}/quizzes/{slug}/attempts/{attempt_uid}", headers=JSON
    ).json()


def answer_correctly(session, slug, attempt_uid, question):
    payload = {"question_uid": question["uid"]}
    if question["kind"] == "single_choice":
        correct = next(
            (option["uid"] for option in question["options"] if option.get("is_correct")), None
        )
        payload["option_uids"] = correct or question["options"][1]["uid"]
    elif question["kind"] == "numeric":
        payload["answer_text"] = "1024"
    elif question["kind"] == "true_false":
        payload["answer_text"] = "true"
    else:
        payload["answer_text"] = "the planner picks a bad index for live rows"
    return session.post(
        f"{BASE_URL}/quizzes/{slug}/attempts/{attempt_uid}/answer", data=payload, headers=JSON
    )
