<script>
    import { onMount }       from 'svelte';
    import { useTinyRouter } from 'svelte-tiny-router';

    import { dragged }       from './dragndrop.svelte.js';
    import { api }           from '../../urls.svelte.js';
    import { t }             from '../../translations.svelte.js';

    import TaskList          from './TaskList.svelte';
    import LineEditor        from '../../Components/LineEditor.svelte';

    let {
        estimated_time,
        show_closed,
        siblings,
        states = {},
        task
    } = $props();
    let children = $state(null);
    let deleted  = $state(false);
    let error    = $state(null);
    const router = useTinyRouter();
    let start    = 0;

    function addSubtask(){
        router.navigate(`/task/${task.id}/add_subtask`);
    }

    async function addTime(){
        const url  = api(`time/track_task/${task.id}`);
        const resp = await fetch(url,{credentials:'include'}); // create new time or return time with assigned tasks
        if (resp.ok) {
            const track = await resp.json();
            console.log(track);
        } else {
            error = await resp.text();
        }
    }

    async function deleteTask(){
        if (confirm(t('confirm_delete',{element:task.name}))){
            const url  = api(`task/${task.id}`);
            const resp = await fetch(url,{
                credentials : 'include',
                method      : 'DELETE'
            });
            if (resp.ok){
                deleted = true;
            } else {
                error = await resp.text();
            }
        }
    }

    function ondragstart(ev){
        ev.stopPropagation();
        dragged.element  = task;
        dragged.siblings = siblings;
    }


    async function ondrop(ev){
        ev.stopPropagation();
        if (dragged.element.id == task.id) return;
        const  url = api(`task/${dragged.element.id}`);
        const resp = await fetch(url,{
            credentials : 'include',
            method      : 'PATCH',
            body        : JSON.stringify({ parent_task_id : task.id})
        });
        if (resp.ok) {
            children[dragged.element.id]=dragged.element;
            if (dragged.siblings[dragged.element.id]) delete dragged.siblings[dragged.element.id];
        } else {
            error = await resp.text();
        }
        return false;
    }

    async function loadChildren(){
        const url  = api('task/list');
        const data = {
            parent_task_id : +task.id,
            show_closed    : show_closed
        };
        if (task.show_closed) data.show_closed = true;
        const resp = await fetch(url,{
            credentials : 'include',
            method      : 'POST',
            body        : JSON.stringify(data)
        });
        if (resp.ok){
            children = await resp.json();
            error    = null;
        } else {
            error = await resp.text();
        }
    }

    function openTask(){
        router.navigate(`/task/${task.id}/view`);
    }

    async function patchTask(changeset){
        const url  = api(`task/${task.id}`);
        const resp = await fetch(url,{
            credentials : 'include',
            method      : 'PATCH',
            body        : JSON.stringify(changeset)
        });
        if (resp.ok){
            task = await resp.json();
            return true;
        } else {
            error = await resp.text();
            return false;
        }
    }

    function setName(newName){
        patchTask({name:newName});
    }

    function map_state(tx){
        for (let [code,name] of Object.entries(states)){
            if (tx == name) return {status:+code};
        }
        return {state:0};
    }

    if (task.estimated_time){
        estimated_time.sum += task.estimated_time;
    }

    onMount(loadChildren);
</script>

{#if !deleted}
<li draggable="true" {ondrop} ondragover={e => e.preventDefault()} {ondragstart} class="task {states[task.status]?.toLowerCase()}">
    <LineEditor bind:value={task.name} onclick={openTask} editable={true} onSet={setName} type="a" />
    {#if task.estimated_time}
    <span class="estimated_time">({+task.estimated_time}&nbsp;h)</span>
    {/if}
    {#if states[task.status] != 'PENDING'}
    <button class="symbol" title={t('postpone')} onclick={() => patchTask(map_state('PENDING'))}></button>
    {/if}
    {#if states[task.status] != 'OPEN'}
    <button class="symbol" title={t('do_open')} onclick={() => patchTask(map_state('OPEN'))}></button>
    {/if}
    {#if states[task.status] != 'STARTED'}
    <button class="symbol" title={t('started')} onclick={() => patchTask(map_state('STARTED'))}></button>
    {/if}
    {#if states[task.status] != 'COMPLETE'}
    <button class="symbol" title={t('complete')} onclick={() => patchTask(map_state('COMPLETE'))}></button>
    {/if}
    {#if states[task.status] != 'CANCELLED'}
    <button class="symbol" title={t('abort')} onclick={() => patchTask(map_state('CANCELED'))} ></button>
    {/if}
    <button class="symbol" title={t('delete_task')} onclick={deleteTask} ></button>
    <button class="symbol" title={t('add_subtask')} onclick={addSubtask}></button>
    <button class="symbol" title={t('timetracking')} onclick={addTime}></button>
    {#if error}
    <span class="error">{error}</span>
    {/if}
    {#if children}
    <TaskList {states} tasks={children} {estimated_time} {show_closed} />
    {/if}
</li>
{/if}
