import { type ReactNode, useEffect, useState } from 'react'
import { ScrollContext } from '../../functions/Context'
import HeaderMessage from '../layout/HeaderMessage'
import HeaderError from '../layout/HeaderError'

import ViewAnimation from '../views/Animation'
import ViewHomepage from '../views/Homepage'
import ViewPersonal from '../views/Personal'
import ViewSearch from '../views/Search'
import ViewSettings from '../views/Settings'
import ViewText from '../views/Text'
import ViewUpload from '../views/Upload'

export default function PaneContent() {
    const [mainElem, setMainElem] = useState<HTMLElement | null>(null)
    const [path, setPath] = useState(window.location.pathname)
    const [key, setKey] = useState(window.location.href)

    // Track Path
    useEffect(() => {
        const onPop = () => {
            setPath(window.location.pathname)
            setKey(window.location.href)
        }
        window.addEventListener('popstate', onPop)
        return () => window.removeEventListener('popstate', onPop)
    }, [])

    // Match Component
    const views = new Array<{ route: RegExp; scroll: boolean; component: (m: RegExpMatchArray) => ReactNode }>(
        { route: /^\/art\/([0-9]+)$/, scroll: false, component: (m) => <ViewAnimation key={key} id={m[1]} /> },
        { route: /^\/text\/([a-z-]+)$/, scroll: true, component: (m) => <ViewText key={key} id={m[1]} /> },
        { route: /^\/personal$/, scroll: true, component: (_) => <ViewPersonal /> },
        { route: /^\/upload$/, scroll: false, component: (_) => <ViewUpload key={key} /> },
        { route: /^\/settings$/, scroll: true, component: (_) => <ViewSettings key={key} /> },
        { route: /^\/search$/, scroll: true, component: (_) => <ViewSearch key={key} /> },
        { route: /^\/$/, scroll: true, component: (_) => <ViewHomepage key={key} /> },
    )

    const match = views.map((v) => ({ v, m: path.match(v.route) })).find(({ m }) => m !== null)
    const relevant = match ? { ...match.v, component: match.v.component(match.m!) } : null

    // Render Content
    return (
        <ScrollContext.Provider value={mainElem}>
            <main ref={setMainElem} className={`layout-content ${relevant?.scroll ? 'layout-scrolling' : ''}`}>
                {relevant ? (
                    relevant.component
                ) : (
                    <>
                        <HeaderMessage label="System Message" />
                        <HeaderError reason="The page you requested was not found." />
                    </>
                )}
            </main>
        </ScrollContext.Provider>
    )
}
