#!/usr/bin/env python3
# -*- coding: utf-8 -*-
"""
Login handler for Integrated CRM Application
Handles both encoded and plaintext password comparison
"""
username = params_kw.get('username', '')
password = params_kw.get('password', '')

if not username:
    return json.dumps({'status': 'error', 'message': 'Username is required'}, ensure_ascii=False)

if not password:
    return json.dumps({'status': 'error', 'message': 'Password is required'}, ensure_ascii=False)

# Get user from RBAC database
dbname = get_module_dbname('rbac')
async with DBPools().sqlorContext(dbname) as sor:
    users = await sor.sqlExe(
        "SELECT id, username, name, orgid, password, login_fail_count, last_login_fail FROM users WHERE username=${username}$",
        {'username': username}
    )

if not users:
    return json.dumps({'status': 'error', 'message': 'Invalid username or password'}, ensure_ascii=False)

user = users[0]
stored_pw = getattr(user, 'password', '')
fail_count = getattr(user, 'login_fail_count', 0) or 0

# Check lockout
if fail_count >= 3 and user.last_login_fail:
    return json.dumps({'status': 'error', 'message': 'Account locked. Try again in 5 minutes.'}, ensure_ascii=False)

# Try encoded password first, then plaintext fallback
encoded_pw = password_encode(password)
auth_ok = (stored_pw == encoded_pw) or (stored_pw == password)

if auth_ok:
    # Reset fail count on successful login
    async with DBPools().sqlorContext(dbname) as sor:
        await sor.sqlExe(
            "UPDATE users SET login_fail_count=0, last_login_fail=NULL WHERE id=${id}$",
            {'id': user.id}
        )
    
    await remember_user(user.id, user.username, getattr(user, 'orgid', '') or '')
    return json.dumps({
        'status': 'ok',
        'message': 'Login successful',
        'redirect': '/main/base.ui',
        'userid': user.id,
        'username': user.username
    }, ensure_ascii=False)

# Failed login - increment fail count
async with DBPools().sqlorContext(dbname) as sor:
    await sor.sqlExe(
        "UPDATE users SET login_fail_count = login_fail_count + 1, last_login_fail=NOW() WHERE id=${id}$",
        {'id': user.id}
    )

new_fail_count = fail_count + 1
if new_fail_count >= 3:
    return json.dumps({'status': 'error', 'message': 'Account locked after too many failed attempts'}, ensure_ascii=False)

remaining = 3 - new_fail_count
return json.dumps({'status': 'error', 'message': f'Invalid credentials ({remaining} attempts remaining)'}, ensure_ascii=False)
