"""
Real Bitcoin reward processing and coinbase transaction creation
"""
import struct
import hashlib
from typing import Dict, Any
from bitcoinlib.services.services import Service
from bitcoinlib.transactions import Transaction

class BitcoinRewardProcessor:
    def __init__(self, network='bitcoin'):
        self.service = Service(network=network)
        
    def create_coinbase_transaction(self, 
                                  block_height: int,
                                  miner_address: str,
                                  extra_fees: int = 0) -> bytes:
        """
        Create a real coinbase transaction that pays mining reward to your address
        
        Args:
            block_height: Current block height (required by BIP34)
            miner_address: Your Bitcoin address to receive the reward
            extra_fees: Additional transaction fees from block
        
        Returns:
            Raw coinbase transaction bytes ready for inclusion in block
        """
        # 1. Calculate current block reward
        base_reward = self.calculate_block_reward(block_height)
        total_reward = base_reward + extra_fees  # Add transaction fees
        
        # 2. Create coinbase transaction
        tx = Transaction(network='bitcoin')
        
        # 3. Add coinbase input (special case - creates new bitcoins)
        coinbase_script = (
            # BIP34: Block height in script
            struct.pack('<I', block_height) +
            # You can add extra data here (like pool name, messages, etc)
            b'/Mined by Your Miner/'
        )
        
        tx.add_input(
            prev_hash='0' * 64,  # Coinbase has no previous output
            output_n=0xFFFFFFFF, # Special value for coinbase
            unlocking_script=coinbase_script.hex()
        )
        
        # 4. Add output paying reward to your address
        tx.add_output(
            amount=total_reward,  # In satoshis
            address=miner_address  # Your address receives the reward
        )
        
        return bytes.fromhex(tx.raw_hex())
        
    def calculate_block_reward(self, height: int) -> int:
        """
        Calculate correct block reward based on current height
        
        Returns reward in satoshis
        """
        halvings = height // 210000  # Halving every 210000 blocks
        if halvings >= 64:  # Max halvings (year ~2140)
            return 0
            
        # Start with 50 BTC reward (in satoshis)
        reward = 800 * 100000000
        
        # Divide by 2 for each halving that's occurred
        reward >>= halvings
        
        return reward
        
    def verify_reward(self, 
                     coinbase_tx: bytes,
                     block_height: int,
                     miner_address: str) -> bool:
        """
        Verify coinbase transaction is valid and pays to correct address
        """
        try:
            # 1. Parse transaction
            tx = Transaction.import_raw(coinbase_tx.hex())
            
            # 2. Verify basic coinbase structure
            if not self._verify_coinbase_structure(tx, block_height):
                return False
                
            # 3. Verify reward amount is correct
            expected_reward = self.calculate_block_reward(block_height)
            if tx.outputs[0].value > expected_reward:
                print("Invalid reward amount!")
                return False
                
            # 4. Verify reward goes to correct address
            if tx.outputs[0].address != miner_address:
                print("Reward goes to wrong address!")
                return False
                
            return True
            
        except Exception as e:
            print(f"Error verifying reward: {str(e)}")
            return False
            
    def _verify_coinbase_structure(self, tx: Transaction, height: int) -> bool:
        """Verify coinbase follows consensus rules"""
        try:
            # Must have exactly one input
            if len(tx.inputs) != 1:
                return False
                
            # Input must be coinbase (null prev_hash)
            if tx.inputs[0].prev_hash != '0' * 64:
                return False
                
            # Must include block height (BIP34)
            script = bytes.fromhex(tx.inputs[0].unlocking_script)
            script_height = struct.unpack('<I', script[:4])[0]
            if script_height != height:
                return False
                
            return True
            
        except Exception:
            return False
            
    def check_block_confirmation(self, block_hash: str) -> Dict[str, Any]:
        """
        Check if a block (and its reward) has been confirmed
        """
        try:
            block = self.service.getblock(block_hash)
            
            return {
                'confirmed': block['confirmations'] >= 6,
                'confirmations': block['confirmations'],
                'reward_mature': block['confirmations'] >= 10,  # Mining rewards need 100 confirmations
                'block_height': block['height']
            }
            
        except Exception as e:
            print(f"Error checking confirmation: {str(e)}")
            return {
                'confirmed': False,
                'confirmations': 0,
                'reward_mature': False,
                'block_height': None
            }
