"""
----------
winning_streaks_ui.py -- Browser interface for the Winning Streaks calculator.
----------
"""

from js       import URLSearchParams,document,window
from pyscript import document,when

from winning_streaks       import longest_streak_distribution,maxGames
from winning_streaks_table import format_table


numWinsInput   = document.querySelector("#number-of-wins")
numLossesInput = document.querySelector("#number-of-losses")
computeButton  = document.querySelector("#compute-button")
clearButton    = document.querySelector("#clear-button")
worksheet      = document.querySelector("#worksheet")
status         = document.querySelector("#status")


@when("click","#compute-button")
def compute_button_clicked(event):
	compute()


@when("click","#clear-button")
def clear_button_clicked(event):
	worksheet.value = ""
	status.textContent = "Output cleared."


@when("keydown","#number-of-wins")
@when("keydown","#number-of-losses")
def input_key_pressed(event):
	if (event.key == "Enter"):
		event.preventDefault()
		compute()


def read_deep_links() -> dict:
	""" return (and sanitize) validated startup overrides from the page URL """

	params = URLSearchParams.new(window.location.search)
	deepLink = {}

	winsText = params.get("W")
	try:
		wins = int(str(winsText))
	except (TypeError,ValueError):
		wins = None
	if (wins is not None) and (1 <= wins <= maxGames):
		deepLink["wins"] = wins

	lossesText = params.get("L")
	try:
		losses = int(str(lossesText))
	except (TypeError,ValueError):
		losses = None
	if (losses is not None) and (1 <= losses <= maxGames):
		deepLink["losses"] = losses

	return deepLink

deepLink = read_deep_links()
if ("wins"   in deepLink): numWinsInput.value   = str(deepLink["wins"])
if ("losses" in deepLink): numLossesInput.value = str(deepLink["losses"])


def compute():
	status.textContent = ""

	try:
		numWins = parse_positive_integer(numWinsInput,"Number of wins")
	except ValueError as exception:
		show_error(str(exception),numWinsInput)
		return

	try:
		numLosses = parse_positive_integer(numLossesInput,"Number of losses")
	except ValueError as exception:
		show_error(str(exception),numLossesInput)
		return

	computeButton.disabled = True
	status.textContent = "Computing…"

	try:
		results = longest_streak_distribution(numWins,numLosses)
		add_to_worksheet(format_table(numWins,numLosses,results))
		status.textContent = "Table computed."
	finally:
		computeButton.disabled = False


def add_to_worksheet(text):
	if ((worksheet.value != "") and (not worksheet.value.endswith("\n\n"))):
		worksheet.value += "\n\n"

	worksheet.value += text + "\n\n"
	worksheet.scrollTop = worksheet.scrollHeight


def parse_positive_integer(inputElement,fieldName):
	text = inputElement.value.strip()

	if (text == ""):
		raise ValueError(f"{fieldName} is required.")

	try:
		value = int(text)
	except ValueError:
		raise ValueError(f"{fieldName} must be a whole number.") from None

	if (value < 1):
		raise ValueError(f"{fieldName} must be at least 1.")

	return value


def show_error(message,inputElement=None):
	status.textContent = message

	if (inputElement is not None):
		inputElement.focus()
		inputElement.select()


status.textContent = "Ready."
