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

import URLPattern from 'url-pattern'

export const Router = ({ pages }) => {
    const compiledRoutes = useMemo(
        () =>
            Object.entries(pages).map(([pattern, Page]) => ({
                pattern: new URLPattern(pattern),
                Page,
            })),
        [pages]
    )

    const routerUrl = useSignal(location.hash.slice(1))

    useEffect(() => {
        window.addEventListener('hashchange', () => {
            routerUrl.value = location.hash.slice(1)
        })
    }, [])

    const route = compiledRoutes.flatMap(({ pattern, Page }) => {
        const m = pattern.match(routerUrl.value.split('?', 1)[0])
        return m ? [{ Page, params: m }] : []
    })?.[0]

    if (!route) {
        console.log(`Invalid route "${routerUrl.value}", redirecting to homepage`)

        location.href = '/#/'
        routerUrl.value = '/'

        return <>Redirecting...</>
    }

    const { Page, params } = route

    const queryPart =
        routerUrl.value.indexOf('?') === -1
            ? ''
            : routerUrl.value.slice(routerUrl.value.indexOf('?') + 1)
    console.log(queryPart)

    const queryParams =
        queryPart?.length > 0
            ? Object.fromEntries(
                  queryPart.split('&').map(kvPart => {
                      const eqIndex = kvPart.indexOf('=')
                      return eqIndex === -1
                          ? [kvPart, true]
                          : [
                                kvPart.slice(0, eqIndex),
                                decodeURIComponent(kvPart.slice(eqIndex + 1)),
                            ]
                  })
              )
            : {}

    return <Page params={params} query={queryParams} />
}

export const Link = ({ page, params, query, children }) => {
    for (const [key, value] of Object.entries(params ?? {})) {
        page = page.replace(':' + key, encodeURIComponent(value))
    }

    let targetHref = page
    if (query) {
        targetHref +=
            '?' +
            Object.entries(query ?? {})
                .map(([key, value]) => `${key}=${encodeURIComponent(value)}`)
                .join('&')
    }

    return <a href={'/#' + targetHref}>{children}</a>
}
