"""
Jam erstellt eine eigene Bitcoin-Adresse (für Solo-Mining / Auszahlung).

Private Key liegt lokal in data/jam-btc-wallet.json – nur auf diesem PC, für David/Jam.
"""

from __future__ import annotations

import hashlib
import json
import os
import secrets
from datetime import datetime
from pathlib import Path

ROOT = Path(__file__).resolve().parent.parent
WALLET_FILE = ROOT / "data" / "jam-btc-wallet.json"

_B58 = "123456789ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijkmnopqrstuvwxyz"


def _b58encode(data: bytes) -> str:
    n = int.from_bytes(data, "big")
    out = ""
    while n > 0:
        n, r = divmod(n, 58)
        out = _B58[r] + out
    pad = 0
    for b in data:
        if b == 0:
            pad += 1
        else:
            break
    return _B58[0] * pad + out


def _b58check(payload: bytes) -> str:
    chk = hashlib.sha256(hashlib.sha256(payload).digest()).digest()[:4]
    return _b58encode(payload + chk)


def _ripemd160(data: bytes) -> bytes:
    try:
        return hashlib.new("ripemd160", data).digest()
    except ValueError:
        pass
    try:
        from Crypto.Hash import RIPEMD160  # type: ignore

        return RIPEMD160.new(data).digest()
    except Exception:
        pass
    raise RuntimeError("RIPEMD160 nicht verfügbar – pip install pycryptodome")


def _pubkey_compressed(priv: bytes) -> bytes:
    from ecdsa import SigningKey, SECP256k1

    sk = SigningKey.from_string(priv, curve=SECP256k1)
    vk = sk.get_verifying_key()
    x = vk.to_string()[:32]
    y_bit = vk.to_string()[32] % 2
    return bytes([2 + y_bit]) + x


def generate_legacy_address() -> tuple[str, str]:
    """P2PKH-Adresse (beginnt mit 1) – funktioniert mit solo.ckpool."""
    priv = secrets.token_bytes(32)
    pub = _pubkey_compressed(priv)
    h160 = _ripemd160(hashlib.sha256(pub).digest())
    payload = b"\x00" + h160
    address = _b58check(payload)
    return address, priv.hex()


def load_jam_wallet() -> dict | None:
    if not WALLET_FILE.is_file():
        return None
    try:
        return json.loads(WALLET_FILE.read_text(encoding="utf-8"))
    except (json.JSONDecodeError, OSError):
        return None


def ensure_jam_wallet(*, owner: str = "David") -> dict:
    """Jam-Wallet anlegen oder laden."""
    existing = load_jam_wallet()
    if existing and existing.get("address"):
        return existing

    address, priv_hex = generate_legacy_address()
    data = {
        "owner": owner,
        "label": "Jam Bitcoin (Solo-Mining)",
        "address": address,
        "private_key_hex": priv_hex,
        "created_at": datetime.now().isoformat(timespec="seconds"),
        "warning": "Private Key geheim halten! Wer den Key hat, kontrolliert die Coins.",
    }
    WALLET_FILE.parent.mkdir(parents=True, exist_ok=True)
    WALLET_FILE.write_text(json.dumps(data, ensure_ascii=False, indent=2), encoding="utf-8")
    return data


def wallet_summary() -> str:
    w = load_jam_wallet()
    if not w:
        return "Noch keine Jam-Wallet – wird beim Mining-Setup erstellt."
    return f"Jam BTC: {w.get('address', '?')[:20]}… (Datei: data/jam-btc-wallet.json)"
