<script lang="ts">
	import type { Entry as EntryType, EntryKind, KnownFeeling } from "$lib/entry";
	import ExternalLink from "./utils/ExternalLink.svelte";
	import FeelingPill from "./utils/FeelingPill.svelte";
	import Entry from "./utils/Entry.svelte";
	import EntryDescription from "./utils/EntryDescription.svelte";
	import AssetPreview from "./utils/AssetPreview.svelte";
	import { createEventDispatcher } from "svelte";
	import Fuse from "fuse.js";

    let dispatch = createEventDispatcher()

    export let entries: EntryType[]
    let filteredEntries = entries
    export let filters: {
        fromDate: null | Date,
        toDate: null | Date,
        kind: null | EntryKind[],
        feelings: null | {
            exclusive: boolean,
            feelings: KnownFeeling[],
        },
        searchQuery: null | string,
    }
    let extended: string[] = []

    function applyFilters(filters: {
        fromDate: null | Date,
        toDate: null | Date,
        kind: null | EntryKind[],
        feelings: null | {
            exclusive: boolean,
            feelings: KnownFeeling[],
        },
        searchQuery: null | string,
    }) {
        filteredEntries = entries

        if (filters.fromDate != null) {
            filteredEntries = entries.filter((v) => new Date(v.creationDate) >= filters.fromDate!);
        }
        if (filters.toDate != null) {
            filteredEntries = entries.filter((v) => new Date(v.creationDate) <= filters.toDate!);
        }
        if (filters.kind != null) {
            filteredEntries = entries.filter((v) => filters.kind!.includes(v.base.kind));
        }
        if (filters.feelings != null) {
            let feelings = filters.feelings!.feelings
            if (filters.feelings.exclusive) {
                filteredEntries = entries.filter((v) => {
                    let v1 = v.feelings.filter((f) => typeof f === "string" && feelings.includes(f))
                    return v.feelings.length === v1.length;
                })
            } else {
                filteredEntries = entries.filter((v) => {
                    let includes = false
                    feelings.forEach((f) => {
                        if (v.feelings.includes(f)) {
                            includes = true
                        }
                    })

                    return includes
                })
            }
        }
        if (filters.searchQuery != null) {
            let fuse = new Fuse(entries, {
                keys: [
                    "title",
                    "description",
                ],
            });

            let results = fuse.search(filters.searchQuery!);
            filteredEntries = results.map((v) => v.item);
        }

        if (filteredEntries.length !== entries.length) {
            dispatch('updatedFilterStatus', true)
        } else {
            dispatch('updatedFilterStatus', false)
        }
    }

    $: applyFilters(filters)
</script>

{#each filteredEntries as entry (entry.id)}
    <Entry
        on:extended={(e) => extended = [e.detail.id, ...extended]}
        on:contracted={(e) => extended = extended.filter(v => v !== e.detail.id)}
        on:deleted={(e) => { dispatch('deleted', e.detail) }}

        id={entry.id}
        kind={entry.base.kind}
        creationDate={new Date(entry.creationDate)}
        title={entry.base.kind === "date" ? new Date(entry.base.referencedDate).toLocaleDateString() : entry.title}
        isExtended={extended.includes(entry.id)}
    >
        <div slot="contracted">
            {#if entry.base.kind === "song" || entry.base.kind === "album"}
                <ExternalLink href={entry.base.link[0]}>{entry.base.artist} &dash; {entry.base.title}</ExternalLink>
            {/if}

            {#if entry.base.kind === "feeling"}
                <div class="flex gap-1">
                    {#each entry.feelings as feeling}
                        {#if typeof feeling === "string"}
                            <FeelingPill feeling={feeling}/>
                        {:else}
                            <FeelingPill feeling={feeling.identifier} bgColor={feeling.backgroundColor} textColor={feeling.textColor}/>
                        {/if}
                    {/each}
                </div>
            {/if}
        </div>

        <div slot="extended">
            <div class="flex gap-1 mb-2">
                {#each entry.feelings as feeling}
                    {#if typeof feeling === "string"}
                        <FeelingPill feeling={feeling}/>
                    {:else}
                        <FeelingPill feeling={feeling.identifier} bgColor={feeling.backgroundColor} textColor={feeling.textColor}/>
                    {/if}
                {/each}
            </div>

            {#if entry.base.kind === "song" || entry.base.kind === "album"}
                <ExternalLink href={entry.base.link[0]}>{entry.base.artist} &dash; {entry.base.title}</ExternalLink>
            {/if}

            {#if entry.description != null}
                <EntryDescription>{entry.description}</EntryDescription>
            {/if}

            <div class="flex gap-1 mt-2">
                {#each entry.assets as asset}
                    <AssetPreview asset_id={asset}/>
                {/each}
            </div>
        </div>
    </Entry>
{/each}