import {
  json,
  Links,
  Meta,
  Outlet,
  Scripts,
  ScrollRestoration,
  useLoaderData,
} from "@remix-run/react";
import type { LinksFunction, LoaderFunctionArgs } from "@remix-run/node";
import { QueryClient, QueryClientProvider } from "@tanstack/react-query";
// import { sessionStorage } from "./sessions.server";
import MyLayout from "./components/MyLayout";
import { I18nextProvider } from "react-i18next";
import i18n from "./i18n";
import Cookies from "universal-cookie";
import { useMemo, Suspense, useState, useEffect } from "react";
import "./tailwind.css";
import "./styles/global.css";
import font_css from "public/styles/fonts.css?url";
import { Toaster } from "./components/ui/toaster";
import { validateTokens } from "./utils/token-manager.server";

export const links: LinksFunction = () => [
  {
    rel: "preload",
    href: "/fonts/pinar/Pinar-DS2-FD-Medium.woff2",
    as: "font",
    type: "font/woff2",
    crossOrigin: "anonymous",
  },
  { rel: "stylesheet", href: font_css, precedence: "high" },
];

// Detect mobile devices server-side to prevent layout shifts
export async function loader({ request }: LoaderFunctionArgs) {
  let user = null;
  let cookieHeader = null;

  try {
    // DONT DELETE THIS LINE because it will break the token validation
    const tokenResult = await validateTokens(request);
    user = tokenResult.user;
    cookieHeader = tokenResult.headers;
  } catch (error) {
    // If validateTokens throws a redirect, it will be caught by Remix
    // For other errors, we just proceed without a user
    if (!(error instanceof Response)) {
      console.error("Token validation error:", error);
    } else {
      throw error; // Re-throw redirects
    }
  }

  // Get language preference from cookies
  const cookies = new Cookies(request.headers.get("Cookie"), { path: "/" });
  const language = cookies?.get("lang") || "fa"; // Default to Farsi if not set
  const theme = cookies?.get("theme") || "light"; // Default to light theme if not set

  return json(
    {
      user: user,
      lang: language,
      theme: theme,
      ENV: {
        VITE_API_BASE_URL: process.env.VITE_API_BASE_URL,
        VITE_API_SOCKET_BASE_URL: process.env.VITE_API_SOCKET_BASE_URL,
        VITE_API_URL: process.env.VITE_API_URL,
        VITE_SITE_URL: process.env.VITE_SITE_URL,
        VITE_DOMAIN_URL: process.env.VITE_DOMAIN_URL,
        VITE_APP_VERSION_TYPE: process.env.VITE_APP_VERSION_TYPE,
        VITE_SUPPORT_PHONE: process.env.VITE_SUPPORT_PHONE,
        NODE_ENV: process.env.NODE_ENV,
      },
    },
    {
      // Set cache headers for better performance and include cookie updates
      headers: {
        "Cache-Control": "private, max-age=60, stale-while-revalidate=120",
        ...(cookieHeader || {}),
      },
    }
  );
}

// Document layout component
export function Layout({ children }: { children: React.ReactNode }) {
  const loaderData = useLoaderData<typeof loader>();

  // Handle case where loader data might be undefined (error context)
  const { lang = "fa", theme = "light", ENV } = loaderData || {};

  // Create a stable QueryClient instance that persists across renders
  const [queryClient] = useState(
    () =>
      new QueryClient({
        defaultOptions: {
          queries: {
            staleTime: 30 * 1000, // 30 seconds - balance between freshness and performance
            gcTime: 10 * 60 * 1000, // 10 minutes garbage collection
            refetchOnWindowFocus: false, // Prevent refetches on window focus
            refetchOnMount: true, // Refetch on mount only if data is stale (respects staleTime)
            retry: 1, // Limit retry attempts
          },
        },
      })
  );

  // Set language once on load
  useEffect(() => {
    i18n.changeLanguage(lang);
  }, [lang]);

  // Determine text direction based on language
  const textDirection = useMemo(
    () => (i18n.language === "en" ? "ltr" : "rtl"),
    []
  );
  const appTheme = useMemo(
    () => (theme === "dark" ? "dark" : "light"),
    [theme]
  );

  return (
    <QueryClientProvider client={queryClient}>
      <html lang={i18n.language} dir={textDirection}>
        <head>
          <meta charSet="utf-8" />
          <meta
            name="viewport"
            content="width=device-width, initial-scale=1, viewport-fit=cover"
          />
          <meta
            name="theme-color"
            content={appTheme === "dark" ? "#0a0a0a" : "#ffffff"}
          />
          <meta name="color-scheme" content="light dark" />
          <meta name="mobile-web-app-capable" content="yes" />
          {/* iOS-specific: standalone mode. Required for the status-bar-style
              below to take effect — without it iOS ignores black-translucent,
              so the app isn't edge-to-edge and env(safe-area-inset-top) doesn't
              line up with the headers. (Android uses mobile-web-app-capable.) */}
          <meta name="apple-mobile-web-app-capable" content="yes" />
          <meta
            name="apple-mobile-web-app-status-bar-style"
            content="black-translucent"
          />
          <meta name="apple-mobile-web-app-title" content="ویترون" />
          <link rel="canonical" href="https://vitrown.com/" />
          <link rel="manifest" href="/resources/manifest.webmanifest" />
          <link rel="apple-touch-icon" href="/apple-touch-icon.png" />
          <link rel="icon" type="image/svg+xml" href="/favicon.svg" />
          <link rel="icon" type="image/x-icon" href="/favicon.ico" />

          {/* Additional PWA meta tags */}
          <meta name="application-name" content="ویترون" />
          <meta name="msapplication-TileColor" content="#023E8A" />
          <meta name="msapplication-TileImage" content="/icon-144x144.png" />
          <meta name="msapplication-config" content="/browserconfig.xml" />

          <Meta />
          <Links />
        </head>
        <body dir={textDirection} className={`${appTheme} min-h-screen`}>
          <I18nextProvider i18n={i18n}>
            <Suspense fallback={<div className="app-loading-container"></div>}>
              <MyLayout>{children}</MyLayout>
            </Suspense>
          </I18nextProvider>
          <ScrollRestoration />
          {/* Inject environment variables globally for client-side access */}
          <script
            dangerouslySetInnerHTML={{
              __html: `
                window.ENV = ${JSON.stringify(ENV || {})};
                console.log('[ROOT] Environment variables injected:', window.ENV);
                console.log('[ROOT] API Base URL from ENV:', window.ENV ? window.ENV.VITE_API_BASE_URL : 'undefined');
              `,
            }}
          />
          <Scripts />
          <Toaster />
        </body>
      </html>
    </QueryClientProvider>
  );
}

// Root App component
export default function App() {
  return <Outlet />;
}
