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

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

    import Card from './KanbanCard.svelte';

    let { id } = $props();

    let error = $state(null);
    let project = $state(null);
    let router = useTinyRouter();
    let states = $state(null);
    let tasks = $state({});
    let highlight = $state({});

    let columns = $derived(states?Object.keys(states).length+1:1);
    let dragged = null;
    let users = {};

    async function load(){
        loadProject();
        loadStates();
        await loadTasks({project_id:+id,parent_task_id:0});
    }

    async function loadProject(){
        const url = api(`project/${id}`);
        const resp = await fetch(url,{credentials:'include'});
        if (resp.ok){
            project = await resp.json();
            error = null;
        } else {
            error = await resp.text();
        }
    }

    async function loadStates(){
        const url = api(`project/${id}/states`);
        const resp = await fetch(url,{credentials:'include'});
        if (resp.ok){
            states = await resp.json();
            error = null;
        } else {
            error = await resp.text();
        }
    }

    async function loadTasks(selector){
        const url = api('task/list');
        selector.show_closed = true;
        selector.no_index = true;
        var resp = await fetch(url,{
            credentials: 'include',
            method:'POST',
            body:JSON.stringify(selector)
        });
        if (resp.ok){
            var json = await resp.json();
            for (var task_id of Object.keys(json)) {
                let task = json[task_id];
                let state = task.status.code;
                let owner = null;
                let assignee = null;
                for (var user_id of Object.keys(task.members)){
                    var member = task.members[user_id];
                    if (member.permission.name == 'OWNER') owner = user_id;
                    if (member.permission.name == 'ASSIGNEE') assignee = user_id;
                    users[user_id] = member.user.name;
                }
                if (!assignee) assignee = owner;
                task.assignee = assignee;
                if (!tasks[assignee]) tasks[assignee] = {};
                if (!tasks[assignee][state]) tasks[assignee][state] = {};
                tasks[assignee][state][task_id] = task;
            }
        } else {
            error = await resp.text();
        }
    }

    async function drop(user,state){
        let task = dragged;
        dragged = null;
        highlight = {};
        if (task.assignee == user && task.status.code == state) return; // no change
        let patch = {members:{},status:+state}
        patch.members[user] = 'ASSIGNEE';

        const url = api(`task/${task.id}`);
        const resp = await fetch(url,{
            credentials: 'include',
            method: 'PATCH',
            body: JSON.stringify(patch)
        });
        if (resp.ok){
            delete tasks[task.assignee][task.status.code][task.id]
            if (!tasks[user]) tasks[user] = {}
            if (!tasks[user][state]) tasks[user][state] = {}
            tasks[user][state][task.id] = task;
            task.assignee = user;
            task.status = {code:state,name:states[state]};
            error = null;
        } else {
            error = await resp.text();
        }
    }

    function hover(ev,user,state){
        ev.preventDefault();
        highlight = {user:user,state:state};
    }

    onMount(load);
</script>

<style>
    .box,
    .head,
    .user{
        border-radius: 5px;
        margin: 2px;
        min-height: 50px;
        color: black;
        padding: 2px;
    }
    .box{
        background: orange;
    }
    .head,
    .user{
        background: black;
        border: 1px solid orange;
        color: orange;
        text-align: center;
    }
    .highlight{
        background: #4b3000;
    }
</style>

{#if project}
<h1 onclick={ev => router.navigate(`/project/${project.id}/view`)}>{project.name}</h1>
{/if}
{#if error}
<span class="error">{error}</span>
{/if}

<div class="kanban" style="display: grid; grid-template-columns: {`repeat(${columns}, auto)`}">
    <div class="head">{t('user')}</div>
    {#if states}
    {#each Object.entries(states) as [sid,state]}
    <div class="head">{t('state_'+state.toLowerCase())}</div>
    {/each}
    {/if}
    {#each Object.entries(tasks) as [user,stateList]}
        <div class="user">{users[user]}</div>
        {#each Object.entries(states) as [state,name]}
            <div class={[state, highlight.user == user && highlight.state == state ? 'highlight':'']} ondragover={ev => hover(ev,user,state)} ondrop={ev => drop(user,state)} >
            {#if stateList[state]}
            {#each Object.values(stateList[state]).sort((a,b) => a.name.localeCompare(b.name)) as task}
                <Card onclick={() => router.navigate(`/task/${task.id}/view`)} ondragstart={ev => dragged=task} {task} />
            {/each}
            {/if}
            </div>
        {/each}
    {/each}
</div>