"""Breez SDK Spark backend for social-value."""

from __future__ import annotations

import logging
from pathlib import Path

from .types import PaymentRecord, WalletState

logger = logging.getLogger(__name__)


class SparkBackend:
    """Spark backend using breez-sdk-spark."""

    def __init__(self) -> None:
        self._sdk = None

    @property
    def name(self) -> str:
        return "spark"

    def connect(self, mnemonic: str, api_key: str, network: str, working_dir: str) -> None:
        try:
            from breez_sdk_spark import (
                ConnectRequest,
                SparkNetwork,
                connect,
                default_config,
            )
        except ImportError:
            raise ImportError(
                "Spark backend requires breez-sdk-spark. "
                "Install with: pip install social-value[spark]"
            )

        net = SparkNetwork.MAINNET if network == "mainnet" else SparkNetwork.TESTNET
        config = default_config(network=net, breez_api_key=api_key)

        wd = Path(working_dir)
        wd.mkdir(parents=True, exist_ok=True)
        config.working_dir = str(wd)

        # Build request and clear mnemonic from local scope to prevent traceback leaks
        request = ConnectRequest(config=config, mnemonic=mnemonic)
        del mnemonic, api_key
        self._sdk = connect(request)
        del request
        logger.info("social-value: connected to Spark backend (%s)", network)

    def disconnect(self) -> None:
        if self._sdk:
            self._sdk.disconnect()
            self._sdk = None

    def get_state(self) -> WalletState:
        info = self._sdk.get_info()
        return WalletState(
            balance_sat=info.wallet_info.balance_sat,
            pending_send_sat=info.wallet_info.pending_send_sat,
            pending_receive_sat=info.wallet_info.pending_receive_sat,
        )

    def create_invoice(self, amount_sat: int, description: str) -> str:
        from breez_sdk_spark import (
            PaymentMethod,
            PrepareReceiveRequest,
            ReceiveAmount,
            ReceivePaymentRequest,
        )

        prepare = self._sdk.prepare_receive_payment(
            PrepareReceiveRequest(
                payment_method=PaymentMethod.BOLT11_INVOICE,
                amount=ReceiveAmount.BITCOIN(amount_sat),
            )
        )
        logger.info("Spark: deposit %d sats, fee %d sats", amount_sat, prepare.fees_sat)

        res = self._sdk.receive_payment(
            ReceivePaymentRequest(prepare_response=prepare, description=description)
        )
        return res.destination

    def send(self, destination: str, amount_sat: int, memo: str | None = None) -> str:
        from breez_sdk_spark import PayAmount, PrepareSendRequest, SendPaymentRequest

        prepare = self._sdk.prepare_send_payment(
            PrepareSendRequest(destination=destination, amount=PayAmount.BITCOIN(amount_sat))
        )
        res = self._sdk.send_payment(
            SendPaymentRequest(prepare_response=prepare, payer_note=memo)
        )
        return res.payment.id if res.payment else ""

    def send_drain(self, destination: str) -> tuple[int, int, str]:
        from breez_sdk_spark import PayAmount, PrepareSendRequest, SendPaymentRequest

        prepare = self._sdk.prepare_send_payment(
            PrepareSendRequest(destination=destination, amount=PayAmount.DRAIN)
        )
        res = self._sdk.send_payment(SendPaymentRequest(prepare_response=prepare))
        amount = res.payment.amount_sat if res.payment else 0
        fee = prepare.fees_sat
        pid = res.payment.id if res.payment else ""
        return (amount, fee, pid)

    def get_send_fee(self, destination: str, amount_sat: int) -> int:
        from breez_sdk_spark import PayAmount, PrepareSendRequest

        prepare = self._sdk.prepare_send_payment(
            PrepareSendRequest(destination=destination, amount=PayAmount.BITCOIN(amount_sat))
        )
        return prepare.fees_sat

    def list_payments(self, limit: int, offset: int) -> tuple[PaymentRecord, ...]:
        from breez_sdk_spark import ListPaymentsRequest

        raw = self._sdk.list_payments(ListPaymentsRequest(limit=limit, offset=offset))
        records: list[PaymentRecord] = []
        for p in raw:
            direction = "send" if p.payment_type.name == "SEND" else "receive"
            records.append(
                PaymentRecord(
                    payment_id=p.id or "",
                    direction=direction,
                    amount_sat=p.amount_sat or 0,
                    fee_sat=p.fees_sat or 0,
                    destination=p.destination or "",
                    timestamp=p.timestamp or 0.0,
                )
            )
        return tuple(records)
