"""
Coverage tests for transaction_output.py - untested branches.
"""

import pytest

from bsv.script.script import Script
from bsv.transaction_output import TransactionOutput

# ========================================================================
# TransactionOutput initialization branches
# ========================================================================


def test_transaction_output_init_zero_satoshis():
    """Test TransactionOutput with zero satoshis."""
    out = TransactionOutput(satoshis=0, locking_script=Script(b""))
    assert out.satoshis == 0


def test_transaction_output_init_small_amount():
    """Test TransactionOutput with small amount."""
    out = TransactionOutput(satoshis=1, locking_script=Script(b""))
    assert out.satoshis == 1


def test_transaction_output_init_large_amount():
    """Test TransactionOutput with large amount."""
    large_amount = 21_000_000 * 100_000_000  # Max BTC supply
    out = TransactionOutput(satoshis=large_amount, locking_script=Script(b""))
    assert out.satoshis == large_amount


def test_transaction_output_init_negative_amount():
    """Test TransactionOutput with negative amount."""
    try:
        out = TransactionOutput(satoshis=-1, locking_script=Script(b""))
        assert out.satoshis == -1
    except ValueError:
        # May validate positive amounts
        pass


def test_transaction_output_init_empty_script():
    """Test TransactionOutput with empty locking script."""
    out = TransactionOutput(satoshis=1000, locking_script=Script(b""))
    assert len(out.locking_script.serialize()) == 0


def test_transaction_output_init_with_script():
    """Test TransactionOutput with locking script."""
    out = TransactionOutput(satoshis=1000, locking_script=Script(b"\x51"))  # OP_1
    assert len(out.locking_script.serialize()) > 0


def test_transaction_output_init_p2pkh_script():
    """Test TransactionOutput with P2PKH script."""
    # P2PKH: OP_DUP OP_HASH160 <pubkeyhash> OP_EQUALVERIFY OP_CHECKSIG
    script_bytes = b"\x76\xa9\x14" + b"\x00" * 20 + b"\x88\xac"
    out = TransactionOutput(satoshis=1000, locking_script=Script(script_bytes))
    assert len(out.locking_script.serialize()) == 25


# ========================================================================
# Serialization branches
# ========================================================================


def test_transaction_output_serialize():
    """Test TransactionOutput serialization."""
    out = TransactionOutput(satoshis=1000, locking_script=Script(b""))
    serialized = out.serialize()
    assert isinstance(serialized, bytes)
    assert len(serialized) >= 9  # 8 bytes value + 1 byte script length


def test_transaction_output_serialize_with_script():
    """Test TransactionOutput serialization with script."""
    out = TransactionOutput(satoshis=1000, locking_script=Script(b"\x51\x52"))
    serialized = out.serialize()
    assert len(serialized) > 9


def test_transaction_output_serialize_zero_satoshis():
    """Test TransactionOutput serialization with zero satoshis."""
    out = TransactionOutput(satoshis=0, locking_script=Script(b""))
    serialized = out.serialize()
    # First 8 bytes should be zero
    assert serialized[:8] == b"\x00" * 8


def test_transaction_output_serialize_max_satoshis():
    """Test TransactionOutput serialization with max satoshis."""
    out = TransactionOutput(satoshis=0xFFFFFFFFFFFFFFFF, locking_script=Script(b""))
    serialized = out.serialize()
    # First 8 bytes should be all 0xFF
    assert serialized[:8] == b"\xff" * 8


# ========================================================================
# Script type detection
# ========================================================================


def test_transaction_output_is_p2pkh():
    """Test detecting P2PKH output."""
    script_bytes = b"\x76\xa9\x14" + b"\x00" * 20 + b"\x88\xac"
    out = TransactionOutput(satoshis=1000, locking_script=Script(script_bytes))
    # Check if has method to detect type
    if hasattr(out, "is_p2pkh"):
        assert out.is_p2pkh()


def test_transaction_output_is_p2sh():
    """Test detecting P2SH output."""
    # P2SH: OP_HASH160 <scripthash> OP_EQUAL
    script_bytes = b"\xa9\x14" + b"\x00" * 20 + b"\x87"
    out = TransactionOutput(satoshis=1000, locking_script=Script(script_bytes))
    if hasattr(out, "is_p2sh"):
        assert out.is_p2sh()


# ========================================================================
# Edge cases
# ========================================================================


def test_transaction_output_str_representation():
    """Test TransactionOutput string representation."""
    out = TransactionOutput(satoshis=1000, locking_script=Script(b""))
    str_repr = str(out)
    assert isinstance(str_repr, str)


def test_transaction_output_satoshi_boundaries():
    """Test TransactionOutput at satoshi boundaries."""
    # Test various boundary values
    for amount in [0, 1, 546, 1000, 100_000_000, 21_000_000 * 100_000_000]:
        out = TransactionOutput(satoshis=amount, locking_script=Script(b""))
        assert out.satoshis == amount


def test_transaction_output_dust_amount():
    """Test TransactionOutput with dust amount (546 sats)."""
    out = TransactionOutput(satoshis=546, locking_script=Script(b""))  # Standard dust limit
    assert out.satoshis == 546
