import '@fontsource/geist-sans/latin.css'
import 'katex/dist/katex.min.css'

import katex from 'katex'

import './styles.css'

import { For, Show, createEffect, createMemo, createResource, createSignal } from 'solid-js'
import { render } from 'solid-js/web'

const LaTeX = ({ content }) => <span class="latex" ref={el => katex.render(content, el)} />

const generateScript = (value, expression) => {
    const vector = expression.split('+').map(part => part.split('^')[0].trim())

    return `
# cambia queste due righe con i valori corretti
file="my-file.pdf"
sides="two-sided-long-edge" # otherwise use two-sided-short-edge or one-sided

# stampa ${value} = ${expression} copie
for sq in ${vector.join(' ')}; do
    lpr -P cdclf -# $sq -o media=a4 -o fit-to-page -o sides=$sides $file
done` // <- this missing "\n" is intentional
} // <- this missing "\n" is intentional

const ResultItem = ({ value, expression }) => {
    const handleClick = () => {
        navigator.clipboard.writeText(generateScript(value, expression))
    }

    return (
        <div class="result-item" title="Click to copy shell snippet" onClick={handleClick}>
            <LaTeX content={`${value} = ${expression}`} />
        </div>
    )
}

const App = ({}) => {
    const [rawData] = createResource(() => fetch('/shortest-squares-v2.txt').then(res => res.text()))
    const dict = createMemo(() =>
        Object.fromEntries(
            (rawData() ?? '')
                .split('\n')
                .filter(Boolean)
                .map(line => {
                    const [expression, value] = line.split('=').map(part => part.trim())
                    return [parseInt(value), expression]
                })
        )
    )

    createEffect(() => {
        console.log('dict', dict())
    })

    const [text, setText] = createSignal('')

    const results = createMemo(() => {
        const entries = Object.entries(dict())
        const query = text().trim()

        if (query === '') return entries

        if (!/^\d+$/.test(query)) return entries

        return entries.filter(([value]) => value.toString().includes(query))
    })

    const SHOW_COUNT = 8

    return (
        <>
            <h1>Shortest Sum of Squares</h1>
            <p>
                Click a sum of squares to copy the <code>lpr</code> shell command to print that number of copies
            </p>
            <input type="text" value={text()} onInput={e => setText(e.target.value)} />
            <div classList={{ 'results': true, 'has-more': results().length > SHOW_COUNT }}>
                <For each={results().slice(0, SHOW_COUNT)}>
                    {([value, expression]) => <ResultItem value={value} expression={expression} />}
                </For>
                <Show when={results().length === 0}>
                    <p>
                        For now we pre-computed the shortest sums of squares up to 1000 as you shouldn't need to print more than
                        that many copies of a document. Paper is a <em>precious resource</em> after all.
                    </p>
                </Show>
            </div>
        </>
    )
}

render(() => <App />, document.getElementById('app'))
