"""In-memory Lightning transaction ledger.

Tracks invoices, settlements, and balances per the schema in
``docs/adr/018-lightning-ledger.md``.  Uses a simple in-memory list so the
dashboard can display real (ephemeral) data without requiring SQLite yet.
"""

from __future__ import annotations

import logging
import uuid
from dataclasses import dataclass
from datetime import UTC, datetime
from enum import StrEnum

logger = logging.getLogger(__name__)


class TxType(StrEnum):
    incoming = "incoming"
    outgoing = "outgoing"


class TxStatus(StrEnum):
    pending = "pending"
    settled = "settled"
    failed = "failed"
    expired = "expired"


@dataclass
class LedgerEntry:
    """Single ledger row matching the ADR-018 schema."""

    id: str
    tx_type: TxType
    status: TxStatus
    payment_hash: str
    amount_sats: int
    memo: str
    source: str
    created_at: str
    invoice: str = ""
    preimage: str = ""
    task_id: str = ""
    agent_id: str = ""
    settled_at: str = ""
    fee_sats: int = 0


# ── In-memory store ──────────────────────────────────────────────────
_entries: list[LedgerEntry] = []


def create_invoice_entry(
    payment_hash: str,
    amount_sats: int,
    memo: str = "",
    source: str = "tool_usage",
    task_id: str = "",
    agent_id: str = "",
    invoice: str = "",
) -> LedgerEntry:
    """Record a new incoming invoice in the ledger."""
    entry = LedgerEntry(
        id=uuid.uuid4().hex[:16],
        tx_type=TxType.incoming,
        status=TxStatus.pending,
        payment_hash=payment_hash,
        amount_sats=amount_sats,
        memo=memo,
        source=source,
        task_id=task_id,
        agent_id=agent_id,
        invoice=invoice,
        created_at=datetime.now(UTC).isoformat(),
    )
    _entries.append(entry)
    logger.debug("Ledger entry created: %s (%s sats)", entry.id, amount_sats)
    return entry


def mark_settled(payment_hash: str, preimage: str = "") -> LedgerEntry | None:
    """Mark a pending entry as settled by payment hash."""
    for entry in _entries:
        if entry.payment_hash == payment_hash and entry.status == TxStatus.pending:
            entry.status = TxStatus.settled
            entry.preimage = preimage
            entry.settled_at = datetime.now(UTC).isoformat()
            logger.debug("Ledger settled: %s", payment_hash[:12])
            return entry
    return None


def get_balance() -> dict:
    """Compute the current balance from settled and pending entries."""
    incoming_total = sum(
        e.amount_sats
        for e in _entries
        if e.tx_type == TxType.incoming and e.status == TxStatus.settled
    )
    outgoing_total = sum(
        e.amount_sats
        for e in _entries
        if e.tx_type == TxType.outgoing and e.status == TxStatus.settled
    )
    fees = sum(e.fee_sats for e in _entries if e.status == TxStatus.settled)
    pending_in = sum(
        e.amount_sats
        for e in _entries
        if e.tx_type == TxType.incoming and e.status == TxStatus.pending
    )
    pending_out = sum(
        e.amount_sats
        for e in _entries
        if e.tx_type == TxType.outgoing and e.status == TxStatus.pending
    )
    net = incoming_total - outgoing_total - fees
    return {
        "incoming_total_sats": incoming_total,
        "outgoing_total_sats": outgoing_total,
        "fees_paid_sats": fees,
        "net_sats": net,
        "pending_incoming_sats": pending_in,
        "pending_outgoing_sats": pending_out,
        "available_sats": net - pending_out,
    }


def get_transactions(
    tx_type: str | None = None,
    status: str | None = None,
    limit: int = 50,
) -> list[LedgerEntry]:
    """Return ledger entries, optionally filtered."""
    result = _entries
    if tx_type:
        result = [e for e in result if e.tx_type.value == tx_type]
    if status:
        result = [e for e in result if e.status.value == status]
    return list(reversed(result))[:limit]


def clear() -> None:
    """Reset the ledger (for testing)."""
    _entries.clear()
