<script lang="ts">
    import { onMount } from "svelte";
    import SvelteTable, { type TableColumn } from "svelte-table";
    import Row from "./Row";
    import { fetchRows } from "./bridge";
    import { statusMessage } from "./store";
    import SearchButtonComponent from "./SearchButtonComponent.svelte";

    let rows: Row[] = [];
    let columns: TableColumn<Row>[] = [
        {
            key: "Name",
            title: "Name",
            value: (v: Row) => v.Name || v.Project || v.Code || v.Paper || "N/A",
            sortable: true,
            renderValue: (v: Row) => {
                let url;
                if (v.Project) {
                    url = v.Project;
                } else if (v.Code) {
                    url = v.Code;
                } else if (v.Paper) {
                    url = v.Paper;
                } else if (v.Space) {
                    url = v.Space;
                } else if (v.Model) {
                    url = v.Model;
                } else if (v.Dataset) {
                    url = v.Dataset;
                }
                let name = v.Name || url || "";
                let renderName = name;
                if (name.length > 64) {
                    renderName = name.slice(0, 60) + "...";
                }
                return `<a href="${url}" target="_blank" title="${name}">${renderName}</a>`;
            },
            searchValue: (v: Row) => {
                let searchValue = v.Name || "";
                if (v.Project) {
                    searchValue += " " + v.Project;
                }
                if (v.Code) {
                    searchValue += " " + v.Code;
                }
                if (v.Paper) {
                    searchValue += " " + v.Paper;
                }
                if (v.Space) {
                    searchValue += " " + v.Space;
                }
                if (v.Model) {
                    searchValue += " " + v.Model;
                }
                if (v.Dataset) {
                    searchValue += " " + v.Dataset;
                }
                return searchValue;
            },
            parseHTML: true,
            hideFilterHeader: true,
        },
        {
            key: "Search",
            title: "",
            value: (v: Row) => "",
            sortable: false,
            renderComponent: SearchButtonComponent,
            hideFilterHeader: true,
        },
        {
            key: "Date",
            title: "Date",
            value: (v: Row) => v.Date || "",
            sortable: true,
            searchValue: (v: Row) => v.Date || "",
            renderValue: (v: Row) => {
                if (!v.Date) return "";
                let renderDate = v.Date;

                // Convert ISO to YYYY-MM-DD
                if (v.Date.includes("T")) {
                    renderDate = v.Date.split("T")[0];
                }

                return `<span title="${v.Date}">${renderDate}</span>`;
            },
            parseHTML: true,
        },
        {
            key: "Authors",
            title: "Authors",
            value: (v: Row) => v.Authors.join(", "),
            sortable: true,
            searchValue: (v: Row) => v.Authors.join(" "),
            renderValue: (v: Row) => {
                let authors = v.Authors.join(", ");
                let renderAuthors = v.Authors.join(", ");
                if (authors.length > 24) {
                    renderAuthors = renderAuthors.slice(0, 20) + "...";
                }
                return `<span title="${authors}">${renderAuthors}</span>`;
            },
            parseHTML: true,
        },
        {
            key: "Paper",
            title: "Paper",
            value: (v: Row) => v.Paper || "",
            sortable: true,
            searchValue: (v: Row) => v.Paper || "",
            renderValue: (v: Row) => {
                if (!v.Paper) return "";
                const url = v.Paper;
                let name = v.Paper;
                if (url.includes("arxiv.org/")) {
                    name = `arxiv/${url.split("arxiv.org/")[1]}`;
                } else if (url.includes("huggingface.co/papers/")) {
                    name = `hf/${url.split("huggingface.co/papers/")[1]}`;
                }
                let displayName = name.replace(".pdf", "");
                if (displayName.length > 24) {
                    displayName = displayName.slice(0, 20) + "...";
                }
                return `<a href="${url}" target="_blank" title="${name}">${displayName}</a>`;
            },
            parseHTML: true,
        },
        {
            key: "Code",
            title: "Code",
            value: (v: Row) => v.Code || "",
            sortable: true,
            searchValue: (v: Row) => v.Code || "",
            renderValue: (v: Row) => {
                let codeUrl;
                let codeDisplay;
                if (v.Code) {
                    codeUrl = v.Code;
                    if (v.Code.includes("github.com")) {
                        codeDisplay = `gh/${v.Code.split("github.com/")[1].slice(0, 16)}`;
                    } else {
                        codeDisplay = v.Code.slice(0, 16) + "...";
                    }
                }
                if (!codeDisplay) {
                    return "";
                }
                if (codeUrl) {
                    return `<a href="${codeUrl}" target="_blank" title="${codeUrl}">${codeDisplay}</a>`;
                }
                return codeDisplay;
            },
            parseHTML: true,
        },
        {
            key: "License",
            title: "License",
            value: (v: Row) => v.License || "",
            sortable: true,
            searchValue: (v: Row) => v.License || "",
            renderValue: (v: Row) => {
                if (!v.License) return "";

                let displayLicense = v.License;
                if (v.License.length > 24) {
                    displayLicense = v.License.slice(0, 20) + "...";
                }

                return `<span title="${v.License}">${displayLicense}</span>`;
            },
            parseHTML: true,
        },
        {
            key: "Space",
            title: "Space",
            value: (v: Row) => v.Space || "",
            sortable: true,
            searchValue: (v: Row) => v.Space || "",
            renderValue: (v: Row) => {
                if (!v.Space) return "";
                if (v.Space.includes("huggingface.co")) {
                    return `<a href="${v.Space}" target="_blank">hf/${v.Space.split("huggingface.co/")[1].slice(
                        0,
                        16
                    )}</a>`;
                }
                return `<a href="${v.Space}" target="_blank" title="${v.Space}">${v.Space.slice(0, 16)}...</a>`;
            },
            parseHTML: true,
        },
        {
            key: "Model",
            title: "Model",
            value: (v: Row) => v.Model || "",
            sortable: true,
            searchValue: (v: Row) => v.Model || "",
            renderValue: (v: Row) => {
                if (!v.Model) return "";
                if (v.Model.includes("huggingface.co")) {
                    return `<a href="${v.Model}" target="_blank">hf/${v.Model.split("huggingface.co/")[1].slice(
                        0,
                        16
                    )}</a>`;
                }
                return `<a href="${v.Model}" target="_blank" title="${v.Model}">${v.Model.slice(0, 16)}...</a>`;
            },
            parseHTML: true,
        },
        {
            key: "Dataset",
            title: "Dataset",
            value: (v: Row) => v.Dataset || "",
            sortable: true,
            searchValue: (v: Row) => v.Dataset || "",
            renderValue: (v: Row) => {
                if (!v.Dataset) return "";
                if (v.Dataset.includes("huggingface.co")) {
                    return `<a href="${v.Dataset}" target="_blank">hf/${v.Dataset.split("huggingface.co/")[1].slice(
                        0,
                        16
                    )}</a>`;
                } else if (v.Dataset.includes("drive.google.com")) {
                    return `<a href="${v.Dataset}" target="_blank">drive/${v.Dataset.split(
                        "drive.google.com/"
                    )[1].slice(0, 16)}</a>`;
                } else if (v.Dataset.includes("github.com")) {
                    return `<a href="${v.Dataset}" target="_blank">gh/${v.Dataset.split("github.com/")[1].slice(
                        0,
                        16
                    )}</a>`;
                }
                return `<a href="${v.Dataset}" target="_blank" title="${v.Dataset}">${v.Dataset.slice(0, 16)}...</a>`;
            },
            parseHTML: true,
        },
    ];

    let selection: Record<string | number, any> = {};
    let overrideSelection = false;
    let searchValue = "";

    let sortBy: string = "Date";
    let sortOrder: 1 | -1 | 0 = -1;

    $: {
        if (searchValue !== "") {
            selection = { Name: searchValue };
            overrideSelection = true;
        } else {
            if (overrideSelection) {
                selection = {};
                overrideSelection = false;
            }
        }
    }

    async function refreshRows() {
        fetching = true;
        try {
            const fetchedRows = await fetchRows();
            rows = fetchedRows || [];
        } catch (error) {
            console.error(error);
        } finally {
            fetching = false;
        }
    }

    onMount(() => {
        refreshRows();
    });

    let fetching = false;
</script>

{#if fetching}
    <div style="text-align: center; margin-top: 1rem;">
        <p>{@html $statusMessage}</p>
    </div>
{:else}
    <!--spacer-->
    <div style="height: 1rem;" />

    <SvelteTable {columns} {rows} bind:sortBy bind:sortOrder bind:filterSelections={selection} />
{/if}

<style>
    :global(td) {
        border-top: 1px solid #e0e0e0;
    }
</style>
