import gradio as gr

__all__ = ["block", "make_clickable_model", "make_clickable_user", "get_submissions"]


import numpy as np
import pandas as pd

from constants import *
from src.auto_leaderboard.model_metadata_type import ModelType

global data_component, filter_component, ref_dic


def upload_file(files):
    file_paths = [file.name for file in files]
    return file_paths


def read_xlsx_leaderboard():
    df_dict = pd.read_excel(XLSX_DIR, sheet_name=None)  # get all sheet
    return df_dict


def get_specific_df(sheet_name):
    df = read_xlsx_leaderboard()[sheet_name].sort_values(by="Overall", ascending=False)
    return df

def get_link_df(sheet_name):
    df = read_xlsx_leaderboard()[sheet_name]
    return df


ref_df = get_link_df("main")

ref_dic = {}
for id, row in ref_df.iterrows():
    
    ref_dic[
        str(row["Model"])
    ] = f'<a href="{row["Link"]}" target="_blank"  style="color: var(--link-text-color); text-decoration: underline;text-decoration-style: dotted;">{row["Model"]}</a>'

def wrap_model(func):
    def wrapper(*args, **kwargs):
        df = func(*args, **kwargs)
        df["Model"] = df["Model"].apply(lambda x: ref_dic[x])
        # cols_to_round = df.select_dtypes(include=[np.number]).columns.tolist()
        # cols_to_round = [col for col in cols_to_round if col != "Model"]
        # df[cols_to_round] = df[cols_to_round].apply(lambda x: np.round(x, 2))

        all_cols = df.columns.tolist()
        non_numeric_cols = df.select_dtypes(exclude=[np.number]).columns.tolist()
        cols_to_round = [col for col in all_cols if col not in non_numeric_cols and col != "Model"]
        df[cols_to_round] = df[cols_to_round].apply(lambda x: np.round(x, 2))
        return df

    return wrapper


@wrap_model
def get_base_zh_df():
    return get_specific_df("base-zh")


@wrap_model
def get_base_en_df():
    return get_specific_df("base-en")


@wrap_model
def get_attack_zh_df():
    return get_specific_df("attack-zh")


@wrap_model
def get_attack_en_df():
    return get_specific_df("attack-en")


def build_leaderboard(
    TABLE_INTRODUCTION, TAX_COLUMNS, get_chinese_df, get_english_df
):

    gr.Markdown(TABLE_INTRODUCTION, elem_classes="markdown-text")
    data_spilt_radio = gr.Radio(
        choices=["Chinese", "English"],
        value="Chinese",
        label=SELECT_SET_INTRO,
    )

    # 创建数据帧组件
    data_component = gr.components.Dataframe(
        value=get_chinese_df,
        headers=OVERALL_INFO + TAX_COLUMNS,
        type="pandas",
        datatype=["markdown"] + ["number"] + ["number"] * len(TAX_COLUMNS),
        interactive=False,
        visible=True,
        wrap=True,
        column_widths=[250] + [100] + [150] * len(TAX_COLUMNS),
    )

    def on_data_split_radio(seleted_split):
        if "Chinese" in seleted_split:
            updated_data = get_chinese_df()
        if "English" in seleted_split:
            updated_data = get_english_df()
        current_columns = data_component.headers  # 获取的当前的column
        current_datatype = data_component.datatype  # 获取当前的datatype
        filter_component = gr.components.Dataframe(
            value=updated_data,
            headers=current_columns,
            type="pandas",
            datatype=current_datatype,
            interactive=False,
            visible=True,
            wrap=True,
            column_widths=[250] + [100] + [150] * (len(current_columns) - 2),
        )
        return filter_component

    # 关联处理函数
    data_spilt_radio.change(
        fn=on_data_split_radio, inputs=data_spilt_radio, outputs=data_component
    )


def build_demo():
    block = gr.Blocks()

    with block:
        gr.Markdown(LEADERBOARD_INTRODUCTION)

        with gr.Tabs(elem_classes="tab-buttons") as tabs:
            # first
            with gr.TabItem(
                "Base Risk Prompt Set Results",
                elem_id="evalcrafter-benchmark-tab-table",
                id=0,
            ):
                build_leaderboard(
                    TABLE_INTRODUCTION_1,
                    risk_topic_1_columns,
                    get_base_zh_df,
                    get_base_en_df
                )
            # second
            with gr.TabItem(
                "Attack Prompt Set Results",
                elem_id="evalcrafter-benchmark-tab-table",
                id=1,
            ):
                build_leaderboard(
                    TABLE_INTRODUCTION_2,
                    attack_columns,
                    get_attack_zh_df,
                    get_attack_en_df
                )
            # last table about
            with gr.TabItem("📝 About", elem_id="evalcrafter-benchmark-tab-table", id=3):
                gr.Markdown(LEADERBORAD_INFO, elem_classes="markdown-text")

        with gr.Row():
            with gr.Accordion("📙 Citation", open=True):
                citation_button = gr.Textbox(
                    value=CITATION_BUTTON_TEXT,
                    label=CITATION_BUTTON_LABEL,
                    lines=10,
                    elem_id="citation-button",
                    show_label=True,
                    show_copy_button=True,
                )

    # block.launch(share=True)
    block.launch()

if __name__ == "__main__":
    build_demo()