from __future__ import annotations

import argparse
import getpass
import sys

from ...errors import QingflowApiError
from ..context import CliContext
from ..qingflow_login import login_with_qingflow_password
from .common import read_secret_arg


def register(subparsers: argparse._SubParsersAction[argparse.ArgumentParser]) -> None:
    parser = subparsers.add_parser("auth", help="认证与会话")
    auth_subparsers = parser.add_subparsers(dest="auth_command", required=True)

    login = auth_subparsers.add_parser("login", help="登录 CLI：轻流账号密码交互")
    login.add_argument("--base-url")
    login.add_argument("--qf-version")
    login.add_argument("--email", help="轻流账号邮箱；不传时在交互终端提示输入")
    login.add_argument("--password", help="轻流账号密码；建议仅用于本地调试，脚本请优先使用 --password-stdin")
    login.add_argument("--password-stdin", action="store_true", help="从标准输入读取轻流账号密码")
    login.add_argument("--persist", action=argparse.BooleanOptionalAction, default=True)
    login.set_defaults(handler=_handle_login, format_hint="auth_whoami")

    use_credential = auth_subparsers.add_parser("use-credential", help="直接注入 credential")
    use_credential.add_argument("--base-url")
    use_credential.add_argument("--qf-version")
    use_credential.add_argument("--credential")
    use_credential.add_argument("--credential-stdin", action="store_true")
    use_credential.add_argument("--persist", action=argparse.BooleanOptionalAction, default=False)
    use_credential.set_defaults(handler=_handle_use_credential, format_hint="auth_whoami")

    whoami = auth_subparsers.add_parser("whoami", help="查看当前登录态")
    whoami.set_defaults(handler=_handle_whoami, format_hint="auth_whoami")

    logout = auth_subparsers.add_parser("logout", help="退出登录")
    logout.add_argument("--forget-persisted", action="store_true")
    logout.set_defaults(handler=_handle_logout, format_hint="")


def _handle_login(args: argparse.Namespace, context: CliContext) -> dict:
    email = _resolve_login_email(args)
    password = _resolve_login_password(args)
    login_result = login_with_qingflow_password(
        base_url=args.base_url,
        email=email,
        password=password,
    )
    result = context.auth.auth_use_token(
        profile=args.profile,
        base_url=args.base_url,
        qf_version=args.qf_version,
        token=login_result.token,
        login_token=login_result.login_token,
        user_info=login_result.user_info,
        persist=bool(args.persist),
    )
    warnings = list(result.get("warnings") or []) if isinstance(result, dict) else []
    if isinstance(result, dict):
        result["cli_auth"] = {"flow": login_result.flow}
        if warnings:
            result["warnings"] = warnings
    return result


def _resolve_login_email(args: argparse.Namespace) -> str:
    email = str(args.email or "").strip()
    if email:
        return email
    if sys.stdin.isatty():
        return input("Qingflow email: ").strip()
    raise QingflowApiError.config_error(
        "qingflow auth login needs an interactive terminal, or pass --email with --password-stdin."
    )


def _resolve_login_password(args: argparse.Namespace) -> str:
    if args.password or bool(args.password_stdin):
        return read_secret_arg(
            args.password,
            stdin_enabled=bool(args.password_stdin),
            label="password",
        )
    if sys.stdin.isatty():
        return getpass.getpass("Qingflow password: ")
    raise QingflowApiError.config_error(
        "qingflow auth login needs an interactive terminal or --password-stdin."
    )


def _handle_use_credential(args: argparse.Namespace, context: CliContext) -> dict:
    credential = (
        read_secret_arg(args.credential, stdin_enabled=bool(args.credential_stdin), label="credential")
        if args.credential or bool(args.credential_stdin)
        else ""
    )
    return context.auth.auth_use_credential(
        profile=args.profile,
        base_url=args.base_url,
        qf_version=args.qf_version,
        credential=credential,
        persist=bool(args.persist),
    )


def _handle_whoami(args: argparse.Namespace, context: CliContext) -> dict:
    return context.auth.auth_whoami(profile=args.profile)


def _handle_logout(args: argparse.Namespace, context: CliContext) -> dict:
    return context.auth.auth_logout(profile=args.profile, forget_persisted=bool(args.forget_persisted))
