# ------------------------------------------------------------
# pwentry.py - brython password strength meter
# attaches to elements with known ids on the page.
# safe to load on any page - silently exits if elements not found.
# ------------------------------------------------------------

from browser import document as doc, window

from utils import *

# ------------------------------------------------------------

MINLEN   = 10
MINSCORE = 2
CLASSES  = [ 'very-weak', 'weak', 'fair', 'strong', 'very-strong' ]
LABELS   = [ 'Very weak', 'Weak', 'Fair', 'Strong', 'Very strong' ]

# ------------------------------------------------------------

def setclass (el, cls) :
	if not el :
		warn (f'cant set class, no element : { el = } : { cls = }')
		return
	if not cls :
		warn (f'cant set class, no class given : { el = } : { cls = }')
		return
		
	for c in CLASSES :
		el.classList.remove (c)
	if cls :
		el.classList.add (cls)

# ------------------------------------------------------------

def show (el) :  el.classList.remove ('hidden')
def hide (el) :  el.classList.add    ('hidden')

# ------------------------------------------------------------

def toggle_password (ev) :
	'toggle password visibility'

	field = doc.getElementById ('passphrase')
	if not field :  return
	field.type = 'text' if field.type == 'password' else 'password'

#@	markup = '''
#@<button class="showpass" onclick="alert('foo')"> <img src="https://dev.towncards.my.to/static/images/eye-show.svg"> </button>
#@
#@.field {
#@	position : relative ;
#@}
#@.showpass {
#@  width: 1.5em;
#@  background-image: url("/static/images/eye-show.svg");
#@  background-size: 1em;
#@  height: 1.8em;
#@  stroke: #999 ;
#@  padding: 0.1em;
#@  border: none;
#@  background: top;
#@  margin-top: 0.5em;
#@  position: absolute;
#@  right: 0;
#@  top: 0.1em;
#@}
#@'''
# ------------------------------------------------------------

def update (ev = none) :

	log ('password update : ')

	passfield = doc.getElementById ('passphrase')
	if not passfield :  return

	emailfield  = doc.getElementById ('email')
	bar         = doc.getElementById ('strength-bar')
	text        = doc.getElementById ('strength-text')
	lencount    = doc.getElementById ('len-count')
	lenok       = doc.getElementById ('len-ok')
	lenfail     = doc.getElementById ('len-fail')

	# bail silently if any required element is missing
	if not all ([ bar, text, lencount, lenok, lenfail ]) :
		log (f'pass check : MISSING ELEMENTS : { [ bar, text, lencount, lenok, lenfail ] }')
		#return

	passval = passfield.value or ''
	length  = len (passval)

	if not passval :
		hide (lenok)
		hide (lenfail)
		lencount.textContent = '0 chars'
		setclass (bar,  none)
		setclass (text, none)
		text.textContent = ''
		return

	# --- length indicator

	lencount.textContent = f'{ length } chars'

	# --- strength meter via zxcvbn

	emailval = emailfield.value if emailfield else ''
	ctx      = [ emailval ] if emailval else []

	result  = window.zxcvbn (passval, ctx)
	score   = int (result.score)
	cls     = CLASSES [ score ]

	setclass (bar,  cls)
	setclass (text, cls)

	label   = LABELS [ score ]
	warning = result.feedback and result.feedback.warning or ''

	if length >= MINLEN and score >= MINSCORE:
		show (lenok)
		hide (lenfail)
	else :
		show (lenfail)
		hide (lenok)

	text.textContent = f'{ label } \u2014 { warning }' if warning else label

# ------------------------------------------------------------

def main () :

	passfield = doc.getElementById ('passphrase')
	if not passfield :
		return   # not on a page with password entry, nothing to do

	# wire up handlers
	passfield.bind ('input', update)

	passtoggle = doc.getElementById ('pwtoggle')
	passtoggle.bind ('click', toggle_password)

	emailfield = doc.getElementById ('email')
	if emailfield :
		emailfield.bind ('input', update)

	loginbtn = doc.getElementById ('login-pass')
	if loginbtn :
		def on_submit (ev) :
			form = doc.getElementById ('login-form')
			form.action = '/auth/login/pass'
			if form :  form.submit ()
		loginbtn.bind ('click', on_submit)

	createbtn = doc.getElementById ('create-pass')
	if createbtn :
		def on_submit (ev) :
			form = doc.getElementById ('login-form')
			form.action = '/auth/login/create'
			if form :  form.submit ()
		createbtn.bind ('click', on_submit)

# ------------------------------------------------------------

try :  polling (main, '#passphrase')
except Exception as e :  shout (f'error in main : { e }')
