"""
Coverage tests for script/type.py - untested branches.
"""

import pytest

from bsv.keys import PrivateKey
from bsv.script.type import P2PKH

# ========================================================================
# P2PKH lock branches
# ========================================================================


def test_p2pkh_lock_with_address():
    """Test P2PKH lock with address string."""
    priv = PrivateKey()
    pub = priv.public_key()
    address = pub.address()

    script = P2PKH().lock(address)
    assert script is not None
    assert script.byte_length() == 25


def test_p2pkh_lock_with_pkh_bytes():
    """Test P2PKH lock with public key hash bytes."""
    from bsv.hash import hash160

    priv = PrivateKey()
    pub = priv.public_key()
    pkh = hash160(pub.serialize())

    script = P2PKH().lock(pkh)
    assert script is not None
    assert script.byte_length() == 25


# ========================================================================
# P2PKH unlock branches
# ========================================================================


def test_p2pkh_unlock_basic():
    """Test P2PKH unlock script creation."""
    priv = PrivateKey()

    try:
        unlocking_template = P2PKH().unlock(priv)
        assert unlocking_template is not None
    except AttributeError:
        # May have different API
        pytest.skip("P2PKH.unlock not available")


# ========================================================================
# P2PKH verification branches
# ========================================================================


def test_p2pkh_is_p2pkh_valid():
    """Test is_p2pkh with valid P2PKH script."""
    from bsv.script.script import Script

    # Valid P2PKH: OP_DUP OP_HASH160 <20 bytes> OP_EQUALVERIFY OP_CHECKSIG
    script = Script(b"\x76\xa9\x14" + b"\x00" * 20 + b"\x88\xac")

    if hasattr(P2PKH, "is_p2pkh"):
        result = P2PKH.is_p2pkh(script)
        assert result


def test_p2pkh_is_p2pkh_invalid():
    """Test is_p2pkh with invalid script."""
    from bsv.script.script import Script

    script = Script(b"\x51\x52")  # OP_1 OP_2

    if hasattr(P2PKH, "is_p2pkh"):
        result = P2PKH.is_p2pkh(script)
        assert not result


def test_p2pkh_is_p2pkh_empty():
    """Test is_p2pkh with empty script."""
    from bsv.script.script import Script

    script = Script(b"")

    if hasattr(P2PKH, "is_p2pkh"):
        result = P2PKH.is_p2pkh(script)
        assert not result


def test_p2pkh_is_p2pkh_wrong_length():
    """Test is_p2pkh with wrong length."""
    from bsv.script.script import Script

    # Wrong pubkeyhash length
    script = Script(b"\x76\xa9\x14" + b"\x00" * 19 + b"\x88\xac")

    if hasattr(P2PKH, "is_p2pkh"):
        result = P2PKH.is_p2pkh(script)
        assert not result


# ========================================================================
# P2PKH extraction branches
# ========================================================================


def test_p2pkh_extract_pubkey_hash():
    """Test extracting public key hash from P2PKH."""
    from bsv.script.script import Script

    pkh = b"\x11" * 20
    script = Script(b"\x76\xa9\x14" + pkh + b"\x88\xac")

    if hasattr(P2PKH, "extract_pubkey_hash"):
        extracted = P2PKH.extract_pubkey_hash(script)
        assert extracted == pkh


def test_p2pkh_extract_pubkey_hash_invalid():
    """Test extracting from invalid P2PKH."""
    from bsv.script.script import Script

    script = Script(b"\x51")

    if hasattr(P2PKH, "extract_pubkey_hash"):
        try:
            extracted = P2PKH.extract_pubkey_hash(script)
            assert extracted is None
        except Exception:
            # Expected for invalid script
            pass


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


def test_p2pkh_with_compressed_key():
    """Test P2PKH with compressed public key."""
    priv = PrivateKey()
    address = priv.public_key().address()

    script = P2PKH().lock(address)
    # Should produce standard 25-byte P2PKH
    assert script.byte_length() == 25


def test_p2pkh_deterministic():
    """Test P2PKH lock is deterministic."""
    priv = PrivateKey(b"\x01" * 32)
    address = priv.public_key().address()

    script1 = P2PKH().lock(address)
    script2 = P2PKH().lock(address)

    assert script1.serialize() == script2.serialize()
