<script context="module" lang="ts">
    import {writable} from 'svelte/store';
    const show_preview = writable<boolean>(false);
</script>
<script lang="ts">
    import {Checkbox, Dropdown, DropdownItem, Spinner, Table, TableBody, TableBodyCell, TableBodyRow, TableHead, TableHeadCell, Tooltip} from 'flowbite-svelte';
    import {Folder, FolderParent, DocumentBlank, ChevronSortDown} from 'carbon-icons-svelte';
    import {filesize} from 'filesize';
    import {api, changeStateFunction, download, StateE, token, rpc} from '../store';
    import LinkButton from './LinkButton.svelte';
    import DeleteModal from './DeleteModal.svelte';

    export let node: api.Node;

    let selected: number[] = [];
    let nodes: api.Node[], dirs: api.Node[], files: api.Node[], previews: {[key: number]: string|null} = {};
    let total_size: number;
    $: { nodes = node.children!; selectNone(); }
    $: dirs = nodes.filter(v => !v.file).sort((a, b) => a.name.localeCompare(b.name));
    $: files = nodes.filter(v => v.file).sort((a, b) => a.name.localeCompare(b.name));
    $: total_size = files.map(v => v.size).reduce<number>((a, b) => (a + b!), 0);
    $: {
        if ($show_preview) {
            for (const file of files) {
                if (!file.preview) continue;
                getPreview(file.id);
            }
        }
    }

    async function getPreview(node: number) {
        const resp = await rpc.FS_download_preview($token ?? '', node);
        if (resp.o == null)
            return;
        previews[node] = 'data:image/png;base64,' + resp.o;
        previews = previews;
    }

    let ctx_node: api.Node;
    let ctx_hidden = true;
    let ctx_x = 0, ctx_y = 0;
    let ctx_style: string;
    $: ctx_style = `top: ${ctx_y}px; left: ${ctx_x}px; position: fixed;`;

    function onCtxMenu(node: api.Node, e: MouseEvent) {
        e.preventDefault();
        if (!ctx_hidden)
            return ctx_hidden = true;
        ctx_x = e.pageX;
        ctx_y = e.pageY;
        ctx_node = node;
        ctx_hidden = false;
    }

    const selectAll = () => selected = nodes.map(v => v.id);
    const selectFolders = () => selected = dirs.map(v => v.id);
    const selectFiles = () => selected = files.map(v => v.id);
    const selectNone = () => selected = [];
    const downloadSelected = () => download($token ?? '', nodes.filter(v => selected.includes(v.id)));
    const deleteSelected = () => del(selected);


    const onCtxDownload = () => download($token ?? '', [ctx_node]);

    let del: (nodes: number[]) => Promise<void>;
    const onCtxDelete = () => del([ctx_node.id]);

    const onShowPreview = (e: Event) => { show_preview.set((e.target as HTMLInputElement).checked); }
</script>

<svelte:body on:click={() => (ctx_hidden = true)} />

<DeleteModal bind:del={del} />

<Table hoverable>
    <TableHead theadClass="text-xs">
        <TableHeadCell class="p-2 pl-4 w-0 h-0">
            <ChevronSortDown id="dropdown-button" />
        </TableHeadCell>
        <TableHeadCell class="p-2 w-0"><Checkbox checked={$show_preview} on:change={onShowPreview} /><Tooltip>Show image previews</Tooltip></TableHeadCell>
        <TableHeadCell>Name</TableHeadCell>
        <TableHeadCell>Size</TableHeadCell>
    </TableHead>
    <TableBody>
        {#if node.parent !== null}
            <TableBodyRow>
                <TableBodyCell class="!p-4"></TableBodyCell>
                <TableBodyCell class="px-2 w-0"><FolderParent /></TableBodyCell>
                <TableBodyCell class="pl-0"><LinkButton on:click={changeStateFunction(StateE.VIEW, node.parent ?? 0)}>..</LinkButton></TableBodyCell>
                <TableBodyCell></TableBodyCell>
            </TableBodyRow>
        {/if}
        {#each dirs as node}
            <TableBodyRow on:contextmenu={onCtxMenu.bind(null, node)}>
                <TableBodyCell class="p-2 pl-4 w-0 h-0"><Checkbox bind:group={selected} value={node.id}/></TableBodyCell>
                <TableBodyCell class="px-2 w-0"><Folder /></TableBodyCell>
                <TableBodyCell class="pl-0"><LinkButton on:click={changeStateFunction(StateE.VIEW, node.id)}>{node.name}</LinkButton></TableBodyCell>
                <TableBodyCell></TableBodyCell>
            </TableBodyRow>
        {/each}
        {#each files as node}
            <TableBodyRow on:contextmenu={onCtxMenu.bind(null, node)}>
                <TableBodyCell class="p-2 pl-4 w-0 h-0"><Checkbox bind:group={selected} value={node.id}/></TableBodyCell>
                <TableBodyCell class="px-2 min-w-0">
                    {#if $show_preview && node.preview}
                        {#if previews[node.id] !== undefined}
                            <img class="w-screen max-w-xs" alt="preview" src={previews[node.id]} />
                        {:else}
                            <Spinner size="4"/>
                        {/if}
                    {:else}
                        <DocumentBlank />
                    {/if}
                </TableBodyCell>
                <TableBodyCell class="pl-0"><LinkButton on:click={changeStateFunction(StateE.VIEW, node.id)}>{node.name}</LinkButton></TableBodyCell>
                <TableBodyCell>{filesize(node.size ?? 0, {base: 2, standard: 'jedec'})}</TableBodyCell>
            </TableBodyRow>
        {/each}
    </TableBody>
    <tfoot class="text-gray-700 bg-gray-50">
        <tr>
            <td class="px-6 py-3" colspan="3">
                {#if selected.length > 0}
                    <LinkButton on:click={downloadSelected}>Download</LinkButton>
                    <LinkButton color="red" on:click={deleteSelected}>Delete</LinkButton>
                {/if}
            </td>
            <td class="px-6 py-3">{filesize(total_size, {base: 2, standard: 'jedec'})}</td>
        </tr>
    </tfoot>
</Table>

<Dropdown triggeredBy="#dropdown-button" trigger="hover" placement="left">
    <DropdownItem on:click={selectAll}>Select all</DropdownItem>
    <DropdownItem on:click={selectFolders}>Select folders</DropdownItem>
    <DropdownItem on:click={selectFiles}>Select files</DropdownItem>
    <DropdownItem on:click={selectNone}>Select none</DropdownItem>
</Dropdown>

<!-- svelte-ignore a11y-no-static-element-interactions -->
<div style={ctx_style} hidden={ctx_hidden} class="z-50 shadow-md rounded-lg border-gray-100 bg-white" on:contextmenu={() => (ctx_hidden = true)}>
    <ul class="py-1">
        <li><button class="font-medium py-2 px-4 text-sm hover:bg-gray-100 w-full text-left" on:click={onCtxDownload}>Download</button></li>
        <li><button class="font-medium py-2 px-4 text-sm hover:bg-gray-100 text-red-400 w-full text-left" on:click={onCtxDelete}>Delete</button></li>
    </ul>
</div>
