import dotenv
from eth_account.messages import encode_defunct
from web3 import Web3

from web3_google_hsm.accounts.gcp_kms_account import GCPKmsAccount
from web3_google_hsm.types.ethereum_types import Transaction

if __name__ == "__main__":
    from rich.console import Console

    console = Console()
    dotenv.load_dotenv()
    w3 = Web3(Web3.HTTPProvider("http://localhost:8545"))
    account = GCPKmsAccount()

    console.print(f"GCP KMS Account address: {account.address}")

    # 1. Test Message Signing and Verification
    message = "Hello Ethereum!"
    message_hash = encode_defunct(text=message)

    # Sign the message
    signed_message = account.sign_message(message)
    console.print("\nSigned message details:")
    console.print(f"R: {signed_message.r.hex()}")
    console.print(f"S: {signed_message.s.hex()}")
    console.print(f"V: {signed_message.v}")
    console.print(f"Full signature: {signed_message.to_hex()}")

    # Verify the signature using web3.py
    recovered_address = w3.eth.account.recover_message(
        message_hash, vrs=(signed_message.v, signed_message.r, signed_message.s)
    )
    console.print("\nSignature verification:")
    console.print(f"Original address: {account.address}")
    console.print(f"Recovered address: {recovered_address}")
    console.print(f"Signature valid: {recovered_address.lower() == account.address.lower()}")

    # 2. Test Transaction Signing and Sending
    console.print("\nTesting transaction signing...")

    # First, fund the account from a test account (using Anvil's default funded account)
    funded_account = w3.eth.account.from_key("0xac0974bec39a17e36ba4a6b4d238ff944bacb478cbed5efcae784d7bf4f2ff80")

    # Send some ETH to our GCP KMS account
    fund_tx = {
        "from": funded_account.address,
        "to": account.address,
        "value": w3.to_wei(10, "ether"),
        "gas": 21000,
        "gasPrice": w3.eth.gas_price,
        "nonce": w3.eth.get_transaction_count(funded_account.address),
        "chainId": w3.eth.chain_id,
    }

    # Send funding transaction
    signed_fund_tx = w3.eth.account.sign_transaction(fund_tx, funded_account.key)
    fund_tx_hash = w3.eth.send_raw_transaction(signed_fund_tx.raw_transaction)
    fund_receipt = w3.eth.wait_for_transaction_receipt(fund_tx_hash)
    console.print(f"Funded account with 10 ETH. TX hash: {fund_receipt['transactionHash'].hex()}")

    # Now create and sign a transaction from our GCP KMS account
    tx = {
        "from": funded_account.address,
        "chain_id": w3.eth.chain_id,
        "nonce": w3.eth.get_transaction_count(account.address),
        "value": w3.to_wei(0.000001, "ether"),
        "data": "0x00",
        "to": "0xa5D3241A1591061F2a4bB69CA0215F66520E67cf",
        "type": 0,
        "gas_limit": 1000000,
        "gas_price": 300000000000,
    }

    # Sign the transaction
    signed_tx = account.sign_transaction(Transaction.from_dict(tx))
    console.print(f"{signed_tx=}")

    if signed_tx:
        console.print(signed_tx)
        # Send the transaction
        tx_hash = w3.eth.send_raw_transaction(signed_tx)
        receipt = w3.eth.wait_for_transaction_receipt(tx_hash)
        console.print("\nTransaction successful!")
        console.print(f"Transaction hash: {receipt['transactionHash'].hex()}")
        console.print(f"From: {receipt['from']}")
        console.print(f"To: {receipt['to']}")
        console.print(f"Gas used: {receipt['gasUsed']}")

        # Verify the transaction signature
        tx_data = w3.eth.get_transaction(tx_hash)
        # Get the raw transaction data
        raw_tx = signed_tx
        recovered_address = w3.eth.account.recover_transaction(raw_tx)
        console.print("\nTransaction signature verification:")
        console.print(f"Original address: {account.address}")
        console.print(f"Recovered address: {recovered_address}")
        console.print(f"Signature valid: {recovered_address.lower() == account.address.lower()}")
    else:
        console.print("Failed to sign transaction")
