// modules/core/router.js
import { init as initClickManager } from './ClickManager.js';
import { navigateTo } from './navigateTo.js';

const routes = new Map();
const wildcards = [];
const guards = new Map();

let currentRoute = null;
let layoutCallback = null;
let metaCallback = null;

/**
 * Registriert eine neue Route mit optionalem Handler
 * @param {string} path - Pfad der Route
 * @param {Function} handler - Callback bei Treffer
 */
export function defineRoute(path, handler) {
    if (path.includes('*')) {
        wildcards.push({ pattern: new RegExp('^' + path.replace('*', '.*') + '$'), handler });
    } else {
        routes.set(path, handler);
    }
}

/**
 * Definiert einen Guard für eine Route
 * @param {string} path - Pfad
 * @param {Function} guard - Guard-Funktion (return false = block)
 */
export function guardRoute(path, guard) {
    guards.set(path, guard);
}

/**
 * Gibt die aktuell aktive Route zurück
 */
export function getRouteContext() {
    return currentRoute;
}

/**
 * Setzt eine Callback-Funktion für dynamische Layout-Switches
 */
export function onLayoutSwitch(fn) {
    layoutCallback = fn;
}

/**
 * Setzt eine Callback-Funktion für Meta-Daten (z. B. title, theme)
 */
export function onMetaUpdate(fn) {
    metaCallback = fn;
}

function matchRoute(href) {
    if (routes.has(href)) return routes.get(href);
    for (const entry of wildcards) {
        if (entry.pattern.test(href)) return entry.handler;
    }
    return null;
}

function runGuard(href) {
    const guard = guards.get(href);
    return guard ? guard(href) !== false : true;
}

function extractMetaFromHTML(html) {
    const temp = document.createElement('div');
    temp.innerHTML = html;
    const metaTags = {};
    temp.querySelectorAll('[data-meta]').forEach(el => {
        for (const attr of el.attributes) {
            if (attr.name.startsWith('data-meta-')) {
                const key = attr.name.replace('data-meta-', '');
                metaTags[key] = attr.value;
            }
        }
    })
    //const title = temp.querySelector('[data-meta-title]')?.getAttribute('data-meta-title');
    //const theme = temp.querySelector('[data-meta-theme]')?.getAttribute('data-meta-theme');
    return { metaTags };
}

function animateLayoutSwitch(type) {
    document.body.dataset.layout = type;
    document.body.classList.add('layout-transition');
    setTimeout(() => document.body.classList.remove('layout-transition'), 300);
}

/**
 * Startet den Router mit optionaler Prefetch-Konfiguration
 * @param {Object} prefetchOptions - Optionen für das Prefetching-System
 */
export function startRouter(prefetchOptions = {}) {
    initClickManager((href, link, options) => {
        if (!runGuard(href)) return;

        if (options.modal) {
            const handler = matchRoute(href);
            currentRoute = { href, modal: true, link, options };
            handler?.(currentRoute);
            layoutCallback?.(currentRoute);
            metaCallback?.(currentRoute);
        } else {
            navigateTo(href, {
                ...options,
                onUpdate: (html) => {
                    const container = document.querySelector('main');
                    if (container) container.innerHTML = html;

                    const routeHandler = matchRoute(href);
                    currentRoute = { href, html, modal: false };

                    const meta = extractMetaFromHTML(html);
                    if (meta.title) document.title = meta.title;
                    if (meta.theme) document.documentElement.style.setProperty('--theme-color', meta.theme);

                    routeHandler?.(currentRoute);
                    layoutCallback?.(currentRoute);
                    metaCallback?.(currentRoute);
                }
            });
        }
    }, prefetchOptions);

    // Bei Seitenstart erste Route prüfen
    window.addEventListener('DOMContentLoaded', () => {
        const href = location.pathname;
        const routeHandler = matchRoute(href);
        currentRoute = { href, modal: false };
        routeHandler?.(currentRoute);
        layoutCallback?.(currentRoute);
        metaCallback?.(currentRoute);
    });
}

export { animateLayoutSwitch, extractMetaFromHTML };
