import {
	createHashHistory,
	createRootRoute,
	createRoute,
	createRouter,
	Outlet,
} from '@tanstack/react-router'
import { lazy, Suspense } from 'react'
import { IndexPage } from './components/index-page.tsx'
import { MobilePreview } from './components/mobile-preview.tsx'
import { WebPreview } from './components/web-preview.tsx'

// ---------------------------------------------------------------------------
// Auto-discover workflow entries via Vite's import.meta.glob.
// The @workflows alias is set by the CLI to point at the customer's
// workflows/ directory.
// ---------------------------------------------------------------------------

const webModules = import.meta.glob<{ default: React.ComponentType }>('@workflows/*/web/*/main.tsx')

const mobileModules = import.meta.glob('@workflows/*/mobile/*.rfwtxt', {
	query: '?raw',
	import: 'default',
})

// ---------------------------------------------------------------------------
// Path parsers
// ---------------------------------------------------------------------------

export interface ParsedWeb {
	workflow: string
	task: string
}

export interface ParsedMobile {
	workflow: string
	widget: string
}

export function parseWebPath(path: string): ParsedWeb | null {
	const m = path.match(/\/([^/]+)\/web\/([^/]+)\/main\.tsx$/)
	return m ? { workflow: m[1], task: m[2] } : null
}

export function parseMobilePath(path: string): ParsedMobile | null {
	const m = path.match(/\/([^/]+)\/mobile\/([^/]+)\.rfwtxt$/)
	return m ? { workflow: m[1], widget: m[2] } : null
}

// ---------------------------------------------------------------------------
// Route tree
// ---------------------------------------------------------------------------

const rootRoute = createRootRoute({
	component: () => <Outlet />,
})

const indexRoute = createRoute({
	getParentRoute: () => rootRoute,
	path: '/',
	component: () => <IndexPage webModules={webModules} mobileModules={mobileModules} />,
})

// Web routes: /#/workflows/:workflow/web/:task
const webRoutes = Object.entries(webModules).flatMap(([path, loader]) => {
	const parsed = parseWebPath(path)
	if (!parsed) return []

	const LazyComponent = lazy(loader)

	return [
		createRoute({
			getParentRoute: () => rootRoute,
			path: `/workflows/${parsed.workflow}/web/${parsed.task}`,
			validateSearch: (search: Record<string, unknown>) => ({
				header: search.header !== 'false',
			}),
			component: () => (
				<WebPreview workflow={parsed.workflow} task={parsed.task}>
					<Suspense fallback={<LoadingSpinner />}>
						<LazyComponent />
					</Suspense>
				</WebPreview>
			),
		}),
	]
})

// Mobile routes: /#/workflows/:workflow/mobile/:widget
const mobileRoutes = Object.entries(mobileModules).flatMap(([path]) => {
	const parsed = parseMobilePath(path)
	if (!parsed) return []

	return [
		createRoute({
			getParentRoute: () => rootRoute,
			path: `/workflows/${parsed.workflow}/mobile/${parsed.widget}`,
			validateSearch: (search: Record<string, unknown>) => ({
				header: search.header !== 'false',
			}),
			component: () => <MobilePreview workflow={parsed.workflow} widget={parsed.widget} />,
		}),
	]
})

const routeTree = rootRoute.addChildren([indexRoute, ...webRoutes, ...mobileRoutes])

const hashHistory = createHashHistory()
export const router = createRouter({ routeTree, history: hashHistory })

declare module '@tanstack/react-router' {
	interface Register {
		router: typeof router
	}
}

// ---------------------------------------------------------------------------
// Shared components
// ---------------------------------------------------------------------------

function LoadingSpinner() {
	return (
		<div style={{ display: 'flex', justifyContent: 'center', padding: '3rem' }}>
			<div
				style={{
					width: 24,
					height: 24,
					border: '3px solid #e2e8f0',
					borderTopColor: '#0d9488',
					borderRadius: '50%',
					animation: 'spin 0.6s linear infinite',
				}}
			/>
			<style>{'@keyframes spin { to { transform: rotate(360deg) } }'}</style>
		</div>
	)
}
