"""User-paste-creds flow — skip signup entirely.

The user creates the Spotify account manually in their own browser (which is
the right tool for the captcha step — accessibility options + their normal
fingerprint pass Google's score naturally). They then paste the new account's
email + password into the PWA. SB handles the rest:

  1. Save new creds to vault
  2. trikatuka: log in user1 (old) + user2 (new) + Transfer all playlists
  3. smurfmarkt: apply the upgrade_key to the new account

This is strictly additive to `full_flow` — the signup automation path is
still there for anyone who wants to use it.
"""
from typing import Any, Callable, Dict

import abort
from config import Config
from utils.logger import child
from vault import save_credentials

from . import smurfmarkt, trikatuka

log = child("trikatuka_smurfmarkt")


def run(sb_factory: Callable, params: Dict[str, Any], cfg: Config) -> Dict[str, Any]:
    new_email = (params.get("new_email") or "").strip()
    new_password = params.get("new_password") or ""
    old_email = (params.get("old_email") or "").strip()
    old_password = params.get("old_password") or ""
    upgrade_key = (params.get("upgrade_key") or "").strip()
    country = params.get("country") or "US"
    save_as_site = params.get("save_as_site") or cfg.signup_save_as_site

    missing = []
    if not new_email: missing.append("new_email")
    if not new_password: missing.append("new_password")
    if not old_email: missing.append("old_email")
    if not old_password: missing.append("old_password")
    if missing:
        return {"ok": False, "error": "missing required creds: " + ", ".join(missing)}

    log_parts = []

    with sb_factory() as sb:
        abort.register_sb(sb)
        try:
            save_credentials(
                cfg, site=save_as_site, email=new_email, password=new_password,
                note="user-pasted; trikatuka+smurfmarkt flow",
            )
            log_parts.append(f"vault saved ({save_as_site})")
            log.info(f"starting trikatuka for new={new_email} old={old_email}")

            trikatuka_params = {
                "old_email": old_email,
                "old_password": old_password,
                "new_email": new_email,
                "new_password": new_password,
            }
            r2 = trikatuka.run(sb, trikatuka_params, cfg)
            log_parts.append(f"trikatuka: {'ok' if r2.get('ok') else 'FAIL ' + str(r2.get('error'))}")
            if not r2.get("ok"):
                return {
                    "ok": False,
                    "error": "trikatuka: " + str(r2.get("error")),
                    "log": "\n".join(log_parts),
                    "email": new_email,
                    "password": new_password,
                    "save_as_site": save_as_site,
                }

            if not upgrade_key:
                log.warning("no upgrade_key provided; skipping smurfmarkt")
                log_parts.append("smurfmarkt: skipped (no upgrade_key)")
                return {
                    "ok": True,
                    "log": "\n".join(log_parts),
                    "email": new_email,
                    "password": new_password,
                    "save_as_site": save_as_site,
                }

            smurf_params = {
                "upgrade_key": upgrade_key,
                "email": new_email,
                "password": new_password,
                "country": country,
            }
            r3 = smurfmarkt.run(sb, smurf_params, cfg)
            log_parts.append(f"smurfmarkt: {'ok' if r3.get('ok') else 'FAIL ' + str(r3.get('error'))}")
            return {
                "ok": bool(r3.get("ok")),
                "error": r3.get("error"),
                "log": "\n".join(log_parts),
                "email": new_email,
                "password": new_password,
                "save_as_site": save_as_site,
            }
        finally:
            abort.clear_sb()
