import { useSignal, signal, useComputed, batch, effect } from '@preact/signals'

import { TreeView, EXAMPLE_TREE } from '@/client/components/TreeView.jsx'
import { Editor } from '@/client/components/Editor.jsx'
import clsx from 'clsx'
import { useEffect, useState } from 'preact/hooks'
import { fetchJson } from '../utils.js'
import { Terminal } from './Terminal.jsx'

function ensurePrefix(s, prefix) {
    return s.slice(0, prefix.length) === prefix ? s : prefix + s
}

function stripPrefix(s, prefix) {
    return s.slice(0, prefix.length) === prefix ? s.slice(prefix.length) : s
}

function clamp(min, value, max) {
    return Math.max(min, Math.min(value, max))
}

export const Ide = ({}) => {
    const ws = useSignal(null)
    const uuid = useSignal(null)

    useEffect(() => {
        ws.value = new WebSocket(`ws://${location.host}/api/docker/node:current-alpine/pty`)
        ws.value.addEventListener('message', e => {
            const event = JSON.parse(e.data)
            if (event.type === 'created') {
                uuid.value = event.id
                history.pushState(event.id, '', '/@container/' + event.id)
            }
        })
    }, [])

    if (!uuid.value) return <>Creating container...</>

    const activeTab = useSignal(null)

    const tabs = useSignal([
        // {
        //     id: '/project/main.c',
        //     content: signal('...main.c...'),
        // },
        // {
        //     id: '/project/data.csv',
        //     content: signal('...data.csv...'),
        // },
    ])

    const activePath = useComputed(() => {
        if (activeTab.value === null) return null

        return tabs.value[activeTab.value].id
    })

    const activeContent = useComputed(() => {
        if (activeTab.value === null) return null

        return tabs.value[activeTab.value].content
    })

    effect(() => {
        const path = activePath.value
        const contentSig = activeContent.value

        if (contentSig === null || path === null) return

        console.log(path, contentSig.value)
    })

    return (
        <div class="ide">
            <div class="sidebar">
                <div class="logo">PHC / Run</div>

                <div class="flex-row">
                    <button class="icon">
                        <div class="material-symbols-outlined">home</div>
                    </button>
                    <div class="project-details flex-grow">
                        <div class="title">{uuid.value}</div>
                        <div class="open">
                            <div class="material-symbols-outlined">unfold_more</div>
                        </div>
                    </div>
                </div>

                <div class="section">
                    <div class="spoiler">
                        <div class="material-symbols-outlined">account_tree</div>
                        <div class="title">Files</div>
                        <div class="material-symbols-outlined">keyboard_arrow_down</div>
                    </div>
                    <div class="content">
                        <TreeView
                            listDir={async path => {
                                const entries = await fetchJson(
                                    `/api/container/${uuid.value}/exec/ls/${stripPrefix(path, '/')}`
                                )

                                return entries
                            }}
                            actionOpenFile={async path => {
                                const content = await fetchJson(
                                    `/api/container/${uuid.value}/fs/${stripPrefix(path, '/')}`
                                )

                                console.log('content', content)

                                batch(() => {
                                    tabs.value = [
                                        ...tabs.value,
                                        {
                                            id: path,
                                            content: signal(content),
                                        },
                                    ]

                                    activeTab.value = tabs.value.length - 1
                                })
                            }}
                            rootPath={'/'}
                        />
                    </div>
                </div>
                <div class="section">
                    <div class="spoiler">
                        <div class="material-symbols-outlined">chat</div>
                        <div class="title">Conversation</div>
                        <div class="material-symbols-outlined">keyboard_arrow_down</div>
                    </div>
                    <div class="content">...</div>
                </div>
                <div class="section">
                    <div class="spoiler">
                        <div class="material-symbols-outlined">settings</div>
                        <div class="title">Settings</div>
                        <div class="material-symbols-outlined">keyboard_arrow_down</div>
                    </div>
                </div>
                <div class="spacer"></div>
                <div class="user-details">
                    <div class="profile">
                        <img
                            src={`https://api.dicebear.com/9.x/identicon/svg?seed=${uuid.value}`}
                            alt="profile picture"
                        />
                    </div>
                    <div class="username">{'aziis98'}</div>
                    <div class="email">{'aziis98'}@exmaple.com</div>
                </div>
            </div>
            <div class="header">
                <div class="search">
                    <div class="material-symbols-outlined">search</div>
                    <input type="text" placeholder="Search a snippet..." />
                </div>
                <div class="actions">
                    <button class="icon">
                        <div class="material-symbols-outlined">terminal</div>
                    </button>
                    <button
                        class="run"
                        onClick={() => {
                            console.log('Running file:', activePath.value)
                            if (!activePath.value) return

                            const fullPath = '/project' + activePath.value

                            if (fullPath.endsWith('.sh')) {
                                ws.value.send(`sh ${fullPath}\n`)
                                return
                            }
                            if (fullPath.endsWith('.js')) {
                                ws.value.send(`node ${fullPath}\n`)
                                return
                            }
                        }}
                    >
                        <div class="material-symbols-outlined">play_arrow</div>
                        Run File
                    </button>
                </div>
            </div>
            <div class="tabbed-editor">
                <div class="tabs">
                    {tabs.value.map((tab, index) => (
                        <div
                            class={clsx('tab', activeTab.value === index && 'active')}
                            onClick={() => (activeTab.value = index)}
                        >
                            <div class="title">{tab.id.split('/').at(-1)}</div>
                            <div class="buttons">
                                <button
                                    class="flat icon"
                                    onClick={e => {
                                        e.stopPropagation()

                                        batch(() => {
                                            const newValues = [...tabs.value]
                                            newValues.splice(index, 1)

                                            console.log(
                                                newValues.length,
                                                activeTab.value,
                                                clamp(0, activeTab.value, newValues.length - 1)
                                            )

                                            tabs.value = newValues
                                            activeTab.value =
                                                newValues.length === 0
                                                    ? null
                                                    : clamp(
                                                          0,
                                                          activeTab.value > index
                                                              ? activeTab.value - 1
                                                              : activeTab.value,
                                                          newValues.length - 1
                                                      )
                                        })
                                    }}
                                >
                                    <div class="material-symbols-outlined">close</div>
                                </button>
                            </div>
                        </div>
                    ))}
                </div>
                <div class="editor">
                    {activeContent.value === null ? (
                        <>No file opened</>
                    ) : (
                        <Editor
                            code={activeContent.value}
                            setCode={async source => {
                                activeContent.value.value = source

                                const path = activePath.value

                                await fetchJson(`/api/container/${uuid.value}/fs/${stripPrefix(path, '/')}`, {
                                    method: 'PUT',
                                    body: source,
                                })
                            }}
                        />
                    )}
                </div>
            </div>
            <div class="terminal">
                <div class="title">Terminal</div>
                <div class="actions">
                    <button class="flat icon">
                        <div class="material-symbols-outlined">delete</div>
                    </button>
                    <button class="flat icon">
                        <div class="material-symbols-outlined">close</div>
                    </button>
                </div>
                <div class="content" xterm-dimensions>
                    <Terminal ws={ws.value} />
                </div>
            </div>
            <div class="status">Websocket connection active</div>
        </div>
    )
}
