<script lang="ts">
    import { onMount } from "svelte";
    import { ProgressBarRound } from "carbon-icons-svelte";
    import { getConfig } from "./utils/getConfig";

    interface Entry {
        name: string;
        rank: number;
        score: number;
        votes: number;
        open_source: boolean;
        displayName?: string;
    }

    export let onEntryClick: (entry: Entry) => void;
    export let showOnlyOpenSource: boolean;
    export let voteType: string = "render";

    const baseUrl = "https://huggingface.co/datasets/dylanebert/3d-arena/resolve/main/outputs";
    let leaderboard: Entry[] = [];
    let filteredLeaderboard: Entry[] = [];
    let isLoading = false;

    const fetchLeaderboardData = async () => {
        isLoading = true;
        try {
            const url = `/api/leaderboard?vote_type=${voteType}`;
            const response = await fetch(url, {
                method: "GET",
                headers: {
                    "Cache-Control": "no-cache",
                },
            });
            const data = (await response.json()) as Entry[];
            const entriesWithDisplayNames = await Promise.all(
                data.map(async (entry) => {
                    const config = await getConfig(entry.name);
                    return { ...entry, displayName: config.DisplayName || entry.name };
                }),
            );
            entriesWithDisplayNames.sort((a, b) => a.rank - b.rank);

            leaderboard = entriesWithDisplayNames;
            updateFilteredLeaderboard();
        } finally {
            isLoading = false;
        }
    };

    const updateFilteredLeaderboard = () => {
        filteredLeaderboard = showOnlyOpenSource
            ? leaderboard.filter((entry) => entry.open_source)
            : leaderboard;
    };

    $: {
        showOnlyOpenSource;
        updateFilteredLeaderboard();
    }

    $: {
        voteType;
        fetchLeaderboardData();
    }

    onMount(async () => {
        await fetchLeaderboardData();
    });
</script>

{#if isLoading}
    <div class="loading-container">
        <ProgressBarRound class="loading-icon" />
        <div class="loading-text">Loading...</div>
    </div>
{:else if filteredLeaderboard.length > 0}
    <div class="grid">
        {#each filteredLeaderboard as entry, index}
            <button class="grid-item" on:click={() => onEntryClick(entry)}>
                <img
                    src={`${baseUrl}/${entry.name}/thumbnail.png`}
                    alt={entry.name}
                    class="thumbnail"
                />
                <div class="ranking">{index + 1}</div>
                <div class="title">{entry.displayName}</div>
                <div class="score-container">
                    <div class="score">
                        <span class="label">Score:</span>
                        {entry.score}
                    </div>
                    <div class="votes">
                        <span class="label">Votes:</span>
                        {entry.votes}
                    </div>
                </div>
            </button>
        {/each}
    </div>
{:else}
    <div class="loading-container">
        <ProgressBarRound class="loading-icon" />
        <div class="loading-text">Loading...</div>
    </div>
{/if}
