'use client';

import NextLink from 'next/link';
import {MotionConfig} from 'framer-motion';
import {Theme} from '@astryxdesign/core/theme';
import {LinkProvider} from '@astryxdesign/core/Link';
import {ToastViewport} from '@astryxdesign/core/Toast';
import {loyalyTheme} from '@/theme';
import {WorkspaceProvider} from '@/shared/providers/WorkspaceProvider';
import {SessionProvider} from '@/features/auth/providers/SessionProvider';
import type {AuthSession} from '@/features/auth/types/auth';
import {LoyalyAiProvider} from '@/features/loyaly-ai/providers/LoyalyAiProvider';

/**
 * @/theme wraps the GENERATED module (__built: true), so <Theme> skips runtime
 * token injection entirely — tokens already ship in loyaly.css. Importing
 * src/theme/loyalyTheme.ts here instead would move theming to a client-only
 * useInsertionEffect and reintroduce the first-paint flash.
 *
 * @/theme also re-attaches the Lucide icon registry that `theme build` drops;
 * <Theme> registers it during render, on both the SSR and hydration passes.
 *
 * WorkspaceProvider and LoyalyAiProvider sit here, ABOVE the route tree, so
 * query scope and Loyaly AI state outlive both navigation and the responsive
 * swap between the inline panel and the slide-over.
 */
export function Providers({
  children,
  initialSession,
}: {
  children: React.ReactNode;
  /** Resolved from the signed cookie in the root layout — see SessionProvider. */
  initialSession: AuthSession | null;
}) {
  return (
    <Theme theme={loyalyTheme} mode="dark">
      <LinkProvider component={NextLink}>
        {/* One line, and every motion.* in the app honours prefers-reduced-motion. */}
        <MotionConfig reducedMotion="user">
          {/* Above the route tree AND outside (workspace), because /login
              establishes the session that the workspace then reads. */}
          <SessionProvider initialSession={initialSession}>
            <WorkspaceProvider>
              <LoyalyAiProvider>{children}</LoyalyAiProvider>
            </WorkspaceProvider>
          </SessionProvider>
          {/* Mounted once at the root: useToast() positions, stacks and
              expires notifications into this viewport from anywhere. */}
          <ToastViewport />
        </MotionConfig>
      </LinkProvider>
    </Theme>
  );
}
