import js
import source.picture as pic
import asyncio
from pyodide.ffi import create_proxy, create_once_callable
from source.config import config
api_domain = config.api_domain

height, width= 400, 600

img = js.document.getElementById("targetPic")
img_list: list[str] = None
leaderboard_site: int = 0
leaderboard_max: int = 10
leaderboard_data: list[tuple[int, float, str]] = None
username:str = ""
run: int = 0 #current run

#login overlay
async def loginOverlay():
    overlay = js.document.getElementById("startOverlay")
    overlay.style.display = "flex"
    usernameInput = js.document.getElementById("usernameInput")
    submitButton = js.document.getElementById("submitUsername")
    js.document.getElementById("codeInput").value = str(hash(js.Math.random()))[2:10:]  # Generate a random 6-digit code
    
    def on_submit(event):
        event.preventDefault()  # Prevent the default form submission behavior
        username = usernameInput.value
        if username:
            asyncio.ensure_future(fetchCookie(username))
              # Hide the overlay after login
        else:
            print("Please enter a username.")
        overlay.style.display = "none"
        asyncio.ensure_future(get_gamesImg(5))
    
    def guest_login(event):
        event.preventDefault()  # Prevent the default form submission behavior
        if js.document.cookie:
            js.document.cookie = f"{str(js.document.cookie)}; expires=Thu, 01 Jan 1970 00:00:00 UTC"  # Clear existing cookies
        overlay.style.display = "none"  # Hide the overlay after login
        asyncio.ensure_future(get_gamesImg(5))
            
    submit_proxy = create_proxy(on_submit)
    submitButton.addEventListener("click", submit_proxy)
    guest_proxy = create_proxy(guest_login)
    
    js.document.getElementById("guestButton").addEventListener("click", guest_proxy)
    

#get cookies from server as string
async def fetchCookie(username: str):
    try:
        opts = js.eval("""({
            method: "POST",
            headers: { "Content-Type": "application/json" },
            body: JSON.stringify({ username: "%s" })
        })""" %username)

        resp = await js.fetch("%s/cookie" % api_domain, opts)
        if not resp.ok:
            print("Cookie fetch HTTP error:", resp.status)
            js.document.getElementById("usernameOverlay").style.display = "flex"
            js.document.getElementById("textUsernameOverlay").innerText = "Username exist already, try another name." 
            return
        print(resp)
        text = await resp.json()
        print("Cookie fetch response:", text.username)
        js.document.cookie = f"{text.username}={text.id}; expires=expires=Fri, 31 Dec 9999 23:59:59 GMT" # Manually set the cookie
        print("Document cookies:", js.document.cookie)
    except Exception as e:
        print("Cookie fetch error:", e)

#get the image from the server
async def get_image(image_url: str) -> str:
    global img
    response = await js.fetch(image_url)
    
    if not response.ok:
        raise Exception(f"HTTP error: {response.status}")
    blob = await response.blob()

    print(response.url)
    
    #imageUrl = js.URL.createObjectURL(blob)
    #print('imageurl: ' + imageUrl)
    
    #img.src = response.url
    
    if img.src == '':
        img.src = response.url
        print(": ",img.height, img.width)

    #img.style.width  = f"{img.naturalWidth }px"
    #img.style.height = f"{img.naturalHeight}px"
    
    img.style.backgroundImage = f'url("{response.url}")'

def update_scoreboard() -> None:
    tabel = js.document.getElementById("scoreboard")
    #clear old entries
    while tabel.rows.length > 1:
        tabel.deleteRow(1)
    #update scoreboard
    for i, row in enumerate(leaderboard_data):
        if not (i >= leaderboard_site * leaderboard_max):
            continue
        if not (i <(leaderboard_site + 1) * leaderboard_max):
            break
        newRow = tabel.insertRow(-1)# append new row to scoreboard at the end
        newRow.insertCell(0).appendChild(js.document.createTextNode(i+1))#position
        newRow.insertCell(1).appendChild(js.document.createTextNode(row[2]))#username
        newRow.insertCell(2).appendChild(js.document.createTextNode(row[1]))#score

async def transmit_guess(location: list, image: str):
    
    global username
    id = ''
    if js.document.cookie:
        username = js.document.cookie.split('=')[0]
        id = js.document.cookie.split('=')[1]
    else:
        print("No cookie found")
        username = "guest"
        id = "guest"
    #print(username, id, location, image)
    try:
        opts = js.eval("""({
            method: "POST",
            headers: { "Content-Type": "application/json" },
            body: JSON.stringify({ username: "%s", id: "%s", location: %s, image: "%s"})
        })""" %(username, id ,location, image)) 
        
        resp = await js.fetch("%s/guess" % api_domain, opts)
        if not resp.ok:
            print("Cookie fetch HTTP error:", resp.status)
            
            return
        print(resp)
        
        """
        get: score, Scoreboard, place, Text of picture's location 
        """
        
        data = await resp.json()
        

        #js.document.getElementById("pictureLocation")
        
        #print("Cookie fetch response:", text.username)
        
    except Exception as e:
        print("Cookie fetch error:", e)
    
    #update result container
    js.document.getElementById("discriptionText").innerText = data.text # text of picture's location
    js.document.getElementById("positionScoreboard").innerText = ""# Scoreboard position
    js.document.getElementById("yourScore").innerText = data.score# personal score
    
    global leaderboard_data
    leaderboard_data = data.leaderboard
    for i, row in enumerate(leaderboard_data):
        if row[2] == username and js.document.cookie and row[1] == data.score:
            js.document.getElementById("positionScoreboard").innerText = f"{i + 1}"# Scoreboard position
            break
    update_scoreboard()
    
    js.markerGoal = js.L.marker(js.L.latLng(data.real_location[0], data.real_location[1])).addTo(js.map) 
    try:
        js.addPathLine([js.marker.getLatLng(), js.markerGoal.getLatLng()], f"{data.distance:.4f} km" if data.distance > 1 else (f"{data.distance:.3f}".split(".")[1] + " m"))
        #pathline = js.L.polyline().addTo(js.map)
        #pathline.setText(" Radweg  ", {"repeat": False, "offset": 10, "center": True})
        #pathline.bindTooltip("%s.4f" %data.distance, {"permanent": True, "direction": "center" })
    except Exception as e:
        print(f"Error adding polyline: {e}")

#asyncio.ensure_future(transmit_guess([1,1], "test"))

# Add event listener to the button for getting the guess position
def make_guess(event):  # Accept the event parameter
    try:
        print(js.marker.getLatLng())
        js.map.off('click')  # Disable further map clicks
        latLng = js.marker.getLatLng()
        asyncio.ensure_future(transmit_guess([latLng.lat, latLng.lng], img_list[run].split('.')[0]))
        js.document.getElementById("resultContainer").style.display = "block"
        js.document.getElementById("guessButton").style.display = "none"
        #js.document.getElementById("mapContainer").style.display = "none"
    except Exception as e:
        print(f"Error in make_guess: {e}")
guess_proxy = create_proxy(make_guess)

def next_round(event):
    print("Next round")
    global run
    run += 1
    if run >= len(img_list):
        #print("No more images available. Starting new round...")
        #run = 0
        #asyncio.ensure_future(get_gamesImg(2))
        return
    
    asyncio.ensure_future(get_image("%s/image/%s" %(api_domain, img_list[run])))
    
    #js.document.getElementById("resultContainer").style.display = "none"
    js.document.getElementById("guessButton").style.display = "inline-block"
    js.document.getElementById("resultContainer").style.display = "none"
    js.clearMap()
    js.onMapClick()
next_round_proxy = create_proxy(next_round)

def next_page(event):
    global leaderboard_site
    if (leaderboard_site +1)*leaderboard_max >= len(leaderboard_data):
        return
    leaderboard_site += 1
    update_scoreboard()
next_page_proxy = create_proxy(next_page)

def previous_page(event):
    global leaderboard_site
    if leaderboard_site <=0:
        return
    leaderboard_site -= 1
    update_scoreboard()
previous_page_proxy = create_proxy(previous_page)

async def get_gamesImg(n:int):
    try:
        gameCode:str = js.document.getElementById("codeInput").value if js.document.getElementById("codeInput").value else ":-:@**"*2
        print("Game code:", gameCode)
        resp = await js.fetch(f"%s/images/{n}/{gameCode}" %api_domain)
        if not resp.ok:
            print("Cookie fetch HTTP error:", resp.status)
            return
        
        data = await resp.json()
        global img_list
        img_list = data.img_paths
        
    except Exception as e:
        print("Cookie fetch error:", e)
    asyncio.ensure_future(get_image("%s/image/%s" %(api_domain, img_list[run])))
    while img.src == '':
        await asyncio.sleep(0.1)
    pic.wheelzoom(img, {"zoom": 0.1, "maxZoom": 3})
    js.document.getElementById("codeInput").value = ""  # Clear the game code input after use
    

#login overlay  
#if not js.document.cookie:
asyncio.ensure_future(loginOverlay())
    #js.document.getElementById("usernameOverlay").style.display = "flex"

    

js.document.getElementById("guessButton").addEventListener("click", guess_proxy)
js.document.getElementById("nextPageButton").addEventListener("click", next_page_proxy)
js.document.getElementById("prevPageButton").addEventListener("click", previous_page_proxy)
js.document.getElementById("nextRoundButton").addEventListener("click", next_round_proxy)
