import {
  createRootRoute,
  createRoute,
  createRouter,
  lazyRouteComponent,
} from '@tanstack/react-router';
import { z } from 'zod';
import AppShell from './components/AppShell';
import { LoadingState } from './components/LoadingState';
import Home from './pages/Home';

// Home is imported eagerly: it is the landing route, and deferring it would put
// a second round trip in front of the first paint. Every other page is a
// separate chunk, fetched when the listener first goes there and then held by
// the service worker.
const Artists = lazyRouteComponent(() => import('./pages/Artists'));
const ArtistDetail = lazyRouteComponent(() => import('./pages/ArtistDetail'));
const Albums = lazyRouteComponent(() => import('./pages/Albums'));
const AlbumDetail = lazyRouteComponent(() => import('./pages/AlbumDetail'));
const Tracks = lazyRouteComponent(() => import('./pages/Tracks'));
const Genres = lazyRouteComponent(() => import('./pages/Genres'));
const Vibe = lazyRouteComponent(() => import('./pages/Vibe'));
const Recommendations = lazyRouteComponent(() => import('./pages/Recommendations'));
const Search = lazyRouteComponent(() => import('./pages/Search'));
const Settings = lazyRouteComponent(() => import('./pages/Settings'));
const Quarantine = lazyRouteComponent(() => import('./pages/Quarantine'));
const Jobs = lazyRouteComponent(() => import('./pages/Jobs'));

// Root route renders the AppShell (NavRail + TopBar + PlaybackBar + NowPlayingPanel)
// with an <Outlet/> where the active child route renders.
export const rootRoute = createRootRoute({
  component: AppShell,
});

export const homeRoute = createRoute({
  getParentRoute: () => rootRoute,
  path: '/',
  component: Home,
});

export const artistsRoute = createRoute({
  getParentRoute: () => rootRoute,
  path: '/artists',
  component: Artists,
});

export const artistDetailRoute = createRoute({
  getParentRoute: () => rootRoute,
  path: '/artists/$artistId',
  component: ArtistDetail,
});

export const albumsRoute = createRoute({
  getParentRoute: () => rootRoute,
  path: '/albums',
  component: Albums,
});

export const albumDetailRoute = createRoute({
  getParentRoute: () => rootRoute,
  path: '/albums/$albumId',
  component: AlbumDetail,
});

export const tracksRoute = createRoute({
  getParentRoute: () => rootRoute,
  path: '/tracks',
  component: Tracks,
});

export const genresRoute = createRoute({
  getParentRoute: () => rootRoute,
  path: '/genres',
  component: Genres,
});

export const vibeRoute = createRoute({
  getParentRoute: () => rootRoute,
  path: '/vibe',
  component: Vibe,
});

export const recommendationsRoute = createRoute({
  getParentRoute: () => rootRoute,
  path: '/recommendations',
  component: Recommendations,
});

export const searchRoute = createRoute({
  getParentRoute: () => rootRoute,
  path: '/search',
  component: Search,
  validateSearch: z.object({
    q: z.string().optional(),
  }),
});

export const settingsRoute = createRoute({
  getParentRoute: () => rootRoute,
  path: '/settings',
  component: Settings,
});

export const quarantineRoute = createRoute({
  getParentRoute: () => rootRoute,
  path: '/quarantine',
  component: Quarantine,
});

export const jobsRoute = createRoute({
  getParentRoute: () => rootRoute,
  path: '/jobs',
  component: Jobs,
});

const routeTree = rootRoute.addChildren([
  homeRoute,
  artistsRoute,
  artistDetailRoute,
  albumsRoute,
  albumDetailRoute,
  tracksRoute,
  genresRoute,
  vibeRoute,
  recommendationsRoute,
  searchRoute,
  settingsRoute,
  quarantineRoute,
  jobsRoute,
]);

export const router = createRouter({
  routeTree,
  // Shown while a route's chunk is in flight. Without it the shell holds the
  // previous page and the tap reads as a dropped input.
  defaultPendingComponent: () => <LoadingState />,
});

// Type-safety: register the router instance type globally.
declare module '@tanstack/react-router' {
  interface Register {
    router: typeof router;
  }
}
