"""Registra/actualiza un perfil de Chromium (y opcionalmente sus cuentas) en osint_db.

Wrapper cliente del service local `osint_db` (FastAPI + DuckDB single-writer) que
mantiene el catalogo de perfiles del navegador usados para investigaciones multicuenta
OSINT. En una sola llamada hace:

1. POST /api/browser-profile con la metadata del perfil (upsert idempotente).
2. Un POST /api/browser-profile/account por cada cuenta de la lista `accounts`.

Funcion impura: hace red (HTTP al service). No lanza; devuelve un dict de estado.
El service responde SIEMPRE HTTP 200 con body `{"status":...}` (se parsea el body).
"""

from browser._osint_db_client import post_json


def browser_profile_register(
    profile_dir: str,
    label: str = "",
    persona: str = "",
    purpose: str = "",
    note_path: str = "",
    tags: list | None = None,
    notes: str = "",
    user_data_dir: str = "",
    status: str = "active",
    accounts: list | None = None,
    base_url: str = "http://127.0.0.1:8771",
) -> dict:
    """Registra o actualiza un perfil Chromium y sus cuentas en el catalogo osint_db.

    Args:
        profile_dir: nombre del directorio real del perfil Chromium (ej. "Profile 1",
            "Default", "osint_01"). Es la PK del perfil; el upsert es idempotente sobre el.
        label: etiqueta humana del perfil (ej. "Persona Maria - OSINT"). "" para omitir.
        persona: identidad/alias ficticio asociado al perfil. "" para omitir.
        purpose: proposito de la investigacion (ej. "rastreo cuentas falsas"). "" para omitir.
        note_path: ruta (rel al vault) de la nota OSINT ligada al perfil. "" para omitir.
        tags: lista de strings de etiquetas (ej. ["osint", "sock-puppet"]). None -> [].
        notes: notas libres sobre el perfil. "" para omitir.
        user_data_dir: directorio user-data-dir de Chromium si NO es el default del wrapper.
            "" -> el perfil hereda el default chromium-cdp al abrirlo.
        status: estado del perfil (active|archived|burned...). Default "active".
        accounts: lista de dicts de cuentas a registrar, cada uno
            {service, identity, secret_ref?, role?, status?, notes?}. None -> sin cuentas.
            `secret_ref` es una REFERENCIA al secreto (ej. "pass show osint/p1/gmail"),
            NUNCA el password en claro.
        base_url: base del service osint_db. Default http://127.0.0.1:8771.

    Returns:
        Caso ok: {"status":"ok", "profile_dir": str, "accounts": int (cuentas registradas
            con exito), "account_errors": list (errores por cuenta, vacia si todo OK)}.
        Caso error (fallo del POST del perfil): {"status":"error", "error": str}.
    """
    try:
        profile_payload: dict = {"profile_dir": profile_dir, "status": status}
        if label:
            profile_payload["label"] = label
        if persona:
            profile_payload["persona"] = persona
        if purpose:
            profile_payload["purpose"] = purpose
        if note_path:
            profile_payload["note_path"] = note_path
        if tags:
            profile_payload["tags"] = list(tags)
        if notes:
            profile_payload["notes"] = notes
        if user_data_dir:
            profile_payload["user_data_dir"] = user_data_dir

        resp = post_json(base_url, "/api/browser-profile", profile_payload)
        if resp.get("status") != "ok":
            return {
                "status": "error",
                "error": resp.get("error", f"el service rechazo el perfil: {resp}"),
            }

        registered_accounts = 0
        account_errors: list = []
        for acc in accounts or []:
            if not isinstance(acc, dict) or not acc.get("service") or not acc.get("identity"):
                account_errors.append(
                    {"account": acc, "error": "cuenta requiere al menos {service, identity}"}
                )
                continue
            acc_payload = {"profile_dir": profile_dir}
            for key in ("service", "identity", "secret_ref", "role", "status", "notes"):
                if acc.get(key):
                    acc_payload[key] = acc[key]
            acc_resp = post_json(base_url, "/api/browser-profile/account", acc_payload)
            if acc_resp.get("status") == "ok":
                registered_accounts += 1
            else:
                account_errors.append(
                    {
                        "account": {"service": acc.get("service"), "identity": acc.get("identity")},
                        "error": acc_resp.get("error", str(acc_resp)),
                    }
                )

        return {
            "status": "ok",
            "profile_dir": profile_dir,
            "accounts": registered_accounts,
            "account_errors": account_errors,
        }
    except Exception as e:  # noqa: BLE001 - contrato: nunca lanzar
        return {"status": "error", "error": f"{type(e).__name__}: {e}"}


if __name__ == "__main__":
    # Smoke contra un puerto muerto: ejercita la degradacion graceful (service inaccesible).
    res = browser_profile_register(
        "Profile 1",
        label="Persona Maria - OSINT",
        persona="maria_ficticia",
        purpose="rastreo cuentas falsas",
        tags=["osint", "sock-puppet"],
        accounts=[{"service": "gmail", "identity": "maria@example.com",
                   "secret_ref": "pass show osint/p1/gmail"}],
        base_url="http://127.0.0.1:1",
    )
    assert res["status"] == "error", res
    print("browser_profile_register smoke OK (service caido -> status error)")
    print(f"  {res}")
