<script>
    import { onMount } from 'svelte';

    import { api, eventStream } from '../../urls.svelte';
    import { error, yikes } from '../../warn.svelte';
    import { t }            from '../../translations.svelte';

    import Editor      from '../../Components/MarkdownEditor.svelte';
    import Users       from '../../Components/UserSelector.svelte';
    import Tags        from '../tags/TagList.svelte';
    import Template    from './Template.svelte';

    let bookmarks    = $state(null);
	let eventSource      = null;
    let loader       = {
        offset : 0,
        limit  : 16,
        active : true
    }
    let new_bookmark = $state({
        comment:{
            source:null,
            rendered:null
        },
        tags:[],
        url:null,
        users:{}
    });

    async function getCandidates(text){
        const url  = api('user/search');
        const resp = await fetch(url,{
            credentials : 'include',
            method      : 'POST',
            body        : text
        });
        if (resp.ok){
            yikes();
            const input = await resp.json();
            return Object.values(input).map(user => {return {...user,display:user.name}});
        } else {
            error(resp);
            return {};
        }
    }

    function handleCreateEvent(evt){
        let data = JSON.parse(evt.data);
        if (data.record) bookmarks = [data.record, ...bookmarks];
    }

    function handleDeleteEvent(evt){
        let data = JSON.parse(evt.data);
        if (data.record && data.record.id) bookmarks = bookmarks.filter(b => b.id != data.record.id);
    }

    function handleUpdateEvent(evt){
        let data = JSON.parse(evt.data);
        if (data.record && data.record.id) bookmarks = bookmarks.map(b => data.record.id == b.id ? data.record : b);
    }


    function load(){
        loadBookmarks();
        eventSource = eventStream(handleCreateEvent,handleUpdateEvent,handleDeleteEvent);
    }

    async function loadBookmarks(){
        const url  = api(`bookmark/list?offset=${loader.offset}&limit=${loader.limit}`);
        const resp = await fetch(url,{credentials:'include'});
        if (resp.ok){
            const raw = await resp.json();
            let merged = bookmarks ? bookmarks : {}
            merged = { ...bookmarks , ...raw };
            bookmarks = Object.values(merged).sort((a, b) => new Date(b.timestamp) - new Date(a.timestamp));
            loader.offset += loader.limit;
            loader.active  = false;
            yikes();
            if (Object.keys(raw).length) onscroll(null); // when bookmarks were received, check whether they fill up the page
        } else {
            error(resp)
        }
    }

    async function onclick(ev){
        delete new_bookmark.comment.rendered;
        const url  = api('bookmark');
        const data = {
            comment : new_bookmark.comment.source,
            url     : new_bookmark.url,
            tags    : new_bookmark.tags
        }
        const share = Object.keys(new_bookmark.users).map(id => +id);
        if (share.length>0) data.share = share;
        const resp = await fetch(url,{
            credentials : 'include',
            method      : 'POST',
            body        : JSON.stringify(data)
        });
        if (resp.ok) {
            const bookmark = await resp.json();
            bookmarks.unshift(bookmark);
        } else {
            error(resp);
        }
    }

    function onscroll(ev){
        if (window.innerHeight + window.scrollY >= document.body.offsetHeight && !loader.active) {
            loader.active = true;
            loadBookmarks();
        }
    }

    onMount(load);
</script>

<svelte:head>
    <title>Umbrella – {t('bookmarks')}</title>
</svelte:head>

<svelte:window {onscroll} />
<fieldset>
    <legend>{t('Bookmarks')}</legend>
    <label>
        {t('URL')}
        <input bind:value={new_bookmark.url} autofocus />
    </label>
    <label>
        {t('Comment')}
        <Editor simple={true} bind:value={new_bookmark.comment} />
    </label>
    <label>
        {t('share_with')}
        <Users {getCandidates} users={new_bookmark.users} />
    </label>
    <Tags module="bookmark" bind:tags={new_bookmark.tags} />
    <button {onclick}>{t('save')}</button>
    {#if bookmarks}
    {#each bookmarks as bookmark}
    <Template {bookmark}  />
    {/each}
    {/if}
</fieldset>
