from playwright.sync_api import sync_playwright
import urllib.parse
import requests
import random
import string
import hashlib
import base64
from dotenv import load_dotenv
import os


def using_refresh_token(refresh_token):
    url = "http://inloggen.somtoday.nl//oauth2/token"
    data = {
        "grant_type": "refresh_token",
        "client_id": "somtoday-leerling-web",
        "scope": "openid"
    }
    data["refresh_token"] = refresh_token


    r = requests.post(url=url, data=data)
     
    try:
        return r.json()
    except requests.JSONDecodeError as E:
        return {"refresh_token": "ABCDEFGHIJKLMOPQRSTUVWXYZ1234567890",
                "access_token": "ABCDEFGHIJKLMOPQRSTUVWXYZ1234567890",
                "somtoday_api_url": "https://api.somtoday.nl",
                "somtoday_oop_url": "https://oop.somtoday.nl",
                "scope": "openid",
                "somtoday_organisatie_afkorting": "ORGANISATION",
                "id_token": "ABCDEFGHIJKLMOPQRSTUVWXYZ1234567890"}
        
def using_uname_pword(username, password, tenant_uuid, *args, **kwargs):
    """Login with username and password

    Args:
        username (string_): Your username.
        password (string): Your password.
        tenant_uuid (string): The schools id.
        
        (Optional) email (string): Your email.


    Returns:
        json: The tokens, in the following way \n {
            "access_token": "<TOKEN HERE>"
            "refresh_token": "<TOKEN HERE>"
        }
    """
        
    CLIENT_ID = "somtoday-leerling-native"
    REDIRECT_URI = "somtoday://nl.topicus.somtoday.leerling/oauth/callback"
    
    email = kwargs.get("email", None)
    
    def generate_tokens():
        code_verifier = generate_nonce()
        code_challenge = generate_code_challenge(code_verifier)
        return code_verifier, code_challenge

    def generate_nonce():
        chars = "abcdefghijklmnopqrstuvwxyz123456789"
        return ''.join(random.choice(chars) for _ in range(128))

    def generate_code_challenge(code_verifier):
        sha256_hash = hashlib.sha256(code_verifier.encode('utf-8')).digest()
        return base64.urlsafe_b64encode(sha256_hash).decode('utf-8').rstrip("=")

    CODE_VERIFIER, CODE_CHALLENGE = generate_tokens()

    def build_auth_url(state):
        return (
            "https://inloggen.somtoday.nl/oauth2/authorize?"
            f"redirect_uri={urllib.parse.quote(REDIRECT_URI)}"
            f"&client_id={CLIENT_ID}"
            f"&response_type=code"
            f"&state={state}"
            f"&scope=openid"
            f"&tenant_uuid={tenant_uuid}"
            f"&session=no_session"
            f"&code_challenge={CODE_CHALLENGE}"
            f"&code_challenge_method=S256"
        )

    with sync_playwright() as p:
        browser = p.chromium.launch(headless=True)
        context = browser.new_context()
        page = context.new_page()

        final_url_holder = {}

        def handle_request(request):
            if "callback" in request.url:
                final_url_holder["url"] = request.url

        page.on("request", handle_request)

        page.goto(build_auth_url("random123"))

        page.wait_for_selector("input[name*='usernameField']", state="visible")
        page.fill("input[name*='usernameField']", username)
        page.keyboard.press("Enter")


        page.wait_for_selector("input[type='email'], input[type='password']")

        if page.locator("input[type='email']").is_visible():
            page.fill("input[type='email']", email)
            page.keyboard.press("Enter")

        page.wait_for_selector("input[type='password']")
        page.fill("input[type='password']", password)
        page.keyboard.press("Enter")

        try:
            page.wait_for_selector("text=Stay signed in", timeout=5000)
            page.locator("input[value='No'], button:has-text('No')").click()
        except:
            pass

        page.wait_for_timeout(100)
        browser.close()


    final_url = final_url_holder.get("url")
    if not final_url:
        raise Exception("where did you gooooo....")

    parsed = urllib.parse.urlparse(final_url)
    code = urllib.parse.parse_qs(parsed.query)["code"][0]


    token_response = requests.post(
        "https://inloggen.somtoday.nl/oauth2/token",
        data={
            "grant_type": "authorization_code",
            "client_id": CLIENT_ID,
            "redirect_uri": REDIRECT_URI,
            "code": code,
            "code_verifier": CODE_VERIFIER,
            "tenant_uuid": tenant_uuid,
        },
    )

    tokens = token_response.json()
    # return {"access_token": tokens.get("access_token"), "refresh_token": tokens.get("refresh_token")}
    return tokens