# -*- coding: utf-8 -*-
from threading import Lock

import utils
import actions.util
from actions.login.get_user_info import get_user_info
from model.customexception import GettingUserInfoException, CanceledDialogException

from sysactions import (
    action,
    get_model,
    show_messagebox,
    StopAction,
    AuthenticationFailed
)

from login_user import sign_in_quick_user
from signin_user import sign_in_table_user
from actions.pos import pos_must_be_blocked
from typing import Optional

current_pos_login_users = {}
login_lock = Lock()
mbcontext = None

@action
def common_login(
        pos_id,         # type: str
        user_id=None,   # type: Optional[str]
        password=None   # type: Optional[str]
):
    # type: (...) -> bool

    global current_pos_login_users

    model = get_model(pos_id)
    try:
        user_info = get_user_info(pos_id, user_id, password, model)
        utils.validate_user_level(pos_id, user_info)
    except CanceledDialogException as _:
        raise StopAction()
    except (AuthenticationFailed, GettingUserInfoException) as _:
        show_messagebox(pos_id, "$INVALID_USERNAME_OR_PASSWORD", "$INFORMATION")
        raise StopAction()

    user_id = user_info.get("UserId")
    with login_lock:
        logged_pos_id = current_pos_login_users[user_id] if user_id in current_pos_login_users else None

    if logged_pos_id is not None:
        show_messagebox(pos_id, message="$USER_IS_LOGIN_IN_POS|{}".format(logged_pos_id), icon="error")
        raise StopAction()

    try:
        with login_lock:
            current_pos_login_users[user_id] = pos_id

        _login_validations(pos_id, user_id)

        working_mode = model.find("WorkingMode").get("usrCtrlType")
        if working_mode == "QSR":
            return sign_in_quick_user(pos_id, user_info)
        else:
            return sign_in_table_user(pos_id, user_info)
    finally:
        with login_lock:
            current_pos_login_users[user_id] = None


def _login_validations(pos_id, user_id):
    if pos_must_be_blocked(pos_id):
        show_messagebox(pos_id, message="$POS_BLOCKED", icon="error")
        raise StopAction()

    if not utils.check_current_day(pos_id):
        raise StopAction()

    actions.util.set_context(mbcontext)
    if actions.util.is_user_already_logged(pos_id, user_id):
        raise StopAction()
