import gradio as gr
import requests
import time
from typing import Any
from communex.client import CommuneClient
from communex.balance import from_nano

netuid = 1
node_url = "wss://commune.api.onfinality.io/public-ws"

def get_com_price() -> Any:
    retries = 5
    for i in range(0, retries):
        try:
            price = float(requests.get("https://api.mexc.com/api/v3/avgPrice?symbol=COMAIUSDT").json()["price"])
            print(f"Fetched COM price: {price}")
            return price
        except Exception as e:
            print(f"Error fetching COM price: {e}")
            if i == retries - 1:
                raise
            time.sleep(retries)
    raise RuntimeError("Failed to fetch COM price")

def get_leaderboard_data():
    try:
        com_price = get_com_price()
        blocks_in_day = 10_800
        client = CommuneClient(node_url)
        emission = client.query("Emission", params=[netuid])
        scores = {}
        for uid, emi in enumerate(emission):
            scores[uid] = ((emi / 10**11) * blocks_in_day) * com_price
        
        sorted_scores = sorted(scores.items(), key=lambda x: x[1], reverse=True)
        leaderboard_data = []
        for rank, (uid, score) in enumerate(sorted_scores, start=1):
            leaderboard_data.append({"rank": rank, "uid": uid, "score": score})
        
        print(f"Leaderboard data: {leaderboard_data}")
        return leaderboard_data
    except Exception as e:
        print(f"Error fetching leaderboard data: {e}")
        return []

def update_leaderboard_table():
    leaderboard_data = get_leaderboard_data()
    return gr.components.DataFrame.update(value=leaderboard_data)

with gr.Blocks() as demo:
    gr.Markdown("# Commune Leaderboard")
    
    leaderboard_table = gr.components.DataFrame(
        headers=["rank", "uid", "score"],
        datatype=["number", "number", "number"],
        interactive=False,
        visible=True,
        elem_id="leaderboard-table"
    )
    
    refresh_button = gr.Button("Refresh Leaderboard")
    
    refresh_button.click(fn=update_leaderboard_table, outputs=leaderboard_table)
    
    # Initial load of leaderboard data
    leaderboard_data = get_leaderboard_data()
    leaderboard_table.value = leaderboard_data

if __name__ == "__main__":
    demo.launch()