<script lang="ts">
    import type FileViewState from "../models/FileViewState.svelte";
    import type Primitive from "../models/Primitive.svelte";
    import PrimitiveIcon from "./PrimitiveIcon.svelte";
    import { Pane, Splitpanes } from "svelte-splitpanes";
    import StreamDataView from "./StreamDataView.svelte";

    const cellH = 29;
    const headerOffset = 24;
    let { fState, height }: { fState: FileViewState; height: number } =
        $props();
    let fillerHeight: number = $state(0);
    let firstEntry = $state(0);
    let lastEntry = $state(100);
    let scrollY = $state(0);
    let prim = $derived(fState.container_prim);
    let entriesToDisplay: Primitive[] = $derived(
        prim ? prim.children.slice(firstEntry, lastEntry) : [],
    );
    let tableHeight = $derived(prim ? prim.children.length * cellH : 0);

    let bodyHeight = $derived(height);

    let locallySelected: Primitive | undefined = $state(undefined);
    $effect(() => {
        locallySelected = fState.selected_leaf_prim;
    });

    function handlePrimClick(prim: Primitive) {
        locallySelected = prim;
        if (!prim.isContainer()) {
            handlePrimDbLClick(prim);
        }
    }

    function handleScroll(event: Event & { currentTarget: HTMLElement }) {
        scrollY = event.currentTarget.scrollTop;
        firstEntry = Math.floor(scrollY / cellH);
        lastEntry = Math.ceil((scrollY + bodyHeight) / cellH);

        fillerHeight = firstEntry * cellH;
    }

    function handlePrimDbLClick(prim: Primitive) {
        const _path: string[] = fState.copyPath();
        _path.push(prim.key);
        fState.selectPath(_path);
    }
</script>

<Splitpanes theme="forge-movable">
    <Pane minSize={1}>
        {#if prim && prim.children && prim.children.length > 0}
            <div
                class="overflow-auto"
                onscroll={handleScroll}
                style="height: {bodyHeight}px"
            >
                <div class="w-[851px]">
                    <table style="position: relative; top: {scrollY}px">
                        <thead>
                            <tr>
                                <td class="page-cell t-header border-forge-prim"
                                    >Key
                                </td>
                                <td class="ref-cell t-header border-forge-prim"
                                    >Type
                                </td>
                                <td class="cell t-header border-forge-sec"
                                    >Value</td
                                >
                            </tr>
                        </thead>
                    </table>
                    <div class="container" style="height: {tableHeight}px">
                        <table>
                            <tbody>
                                <tr
                                    class="filler"
                                    style="height: {fillerHeight}px"
                                ></tr>
                                {#each entriesToDisplay as entry, index (index)}
                                    <tr
                                        class:selected={entry.key ===
                                            locallySelected?.key}
                                        class="row"
                                        onclick={() => handlePrimClick(entry)}
                                        ondblclick={() =>
                                            handlePrimDbLClick(entry)}
                                    >
                                        <td class="page-cell t-data">
                                            <div class="key-field">
                                                <PrimitiveIcon
                                                    ptype={entry.ptype}
                                                />
                                                <p class="text-left">
                                                    {entry.key}
                                                </p>
                                            </div>
                                        </td>
                                        <td class="ref-cell t-data"
                                            >{entry.ptype}</td
                                        >
                                        <td class="cell t-data"
                                            >{entry.value}</td
                                        >
                                    </tr>
                                {/each}
                            </tbody>
                        </table>
                    </div>
                </div>
            </div>
        {/if}
    </Pane>
    <Pane
        size={fState.container_prim?.stream_data ? 50 : 0}
        minSize={fState.container_prim?.stream_data ? 1 : 0}
        maxSize={fState.container_prim?.stream_data ? 100 : 0}
    >
        <div style:height class="bg-forge-dark">
            {#if fState.container_prim?.stream_data}
                <StreamDataView {fState} {height}></StreamDataView>
            {/if}
        </div>
    </Pane>
</Splitpanes>

<style lang="postcss">
    .key-field {
        display: flex;
        flex-direction: row;
        align-items: center;
        gap: 3px;
    }

    .row {
        @apply hover:bg-forge-sec hover:border-forge-bound;
        height: 29px;
        min-height: 29px;
        max-height: 29px;
    }

    .selected {
        @apply bg-forge-acc;
    }

    .t-header {
        @apply uppercase text-xs text-forge-text p-5 bg-forge-sec border-r;
        cursor: default;
    }

    .t-data {
        @apply border border-forge-sec text-sm text-forge-text text-left;
        text-align: left;
        cursor: default;
    }

    .cell {
        @apply min-w-[600px] w-[600px] p-1 m-0;
        user-select: none;
    }

    .ref-cell {
        @apply min-w-[100px] w-[100px] p-1 m-0;
        user-select: none;
    }

    .page-cell {
        @apply min-w-[150px] w-[150px] p-1 m-0;
        user-select: none;
    }
</style>
