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

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

    let { task = null }     = $props();

    let candidates    = $state({});
    let key           = $state(null);
    let requiredTasks = $state({});
    let router        = useTinyRouter();
    let sortedTasks   = $derived(Object.values(candidates).sort((a, b) => a.name.localeCompare(b.name)));
    let timer         = null;

    async function add(new_task_id){
        let url = api(`task/${new_task_id}`);
        let resp = await get(url);
        if (resp.ok){
            yikes();
            let newTask = await resp.json();
            if (newTask.project_id != task.project_id){
                alert('project mismatch!');
                return;
            }
            task.required_tasks_ids.push(new_task_id);
            requiredTasks[new_task_id] = newTask;
            await update();
            delete candidates[new_task_id];
        } else {
            error(resp);
        }
    }

    async function doSearch(){
        if (!key.trim()) {
            candidates = {};
            return;
        }
        const data = { key : key, project_id : task?.project_id };
        const url = api('task/search');
        const res = await fetch(url,{
            credentials : 'include',
            method      : 'POST',
            body        : JSON.stringify(data)
        });
        if (res.ok) {
            yikes();
            candidates = await res.json();
            for (var taskId of Object.keys(requiredTasks)) delete candidates[taskId];
            delete candidates[task.id];
        } else {
            error(resp);
        }
    }

    async function loadTasks(){
        if (!task || !task.required_tasks_ids || !task.required_tasks_ids.length) return;
        const url = api('task/list');
        const res = await post(url,{ids:task.required_tasks_ids});
        if (res.ok){
            yikes();
            requiredTasks = await res.json();
        } else error(resp);
    }

    function oninput(){
        if (timer) clearTimeout(timer);
        timer = setTimeout(doSearch,1000);
    }

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

    async function update(){
            const url  = api(`task/${task.id}`);
            const resp = await patch(url,{required_tasks_ids:task.required_tasks_ids});
            if (!resp.ok) error(resp);
    }

    async function unlink(required_task){
        task.required_tasks_ids = task.required_tasks_ids.filter(item => item != required_task.id);
        update();
        delete requiredTasks[required_task.id];
    }

    onMount(loadTasks);
</script>

{#if requiredTasks}
<ul class="required task list">
    {#each Object.values(requiredTasks) as task}
    <li class="task" >
        <a href="/task/{task.id}/view" onclick={openTask} >{task.name}</a>&nbsp;<button onclick={() => unlink(task)} class="symbol"></button>
    </li>
    {/each}
</ul>
{/if}
{t('add_object',{object:t('task')})}: <input type="text" bind:value={key} {oninput} />
<div class="candidate task list">
    {#each sortedTasks as task}
    <div class="task" onclick={e => add(task.id)}>{task.name}</div>
    {/each}
</div>
