"""
Real Bitcoin Mining System
Connects to actual Bitcoin network and performs real mining
"""
import sys
import os
import time
from decimal import Decimal
sys.path.append(os.path.dirname(os.path.dirname(os.path.abspath(__file__))))

from src.core.block_template import BlockTemplateGenerator
from src.mining.bitcoin_miner import BitcoinMiner
from src.network.block_submitter import BlockSubmitter
from src.hardware.gpu_manager import GPUManager
from src.utils.config import Config
from src.utils.logger import Logger
from bitcoinlib.services.services import Service

class RealBitcoinMiner:
    def __init__(self, network='bitcoin'):
        self.config = Config()
        self.logger = Logger()
        self.network = network
        
        # Initialize Bitcoin network components
        self.service = Service(network=self.network)
        self.template_generator = BlockTemplateGenerator(network=self.network)
        self.block_submitter = BlockSubmitter(network=self.network)
        self.miner = BitcoinMiner(network=self.network)
        
        # Hardware management
        self.gpu_manager = GPUManager()
        
        # Mining stats
        self.blocks_mined = 0
        self.start_time = None
        self.hash_rate = 0
        
    def start(self):
        """Start real Bitcoin mining operations"""
        try:
            self.logger.info("Initializing real Bitcoin mining system...")
            self.logger.info(f"Network: {self.network.upper()}")
            
            # Initialize GPU
            self.gpu_manager.initialize()
            self.logger.info("GPU resources initialized")
            
            # Get current network info
            self._print_network_info()
            
            # Start mining loop
            self.start_time = time.time()
            self.logger.info("Starting mining operations...")
            
            while True:
                try:
                    # Get real block template
                    template = self.template_generator.get_block_template()
                    
                    # Display current mining attempt info
                    self._print_mining_info(template)
                    
                    # Attempt to mine block
                    mined_block = self.miner.mine_block(template)
                    
                    if mined_block:
                        self.logger.info("Potential block found!")
                        # Try to submit to network
                        if self.block_submitter.submit_block(mined_block):
                            self.blocks_mined += 1
                            self.logger.info(f"Successfully mined block {mined_block['hash']}")
                            self._print_success_info(mined_block)
                            
                except Exception as e:
                    self.logger.error(f"Error in mining loop: {str(e)}")
                    time.sleep(5)  # Wait before retrying
                    
        except Exception as e:
            self.logger.error(f"Critical mining error: {str(e)}")
            sys.exit(1)
            
    def _print_network_info(self):
        """Display current Bitcoin network information"""
        try:
            # Get latest block
            latest_block = self.service.getblock(self.service.getbestblockhash())
            
            self.logger.info("\nBitcoin Network Status:")
            self.logger.info("-----------------------")
            self.logger.info(f"Current Height: {latest_block['height']:,}")
            self.logger.info(f"Network: {self.network.upper()}")
            self.logger.info(f"Current Difficulty: {latest_block['difficulty']:,.2f}")
            
            # Calculate current block reward
            halvings = latest_block['height'] // 210000
            reward = Decimal('50') / Decimal(str(2 ** halvings))
            
            self.logger.info(f"Current Block Reward: {reward} BTC")
            
        except Exception as e:
            self.logger.error(f"Error getting network info: {str(e)}")
            
    def _print_mining_info(self, template):
        """Display current mining attempt information"""
        self.logger.info("\nMining Status:")
        self.logger.info("--------------")
        self.logger.info(f"Target Height: {template['height']:,}")
        self.logger.info(f"Including Transactions: {len(template['transactions'])}")
        self.logger.info(f"Total Mining Time: {time.time() - self.start_time:.1f} seconds")
        self.logger.info(f"Blocks Found: {self.blocks_mined}")
        
    def _print_success_info(self, block):
        """Display information about successfully mined block"""
        self.logger.info("\nBlock Successfully Mined!")
        self.logger.info("------------------------")
        self.logger.info(f"Block Hash: {block['hash']}")
        self.logger.info(f"Height: {block['template']['height']:,}")
        self.logger.info(f"Transactions: {len(block['template']['transactions'])}")
        
        # Calculate reward
        halvings = block['template']['height'] // 210000
        reward = Decimal('50') / Decimal(str(2 ** halvings))
        self.logger.info(f"Block Reward: {reward} BTC")

if __name__ == "__main__":
    mining_system = MiningSystem()
    mining_system.start()
