import { toChildArray } from 'preact'
import { useCallback, useEffect, useState } from 'preact/hooks'

export function hashCode(s) {
    s = s.toString() + "seed iniziale dell'hash"

    let hash = 0

    if (s.length === 0) return hash

    for (let i = 0; i < s.length; i++) {
        const chr = s.charCodeAt(i)
        hash = (hash << 5) - hash + chr
        hash |= 0
    }

    return Math.abs(hash)
}

export function useUser(onLoginStateChanged) {
    const [user, setUser] = useState(null)

    useEffect(() => {
        fetch('/api/current-user')
            .then(res => res.json())
            .then(value => {
                setUser(value)
                onLoginStateChanged(value)
            })
            .catch(e => console.error(e))
    }, [])

    return user
}

//
// Hooks
//

// Router

function matchPattern(pattern, url) {
    const r = `^${pattern.replace(/:([a-zA-Z0-9\_\-]+)/g, '(?<$1>[^\\/\\?]+?)')}$`
    return new RegExp(r).exec(url)
}

export const useRouter = routes => {
    for (const [id, route] of Object.entries(routes)) {
        const m = matchPattern(route.pattern, location.pathname)
        if (m) {
            return [id, route, m.groups]
        }
    }

    return ['unknown', { id: 'unknown' }, {}]
}

// useRemoteState

export function useRemoteState(url, initialValue = null) {
    const [error, setError] = useState(null)
    const [value, setValue] = useState(initialValue)

    const refresh = async () => {
        try {
            const res = await fetch(url)
            if (!res.ok) {
                setError(await res.text())
                return
            }

            setValue(await res.json())
        } catch (err) {
            setError(err)
        }
    }

    useEffect(() => {
        refresh()
    }, [])

    return [value, error, refresh]
}

//
// Change Case Utility
//

const fromCaseMap = {
    camel: s => s.split(/(?=[A-Z])/),
    // ...
}
const toCaseMap = {
    dash: parts => parts.map(p => p.toLowerCase()).join('-'),
    // ...
}

export function changeCase(from, to, s) {
    return toCaseMap[to](fromCaseMap[from](s))
}
