from random import choice, shuffle

from playwright.sync_api import Playwright, sync_playwright, expect, Page
from playwright_stealth import stealth_sync
from logging import *
from re import findall, search
from actions.checks import check_logged_in


def play(page: Page):
    check_logged_in(page)
    quiz_type = detect_quiz_type(page)
    match quiz_type:
        case 8 | 9:
            info('Detected quiz_8.')
            play_quiz_8(page)
        case 5 | 4:
            info('Detected quiz_4.')
            play_quiz_4(page)
        case 3 | 2:
            info('Detected quiz_2.')
            play_quiz_2(page)
        case 1:
            info('Detected poll.')
            play_poll(page)
        case 0:
            info('Detected empty page.')


def detect_quiz_type(page: Page) -> int:
    info("Detecting quiz type.")
    if "bt_PollRadio" in page.content():
        return 1
    else:
        try:
            # RGPD
            selector = page.locator("#rqStartQuiz")
            expect(selector).to_be_visible(timeout=10_000)
            selector.click()
            return page.content().count("rqAnswerOption") - 1
        except AssertionError as e:

            if "rqQuestionState" in page.content():
                # The quiz is already started
                warning("Detected via recovery mode.")
                return page.content().count("rqAnswerOption") - 1
            return 0


def play_quiz_8(page: Page):
    info("Playing quiz 8.")
    num_question = len(findall("<span id=\"rqQuestionState.\" class=\"emptyCircle\"></span>", page.content())) + 1
    info(f"Looping on {num_question} questions.")

    counter = 0
    # rgpd_popup(driver)
    for _ in range(num_question):
        correct_answers = []
        for i in range(1, 9):

            element = page.locator(f'#rqAnswerOption{i - 1}')
            # todo can probably be optimised using filter and has_text
            if 'iscorrectoption="True"' in element.evaluate("el => el.outerHTML"):
                correct_answers.append(f'#rqAnswerOption{i - 1}')
        shuffle(correct_answers)

        for answer_id in correct_answers:
            page.locator(answer_id).click()
            page.wait_for_timeout(1000)
        page.wait_for_timeout(3000)  # todo check if there is a better method than hardcoded timout
    page.wait_for_timeout(3000)  # todo check if there is a better method than hardcoded timout


def play_quiz_4(page: Page):
    info("Playing quiz 4.")
    num_question = len(findall("<span id=\"rqQuestionState.\" class=\"emptyCircle\"></span>", page.content())) + 1
    info(f"Looping on {num_question} questions.")

    for i in range(num_question):
        txt = page.content()
        answer_option = search('correctAnswer":"([^"]+)', txt)[1]
        answer_option = answer_option.replace("\\u0027", "'")  # replace Unicode weird symbols
        page.locator(f'css=[data-option="{answer_option}"]').click()
        info(f'Validated answer n°{i + 1}.')
        page.wait_for_load_state('load')
        debug(f'Next page loaded.')
    info("Quiz 4 successful.")


def play_quiz_2(page: Page):
    info("Playing quiz 2.")
    for j in range(10):  # todo de-hardcode the value
        js_function = """
        function get_correct_answer(){
            function br(n) { for (var r, t = 0, i = 0; i < n.length; i++)t += n.charCodeAt(i); return r = parseInt(_G.IG.substr(_G.IG.length - 2), 16), t += r, t.toString() } // Ms check function
            function namedRAValue() { //allow calls to getRAvalue
                return _w.getRAValue()
            }; 
            if (br(document.getElementById("rqAnswerOption0").attributes["data-option"].value) == namedRAValue()){
                return(0);
            }
            else {
                return(1);
            }
        };
        return(get_correct_answer())
        """
        correct_answer_value = page.evaluate(js_function)
        page.locator(f"#rqAnswerOption{correct_answer_value}").click()
        page.wait_for_timeout(2000)
    info("Quiz 2 successful.")
    page.wait_for_timeout(3000)  # todo check if there is a better method than hardcoded timout


def play_poll(page: Page):
    info("Playing poll.")
    answer_elem = page.locator(f"#btoption{choice([0, 1])}")
    answer_elem.click()
    info("Poll successful.")
    page.wait_for_timeout(3000)  # todo check if there is a better method than hardcoded timout