import { useSignal } from '@preact/signals'
import clsx from 'clsx'
import { useEffect, useState } from 'preact/hooks'

export const EXAMPLE_TREE = {
    type: 'root',
    children: [
        {
            type: 'folder',
            name: 'bin/',
            children: [
                {
                    type: 'file',
                    name: 'a.out',
                },
            ],
        },
        {
            type: 'file',
            name: 'main.c',
        },
        {
            type: 'file',
            name: 'data.csv',
        },
    ],
}

const flattenTree = (node, depth = 0, path = []) => {
    if (node.type === 'root') {
        return node.children.flatMap(entry => flattenTree(entry, depth, []))
    }
    if (node.type === 'folder')
        return [
            {
                depth,
                type: 'folder',
                name: node.name,
                path: path.join('/') + '/',
            },
            ...node.children.flatMap(entry => flattenTree(entry, depth + 1, [...path, node.name])),
        ]
    if (node.type === 'file') {
        return [
            {
                depth,
                type: 'file',
                name: node.name,
                path: path.join('/'),
            },
        ]
    }

    throw new Error(`invalid node type "${node?.type ?? '<unknown>'}"`)
}

const TreeViewNode = ({ listDir, actionOpenFile, node, depth, path }) => {
    if (node.type === 'root') {
        const [children, setChildren] = useState([])

        useEffect(async () => {
            setChildren(await listDir(path))
        }, [])

        return children.flatMap(entry => (
            <TreeViewNode
                listDir={listDir}
                actionOpenFile={actionOpenFile}
                node={entry}
                depth={0}
                path={'/' + entry.name}
            />
        ))
    }

    if (node.type === 'folder') {
        const [collapsed, setCollapsed] = useState(true)

        const [children, setChildren] = useState([])

        useEffect(async () => {
            setChildren(collapsed ? [] : await listDir(path))
        }, [collapsed])

        return (
            <>
                <div
                    class="entry folder"
                    style={{ '--depth': depth }}
                    title={path}
                    onClick={() => setCollapsed(c => !c)}
                >
                    <div class="material-symbols-outlined">folder</div>
                    <div class="name">{node.name}/</div>
                    <div class="actions"></div>
                </div>
                {!collapsed &&
                    children.flatMap(entry => (
                        <TreeViewNode
                            listDir={listDir}
                            actionOpenFile={actionOpenFile}
                            node={entry}
                            depth={depth + 1}
                            path={path + '/' + entry.name}
                        />
                    ))}
            </>
        )
    }

    if (node.type === 'file') {
        return (
            <div
                class="entry file"
                style={{ '--depth': depth }}
                title={path}
                onClick={() => {
                    console.log('open', path)
                    actionOpenFile?.(path)
                }}
            >
                <div class="material-symbols-outlined">description</div>
                <div class="name">{node.name}</div>
                <div class="actions"></div>
            </div>
        )
    }
}

const ICONS = {
    ['folder']: 'folder',
    ['file']: 'description',
}

export const TreeView = ({ listDir, actionOpenFile, rootPath }) => {
    return (
        <div class="tree-view">
            <TreeViewNode
                listDir={listDir}
                actionOpenFile={actionOpenFile}
                node={{ type: 'root' }}
                depth={0}
                path={rootPath}
            />
        </div>
    )
}
