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

    const image_extensions = ['jpg','jpeg','gif','png','svg','webp'];
    const router = useTinyRouter();
    let children = $state({});

    let new_dir = $state(null);
    let files = $state();
    let parent = $state(false);
    let form = $state(false);
    let path = $state(null);
    let delete_allowed = $state(false);
    let available = $derived.by(isAvailable);

    async function create_dir(ev){
        ev.preventDefault();
        ev.stopPropagation();
        const url = api('files'+path+'/'+new_dir);
        const res = await fetch(url,{
            credentials: 'include',
            method: 'POST'
        });
        if (res.ok) {
            handleDirectory(res);
            new_dir = null;
        } else {
            error(res);
        }
        return false;
    }

    function dropDir(p,name){
        if (confirm(t('confirm_delete',{element:name})+"\n\n"+t('deletes_nested'))) dropElement(p);
    }


    async function dropElement(url){
        const res = await fetch(url,{
            credentials: 'include',
            method: 'DELETE'
        });
        if (res.ok) {
            handleDirectory(res);
        } else {
            error(res);
        }
    }

    function dropFile(p,name){
        if (confirm(t('confirm_delete',{element:name}))) dropElement(p);
    }

    async function handleDirectory(res){
        let json = await res.json();
        children.dirs  = json.dirs  ? val_sort(json.dirs)  : {};
        children.files = json.files ? val_sort(json.files) : {};
        children.title = json.title ? json.title : path;
        delete_allowed = json.delete;
        yikes();
    }

    function isAvailable(){
        if (!new_dir) return false;
        if (children){
            if (children.dirs) {
                for (let key of Object.values(children.dirs)){
                    if (key == new_dir) return false;
                }
            }
            if (children.files) {
                for (let key of Object.values(children.files)){
                    if (key == new_dir) return false;
                }
            }
        }
        return true;
    }

    function is_image(file){
        let parts = file.toLowerCase().split('.');
        let ext = parts.pop();
        return image_extensions.includes(ext);
    }

    async function loadChildren(p){
        p = p.substring(6);
        if (p == '') p = '/';
        children = { dirs : [], files : [], title : p};
        path = p;
        if (p == '/'){
            children.dirs = [
                { path : `/user/${user.id}`, name : t('my files') },
                { path : '/project', name : t('projects')},
                { path : '/company', name : t('companies')},
            ]

            parent = false;
            form = false;
        } else {
            const url = api(`files${p}`);
            const res = await fetch(url,{credentials:'include'});
            if (res.ok){
                parent = p.substring(0, p.lastIndexOf("/"));
                if (parent == '/user'||p=='/project'||p=='/company') parent = '/';
                form = !(p=='/company'||p=='/project'||p=='/user');
                handleDirectory(res);
            } else {
                error(res);
            }
        }
    }

    function markdown(file){
        let parts = file.split('/');
        let path = `/api/files${file}`;
        path = encodeURI(path);
        let md = `![${parts.pop()}](${path})`;
        navigator.clipboard.writeText(md);
        warn(t('Markdown has been copied to clipboard!'));
        setTimeout(yikes, 2500);
    }

    function onclick(ev){
        ev.preventDefault();
        ev.stopPropagation();

        var target = ev.target;
        while (target && !target.href) target=target.parentNode;
        let href = target.getAttribute('href');
        if (href) {
            router.navigate(href);
            loadChildren(href);
        }

        return false;
    }

    async function upload_file(ev){
        ev.preventDefault();
        const url =  api('files'+path+'/'+files[0].name);
        const resp = await fetch(url, {
            credentials: 'include',
            method: 'POST',
             headers: {
                "Content-Type": "application/unknown",
            },
            body: files[0]
        });
        if (resp.ok){
            handleDirectory(resp);
            files = null;
        } else {
            error(resp);
        }
        return false;
    }

    function val_sort(map){
        return Object.entries(map)
            .map(item => ({name:item[1],path:item[0]}))
            .sort((a,b) => a.name.localeCompare(b.name));
    }

    onMount(() => loadChildren(window.location.pathname));
</script>

<h1>{t('files')} – {children?.title}</h1>

<ul>
{#if parent}
    <li class="dir parent">
        <span class="symbol"></span>
        <a href={'/files'+parent} {onclick}>..</a>
    </li>
{/if}
{#if children?.dirs}
{#each children.dirs as dir}
    <li class="dir">
        <span class="symbol"></span>
        <a href={'/files'+dir.path} {onclick}>{dir.name}</a>
        {#if delete_allowed}
        <button class="symbol" onclick={e => dropDir(`/api/files${dir.path}`,dir.name)}></button>
        {/if}
    </li>
{/each}
{/if}
{#if form}
<li class="action">
    <form onsubmit={create_dir} >
        <span class="symbol">+</span>
        <input type="text" bind:value={new_dir} />
        <button type="submit" disabled={!available} >{t('create_new_object',{object:t('directory')})}</button>
    </form>
</li>
{/if}
{#if children.files}
{#each children.files as file}
    <li class="file">
        <span class="symbol"></span>
        <a href={`/api/files${file.path}`} target="_blank">{file.name}</a>
        {#if is_image(file.path)}
        <button class="symbol" title={'markdown_code'} onclick={e => markdown(file.path)}></button>
        {/if}
        {#if delete_allowed}
        <button class="symbol" title={t('delete_object',{'object':t('file')})} onclick={e => dropFile(`/api/files${file.path}`,file.name)}></button>
        {/if}
    </li>
{/each}
{/if}
{#if form}
    <li class="action">
        <form onsubmit={upload_file}>
            <span class="symbol">+</span>
            <input type="file" bind:files />
            <button disabled={!files}>{t('upload_file')}</button>
        </form>
    </li>
{/if}
</ul>

