<script>
    import { onMount }       from 'svelte';
    import { useTinyRouter } from 'svelte-tiny-router';
    import { api, eventStream, get } from '../../urls.svelte';
    import { error, yikes }  from '../../warn.svelte';
    import { t }             from '../../translations.svelte';
    import { user }          from '../../user.svelte';

    import MarkdownEditor    from '../../Components/MarkdownEditor.svelte';
    import LineEditor        from '../../Components/LineEditor.svelte';
    import Notes             from '../notes/RelatedNotes.svelte';
    import PermissionEditor  from '../../Components/PermissionEditor.svelte';
    import TagList           from '../tags/TagList.svelte';

    let detail = $state(false);
	let eventSource      = null;
    let { key, version } = $props();
    let page = $state({});
    let router = useTinyRouter();
    let members = $state({});
    let editable = $derived(page.members[user.id].permission.code<4);

    async function addMember(entry){
        let newMembers = JSON.parse(JSON.stringify(page.members));
        let id = entry.id;
        if (!newMembers[id]) newMembers[id] = { permission : {name:'READ_ONLY'} };
        return patch({members:newMembers});
    }

    function connectToBus(){
		eventSource = eventStream(null,handleUpdateEvent,null);
    }

    async function dropMember(member){
        var id = member.user.id;
        let newMembers = JSON.parse(JSON.stringify(page.members));
        newMembers[id].permission = null;
        return patch({members:newMembers});
    }

    async function dropVersion(){
        const msg = t('confirm_delete',{element:t('version_of',{version:page.version,element:page.title})});
        if (!confirm(msg)) return;
        let url = api(`wiki/page/${key}/version/${page.version}`);
        let res = await fetch(url,{
            credentials:'include',
            method: 'DELETE'
        });
        if (res.ok){
            let json = await res.json();
            let target = `/wiki/${page.id}/view`;
            if (window.location.pathname == target) {
                loadPage();
            } else {
                router.navigate(target);
                yikes();
            }
        } else {
            error(res);
        }
    }

    function handleUpdateEvent(evt){
        let json = JSON.parse(evt.data);
        if (json.wikipage) loadContent(json.wikipage);
    }

    function nonMember(json){
        return !page.members[json.id];
    }

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

    function loadContent(json){
        json.versions.sort((a,b)=>b-a);
        page = { ...json };
    }

    async function loadJson(res){
        if (res.ok){
            let json  = await res.json();
            loadContent(json);
            yikes();
            return true;
        } else {
            error(res);
            return false;
        }
    }

    async function loadPage(){
        let path = `wiki/page/${key}`;
        if (version) path += `/version/${version}`;
        const url = api(path);
        const res = await get(url);
        loadJson(res);
    }

    function onclick(e){
        e.preventDefault();
        let href = e.target.getAttribute('href');
        if (href) router.navigate(href);
        return false;
    }

    async function patch(data){
        const url = api(`wiki/page/${page.id}`);
        const res = await fetch(url,{
            credentials:'include',
            method:'PATCH',
            body:JSON.stringify(data)
        });
        return loadJson(res);
    }

    async function patchGuestPermissions(ev){
        let data = {guest_allowed:page.guest_allowed};
        console.log(data);
        return patch(data);
    }

    async function patchTitle(t){
        var result = await(patch({title:t}));
        router.navigate(`/wiki/${page.id}/view`);
    }

    function toggleDetail(){
        detail = !detail;
    }

    async function updatePermission(uid, newPerm){
        let newMembers = JSON.parse(JSON.stringify(page.members));
        newMembers[uid] = {permission:newPerm};
        return patch({members:newMembers});
    }

    $effect(loadPage);
	onMount(connectToBus);
</script>

<svelte:head>
    <title>Umbrella – {t('wiki')}: {page?.title}</title>
</svelte:head>

{#if page && page.versions}
<div class="wiki page">
    <div class="versions">
        <span class="version">{t('version')}</span>
        {#each page.versions as v}
        <span class="version">
            <a href={`/wiki/${page.id}/version/${v}`} {onclick} class={page.version == v?'selected':''}>{v}</a>    &nbsp;
        </span>
        {/each}
    </div>
    <LineEditor value={page.title} wrapper="h2" {editable} onSet={t => patchTitle(t)} />
    {#if page.version != page.versions[0]}
    <span class="warn">{t('not_recent_version')}</span>
    {/if}
    <button onclick={toggleDetail} class="symbol" title={t('toggle_objects',{objects:t('users')})}></button>
    <button onclick={dropVersion} class="symbol" title={t('delete_object',{object:t('version')})}> </button>
    {#if detail}
    {#if editable}
    <PermissionEditor members={page.members} {addMember} {dropMember} {getCandidates} {updatePermission} />
    <label>
        <input type="checkbox" bind:checked={page.guest_allowed} onchange={patchGuestPermissions} />
        {t('visible_to_guests')}
    </label>
    {:else}
    <table>
        <thead>
        <tr>
            <th>{t('user')}</th>
            <th>{t('permissions')}</th>
        </tr>
        </thead>
        <tbody>
        {#each Object.values(page.members) as member,id}
        <tr>
            <td>{member.user.name}</td>
            <td>{t('permission_'+member.permission.name.toLowerCase())}</td>
        </tr>
        {/each}
        </tbody>
    </table>
    {/if}
    {/if}
    <MarkdownEditor {editable} value={page.content} onSet={s => patch({content:s})} store_id="wiki/{page.id}/description" />
    <div class="tags">
        <h3>{t('tags')}</h3>
        <TagList module="wiki" id={page.id} user_list={Object.keys(page.members).map(id => +id)} />
    </div>
    <div class="notes">
        <h3>{t('notes')}</h3>
        <Notes module="wiki" entity_id={page.id} />
    </div>
</div>
{/if}
