import libtorrent as lt
import time
import os

# Global session object (consider managing this better in a full app)
ses = lt.session({'listen_interfaces': '0.0.0.0:6881'})
downloads = {}

DEFAULT_SAVE_PATH = os.path.join(os.getcwd(), 'downloads')
if not os.path.exists(DEFAULT_SAVE_PATH):
    os.makedirs(DEFAULT_SAVE_PATH)

def add_torrent(magnet_link, save_path=DEFAULT_SAVE_PATH):
    """Adds a torrent using a magnet link."""
    params = {
        'save_path': save_path,
        'storage_mode': lt.storage_mode_t(2), # storage_mode_sparse
    }
    try:
        handle = lt.add_magnet_uri(ses, magnet_link, params)
        handle.set_sequential_download(True) # Good for streaming
        downloads[handle.info_hash()] = handle
        print(f"Torrent added: {handle.name() if handle.has_metadata() else 'Fetching metadata...'}")
        return handle.info_hash()
    except Exception as e:
        print(f"Error adding torrent: {e}")
        return None

def get_status(info_hash):
    """Returns current status of a torrent"""
    if info_hash not in downloads:
        return {'error': 'Invalid info_hash'}
    
    handle = downloads[info_hash]['handle']
    status = handle.status()
    
    return {
        'progress': round(status.progress * 100, 2),
        'download_rate': status.download_rate,
        'num_peers': status.num_peers,
        'state': str(status.state).split('.')[1],
        'name': status.name,
        'total_size': status.total_wanted
    }

def get_streamable_files(info_hash):
    """Returns list of completed media files for streaming"""
    if info_hash not in downloads:
        return {'error': 'Invalid info_hash'}
    
    handle = downloads[info_hash]['handle']
    status = handle.status()
    
    if not status.is_seeding:
        return {'status': 'Download not complete'}
    
    save_path = downloads[info_hash]['save_path']
    torrent_info = handle.get_torrent_info()
    files = []
    
    for idx in range(torrent_info.num_files()):
        file_entry = torrent_info.file_at(idx)
        if file_entry.size > 0:
            files.append({
                'path': os.path.join(save_path, file_entry.path),
                'size': file_entry.size,
                'name': os.path.basename(file_entry.path)
            })
    
    return {'files': files}

def get_all_torrents_status():
    """Gets the status of all active torrents."""
    return {str(info_hash): get_torrent_status(info_hash) for info_hash in downloads.keys()}

# Example usage (can be removed or moved to app.py)
if __name__ == '__main__':
    # Replace with a real magnet link for testing
    test_magnet = "magnet:?xt=urn:btih:YOUR_TORRENT_INFO_HASH_HERE"
    info_hash = add_torrent(test_magnet)

    if info_hash:
        print(f"Added torrent with info_hash: {info_hash}")
        while True:
            status = get_torrent_status(info_hash)
            print(f"Status: {status['status']}, Progress: {status['progress']:.2f}%, Peers: {status['num_peers']}")
            if status['status'] == 'finished' or status['status'] == 'seeding':
                print("Download finished!")
                break
            time.sleep(5)
    else:
        print("Failed to add torrent.")