<script setup lang="ts">
import * as Plot from "@observablehq/plot";
import PlotFigure from "~/components/PlotFigure";
import { useDisplay } from "vuetify";
import type { SortItem } from "@/components/ServerDbTable.vue"
import { ServerDbTable } from "#components"


const sortBy: Ref<SortItem[]> = ref([{ key: 'type', order: "asc" }])
const itemValue = ref("id");
const { width } = useDisplay();
const scaleTransform: Ref<string[]> = ref([])

const facets = ref([
    "replicon",
    "type",
    "subtype",
    "Superkingdom",
    "phylum",
    "order",
    "family",
    "genus",
    "species",
])
const availableTaxo: Ref<string[]> = ref([
    "species",
    "genus",
    "family",
    "order",
    "phylum",
    "Superkingdom"
]);
const selectedTaxoRank = ref("phylum");

const headers = ref([
    { title: "Replicon", key: "replicon" },
    {
        title: "Type",
        key: "type",
    },
    {
        title: "Subtype",
        key: "subtype",
    },
    {
        title: "Accessions",
        key: "accession_in_sys",
        sortable: false
    }
])

const fullWidth = computed(() => {
    return layoutPlot.value === 'fullwidth'
})
const computedHeaders = computed(() => {
    return [...headers.value, ...availableTaxo.value.map(taxo => {
        return {
            title: capitalize(taxo),
            key: taxo
        }
    })]
})
const { result: msResult } = useMeiliSearch('refseq')

const computedWidth = computed(() => {
    const currentWidth = fullWidth.value ? width.value : width.value / 2
    return Math.max(currentWidth, 550);
});

const allHits = ref([])
onMounted(async () => {
    const params = {
        facets: ["*"],
        filter: [],
        sort: ["type:asc"],
        limit: 500000
    }
    await getAllHits({ index: "refseq", params, query: "" })
})

async function getAllHits(params) {
    if (params.index === 'refseq') {
        console.log(params.index)
        const { data, error } = await useAsyncMeiliSearch(params)
        console.log(error.value)
        console.log(data.value)
        allHits.value = data.value
    }
}


const plotHeight = computed(() => {
    return computedWidth.value / 3;
    // return 500
});

const defaultDataTableServerProps = ref({
    showExpand: false
})

const dataTableServerProps = computed(() => {
    return {
        ...defaultDataTableServerProps.value,
        headers: computedHeaders.value,
        itemValue: itemValue.value
    }
})
const defaultBarPlotOptions = computed(() => {

    return {
        x: { label: null, tickRotate: 45, ticks: 10 },
        y: { grid: true, type: scaleType.value },
        color: { legend: true },
        width: computedWidth.value,
        height: plotHeight.value + 100,
    }
})

const computedSystemDistribution = computed(() => {
    if (toValue(msResult)?.facetDistribution?.type) {
        return Object.entries(toValue(msResult).facetDistribution.type).map(([key, value]) => {
            return {
                type: key,
                count: value
            }
        }).sort()
    } else { return [] }

})
const computedDistriSystemOptions = computed(() => {
    return {
        ...defaultBarPlotOptions.value,
        marginBottom: 100,
        marks: [
            // Plot.frame(),
            Plot.barY(
                toValue(computedSystemDistribution),
                {
                    y: "count", x: 'type', tip: true,
                    fill: "#6750a4",
                    sort: { x: "-y" },
                },

            ),
        ],
    };
});
const computedTaxonomyDistribution = computed(() => {
    if (toValue(msResult)?.facetDistribution?.[selectedTaxoRank.value]) {
        return Object.entries(toValue(msResult).facetDistribution[selectedTaxoRank.value]).map(([key, value]) => {
            return {
                [selectedTaxoRank.value]: key,
                count: value
            }
        }).sort()
    } else { return [] }

})

const computedDistriTaxoOptions = computed(() => {
    return {
        ...defaultBarPlotOptions.value,
        marginBottom: 100,
        marks: [
            Plot.barY(
                toValue(computedTaxonomyDistribution),
                {
                    y: "count",
                    x: selectedTaxoRank.value,
                    tip: true,
                    fill: "#6750a4",
                    sort: { x: "-y" },
                }
            ),
        ],
    };
});
function capitalize(name: string) {
    const [first, ...rest] = name
    return first.toUpperCase() + rest.join('').toLowerCase();
}

function namesToCollapsibleChips(names: string[]) {
    return names.filter((it) => it !== "").map(it => ({ title: it }))
}

function namesToAccessionChips(names: string[]) {
    return namesToCollapsibleChips(names).map(it => {
        return {
            ...it,
            // href: new URL(it.title, "http://toto.pasteur.cloud").toString()
        }
    })
}
const systemPanel: Ref<number> = ref(["table"])
const layoutPlot: Ref<string[]> = ref("grid")

const binPlotOptions = ref({
    marginLeft: 150,
    marginBottom: 200,
    padding: 0,
    width: 1920,
    grid: true,
    x: { tickRotate: 90, tip: true, },

    color: { scheme: "turbo", legend: true },
})

const binPlotDataOptions = computed(() => {
    return allHits.value?.hits?.length > 0 ? {
        ...binPlotOptions.value,
        color: {
            ...binPlotOptions.value.color,
            type: scaleType.value
        },
        // fy: { domain: groupSortDomain.value },
        marks: [
            Plot.cell(allHits.value?.hits ?? [], Plot.group({ fill: "count" }, { x: "type", y: selectedTaxoRank.value, tip: true, inset: 0.5, sort: { y: "fill" } })),
        ]

    } : null

})
const scaleType = ref("linear")
</script>

<template>
    <v-card flat class="mb-2" color="transparent">
        <v-card color="transparent" flat>
            <v-expansion-panels v-model="systemPanel" class="my-2" density="compact" multiple>
                <v-expansion-panel elevation="3" value="barplot">
                    <v-expansion-panel-title color="grey-lighten-4"><v-icon color="primary"
                            class="mr-2">mdi-chart-bar</v-icon>Systems - Taxonomic</v-expansion-panel-title>
                    <v-expansion-panel-text>
                        <v-card flat color="transparent">
                            <v-toolbar flat color="transparent" density="compact">
                                <v-btn-toggle v-model="layoutPlot" density="compact" rounded="false" variant="text"
                                    color="primary" mandatory class="mx-2">
                                    <v-btn icon="md:grid_view" value="grid"></v-btn>
                                    <v-btn icon="md:view_agenda" value="fullwidth"></v-btn>
                                </v-btn-toggle>
                                <v-select v-model="scaleType" class="mx-2" density="compact"
                                    :items="['linear', 'sqrt', 'symlog']" label="Scale Type" hide-details="auto"></v-select>
                                <v-select v-model="selectedTaxoRank" :items="availableTaxo" density="compact"
                                    label="Select taxonomic rank" hide-details="auto" class="mx-2"></v-select>

                            </v-toolbar>
                            <v-row align="start">
                                <v-col :cols="fullWidth ? 12 : 6">
                                    <PlotFigure :options="unref(computedDistriSystemOptions)" defer></PlotFigure>

                                </v-col>
                                <v-col :cols="fullWidth ? 12 : 6">

                                    <PlotFigure defer :options="unref(computedDistriTaxoOptions)"></PlotFigure>

                                </v-col>
                            </v-row>
                        </v-card>

                    </v-expansion-panel-text>
                </v-expansion-panel>
                <v-expansion-panel elevation="3" value="matrix">
                    <v-expansion-panel-title color="grey-lighten-4"><v-icon color="primary"
                            class="mr-2">mdi-data-matrix</v-icon>Heatmap</v-expansion-panel-title>
                    <v-expansion-panel-text>
                        <v-card flat color="transparent">
                            <v-toolbar flat color="transparent" density="compact">
                                <v-select v-model="scaleType" class="mx-2" density="compact"
                                    :items="['linear', 'sqrt', 'symlog']" label="Scale Type" hide-details="auto"></v-select>
                                <v-select v-model="selectedTaxoRank" :items="availableTaxo" density="compact"
                                    label="Select taxonomic rank" hide-details="auto" class="mx-2"></v-select>

                            </v-toolbar>
                            <PlotFigure v-if="toValue(binPlotDataOptions) !== null" :options="unref(binPlotDataOptions)"
                                defer>
                            </PlotFigure>
                        </v-card>
                    </v-expansion-panel-text>
                </v-expansion-panel>
            </v-expansion-panels>

            <ServerDbTable title="RefSeq" db="refseq" :sortBy="sortBy" :facets="facets"
                :data-table-server-props="dataTableServerProps" @refresh:search="getAllHits">
                <template #top>
                    <v-toolbar><v-toolbar-title class="text-capitalize">
                            RefSeq
                        </v-toolbar-title><v-spacer></v-spacer>

                    </v-toolbar>
                </template>
                <template #[`item.accession_in_sys`]="{ item }">
                    <CollapsibleChips :items="namesToAccessionChips(item.accession_in_sys)">
                    </CollapsibleChips>
                </template>
            </ServerDbTable>


        </v-card>

    </v-card>
</template>