import { Suspense } from 'react';
import type { Metadata } from 'next';
import dynamic from 'next/dynamic';
import { dehydrate, HydrationBoundary, QueryClient } from '@tanstack/react-query';
import SearchPage from '@/app/booking/search/page';

export const metadata: Metadata = {
  title: 'EDR Passenger Portal – Book Train Tickets Online',
  description:
    'Book train tickets on the Ethio-Djibouti Railway. Search trains between Ethiopia and Djibouti with easy online booking, seat selection, and flexible payment options.',
  alternates: {
    canonical: '/',
  },
  openGraph: {
    title: 'EDR Passenger Portal – Book Train Tickets Online',
    description:
      'Search and book train tickets across the Ethio-Djibouti Railway. Multiple seat classes available.',
    url: '/',
    type: 'website',
  },
};

// Below-the-fold on the landing page — code-split out of the initial bundle
// needed to render/hydrate the (above-the-fold) search form.
const PackagesSection = dynamic(() => import('@/components/PackagesSection'));

// Skeleton for the search form while stations are prefetched server-side —
// keeps first paint on a slow connection from being a blank page, and
// approximates the real form's height to avoid layout shift once it streams in.
function SearchFormSkeleton() {
  return (
    <div className="w-full max-w-4xl mx-auto animate-pulse">
      <div className="rounded-2xl border border-gray-100 dark:border-gray-800 p-6 space-y-4">
        <div className="h-8 bg-gray-200 dark:bg-gray-700 rounded w-1/3" />
        <div className="grid md:grid-cols-2 gap-4">
          <div className="h-12 bg-gray-200 dark:bg-gray-700 rounded-xl" />
          <div className="h-12 bg-gray-200 dark:bg-gray-700 rounded-xl" />
        </div>
        <div className="h-12 bg-gray-200 dark:bg-gray-700 rounded-xl" />
        <div className="h-12 bg-gray-300 dark:bg-gray-600 rounded-xl w-40" />
      </div>
    </div>
  );
}

// Isolates the server-side stations prefetch behind its own Suspense boundary
// (a real async Server Component, unlike a plain `await` in the page body) so
// Next.js can stream: the shell flushes immediately with SearchFormSkeleton,
// then the real search form + hydrated stations data stream in once ready —
// instead of blocking the whole page's TTFB on that one fetch.
async function StationsPrefetch({ children }: { children: React.ReactNode }) {
  const queryClient = new QueryClient();
  const apiUrl = process.env.NEXT_PUBLIC_API_URL || 'http://localhost:4000';

  await queryClient.prefetchQuery({
    queryKey: ['stations'],
    queryFn: async () => {
      // Caps how long the home page can be blocked on a slow/unresponsive API —
      // without this, a hung request leaves the Suspense boundary (and the
      // skeleton) stuck indefinitely instead of falling through to the
      // client-side fetch, which has its own timeout and a visible error state.
      const res = await fetch(`${apiUrl}/stations`, {
        next: { revalidate: 3600 },
        signal: AbortSignal.timeout(8000),
      });
      const json = await res.json();
      return json?.data ?? json;
    },
    // prefetchQuery defaults to 3 retries on failure — uncapped, that's up to
    // ~24s of retries on top of the 8s timeout above before this ever resolves.
    // Match the client's global default (providers.tsx) instead.
    retry: 1,
  });

  return (
    <HydrationBoundary state={dehydrate(queryClient)}>
      {children}
    </HydrationBoundary>
  );
}

export default function Home() {
  return (
    <>
      <Suspense fallback={<SearchFormSkeleton />}>
        <StationsPrefetch>
          <SearchPage />
        </StationsPrefetch>
      </Suspense>
      {/* Has its own independent data fetch (no dependency on stations) —
          rendered outside the StationsPrefetch boundary so it isn't stuck
          waiting on that fetch to resolve before it can start its own. */}
      <PackagesSection />
    </>
  );
}
