// import React from 'react';
import {
  Links,
  // LiveReload, // 不再需要，使用Vite时会与内置HMR冲突
  Meta,
  Outlet,
  Scripts,
  ScrollRestoration,
  isRouteErrorResponse,
  useRouteError,
  type MetaFunction,
  useLoaderData
} from "@remix-run/react";
import {
  LoaderFunctionArgs,
  redirect,
  ActionFunctionArgs
} from "@remix-run/node";
import { Layout } from "~/components/layout/Layout";
import { ErrorBoundary as AppErrorBoundary } from "~/components/error/ErrorBoundary";
import { MessageModalProvider } from "~/components/ui/MessageModal";
import { ToastProvider } from "~/components/ui/Toast";
import { ClientAuthGuard } from "~/components/auth/ClientAuthGuard";
import { getAccessToken } from "./utils/auth-storage";
import "remixicon/fonts/remixicon.css";
// 导入样式
import styles from "~/styles/main.css?url";
import messageModalStyles from "~/styles/components/message-modal.css?url";
import toastStyles from "~/styles/components/toast.css?url";
import LoadingBarContainer from "~/components/ui/LoadingBar";
import RouteChangeLoader from "~/components/ui/RouteChangeLoader";
// import { useState, useEffect } from "react";


// 导入认证相关的服务器端功能（仅在服务器端使用）
import { 
  // getUserSession, 
  logout,
  type UserRole 
} from "~/api/login/auth.server";

// 定义需要高级权限的路径
// export const developerOnlyPaths = [
//   '/settings',
//   '/config-lists',
//   '/document-types',
//   '/prompts',
// ];

// 导出类型供客户端使用
export type { UserRole };

// 辅助函数：从 MenuItem 数组中提取所有路径（包括子路由）
interface MenuItem {
  path: string;
  children?: MenuItem[];
}

function extractAllPaths(menuItems: MenuItem[]): string[] {
  const paths: string[] = [];

  function traverse(items: MenuItem[]) {
    for (const item of items) {
      paths.push(item.path);
      if (item.children && item.children.length > 0) {
        traverse(item.children);
      }
    }
  }

  traverse(menuItems);
  return paths;
}

// 辅助函数：检查路径是否在允许列表中
function isPathAllowed(pathname: string, allowedPaths: string[]): boolean {
  // 精确匹配
  if (allowedPaths.includes(pathname)) {
    return true;
  }

  // 前缀匹配（处理动态路由和子路由）
  // 例如：allowedPaths 包含 '/documents'，则 '/documents/123' 也应该被允许
  for (const allowedPath of allowedPaths) {
    if (pathname.startsWith(allowedPath + '/')) {
      return true;
    }
  }

  // 根路径特殊处理
  if (pathname === '/' || pathname === '/home') {
    return true; // 首页通常对所有已登录用户开放
  }

  return false;
}

// 添加action处理登录/登出请求
export async function action({ request }: ActionFunctionArgs) {
  const formData = await request.formData();
  const intent = formData.get("intent");

  if (intent === "logout") {
    return logout(request);
  }

  return null;
}

// 添加loader函数进行全局认证检查并传递环境变量给客户端
export async function loader({ request }: LoaderFunctionArgs) {
  // 获取当前路径
  const url = new URL(request.url);
  const pathname = url.pathname;

  // 排除不需要登录验证的路径（公共路径）
  const publicPaths = ['/login', '/favicon.ico', '/callback'];
  const isPublicPath = publicPaths.some(path => pathname.startsWith(path));

  // 获取用户角色和 JWT（从 Cookie Session）
  let userRole: UserRole = 'common'; // 默认为普通用户
  let frontendJWT: string | null = null;
  let allowedPaths: string[] = []; // 用户允许访问的路由列表

  if (!isPublicPath) {
    try {
      const { getUserSession } = await import("~/api/login/auth.server");
      const session = await getUserSession(request);
      userRole = session.userRole;
      frontendJWT = session.frontendJWT || null;

      // 🔑 检查用户角色和JWT是否为空
      if (!userRole || userRole === '') {
        console.error("❌ [Root Loader] 用户角色为空，session数据异常");
        // 保存当前路径，登录后可以跳转回来
        const redirectTo = pathname !== '/login' ? pathname : '/';
        return redirect(`/login?redirect=${encodeURIComponent(redirectTo)}&error=no_role`);
      }

      if (!frontendJWT) {
        console.error("❌ [Root Loader] JWT token为空，session数据异常");
        // 保存当前路径，登录后可以跳转回来
        const redirectTo = pathname !== '/login' ? pathname : '/';
        return redirect(`/login?redirect=${encodeURIComponent(redirectTo)}&error=no_token`);
      }

      // console.log("🔑 [Root Loader] 用户角色:", userRole, "JWT前20字符:", frontendJWT.substring(0, 20));

      // 🔒 RBAC 路由权限检查
      const { getUserRoutesByRole } = await import("~/api/auth/user-routes");
      // 权限校验需要包含隐藏路由，确保用户可以访问隐藏的功能页面
      // console.log("🔒 [Root Loader] 开始调用 getUserRoutesByRole...");
      const routesResult = await getUserRoutesByRole(userRole, frontendJWT, true);
      // console.log("🔒 [Root Loader] getUserRoutesByRole 返回结果:", {
      //   success: routesResult.success,
      //   hasData: !!routesResult.data,
      //   error: routesResult.error,
      //   shouldRedirectToHome: routesResult.shouldRedirectToHome
      // });

      if (routesResult.success && routesResult.data) {
        // 从菜单数据中提取所有允许的路径
        allowedPaths = extractAllPaths(routesResult.data);
        // console.log("🔑 [Root Loader] 用户允许的路由:", allowedPaths);

        // 检查当前路径是否在允许列表中
        const isAllowedPath = isPathAllowed(pathname, allowedPaths);

        if (!isAllowedPath) {
          console.warn(`⚠️ [Root Loader] 用户尝试访问未授权路由: ${pathname}`);
          // 返回 403 错误，而不是 redirect（避免循环）
          throw new Response("无权访问此页面", { status: 403 });
        }
      } else {
        // 🔑 检查是否因为认证失败需要重定向到登录页
        if (routesResult.shouldRedirectToHome) {
          console.error("❌ [Root Loader] 获取用户路由权限失败，可能是令牌已过期，重定向到登录页");
          console.error("❌ [Root Loader] 错误详情:", routesResult.error);

          // 清除会话并重定向到登录页
          const { sessionStorage } = await import("~/api/login/auth.server");
          const session = await sessionStorage.getSession(request.headers.get("Cookie"));
          const destroyedSession = await sessionStorage.destroySession(session);

          return redirect("/login?expired=true", {
            headers: {
              "Set-Cookie": destroyedSession
            }
          });
        }

        // 其他错误，只记录警告，不阻止访问（避免影响正常使用）
        console.warn("⚠️ [Root Loader] 获取用户路由权限失败，跳过权限检查");
      }
    } catch (error) {
      // 如果是 Response 对象（403 错误），直接抛出
      if (error instanceof Response) {
        throw error;
      }

      // 🔑 检查是否是 AuthenticationError（token 过期）
      if (error instanceof Error && error.name === 'AuthenticationError') {
        console.warn("⚠️ [Root Loader] Token 过期，重定向到登录页");
        // 保存当前路径，登录后可以跳转回来
        const redirectTo = pathname !== '/login' ? pathname : '/';
        return redirect(`/login?redirect=${encodeURIComponent(redirectTo)}`);
      }

      console.warn("⚠️ [Root Loader] 获取用户会话失败:", error);
      // 保持默认值 'common'
    }

    // 注意：认证检查和重定向已在 getUserSession() 中统一处理
    // 如果执行到这里，说明已通过认证或是公共路径
  }

  // 检查51707端口访问控制
  const currentPort = process.env.PORT || process.env.API_PORT_CONFIG;
  const runtimePort = url.port || currentPort;
  const isPort51707 = currentPort === '51707' || runtimePort === '51707';

  if (isPort51707 && !isPublicPath) {
    // 51707端口(省局)只允许访问交叉评查相关路径和首页
    const allowedPaths = ['/', '/cross-checking','/chat-with-llm'];
    const isAllowedPath = allowedPaths.some(path => pathname === path) ||
                         pathname.startsWith('/cross-checking/') ||
                         pathname.startsWith('/chat-with-llm/');

    if (!isAllowedPath) {
      return redirect("/cross-checking");
    }
  }

  // 向组件传递路径信息
  return Response.json({
    userRole,  // ✅ 返回真实的用户角色
    pathname,
    frontendJWT,
    isPublicPath,  // 传递给客户端，用于判断是否需要认证
    ENV: {
      // 客户端不再需要直接调用 Dify API
    },
  });
}


export const meta: MetaFunction = () => {
  return [
    { charSet: "utf-8" },
    { name: "viewport", content: "width=device-width,initial-scale=1" },
    { title: "中国烟草AI合同及卷宗审核系统" },
    { name: "description", content: "专业的AI合同及卷宗评查系统，提供智能审核、风险评估和规范化建议" },
    { name: "robots", content: "noindex,nofollow" } // 内部系统，防止被搜索引擎索引
  ];
};

// 使用links函数为应用加载CSS和其他资源
export function links() {
  return [
    { rel: "stylesheet", href: styles },
    { rel: "stylesheet", href: messageModalStyles },
    { rel: "stylesheet", href: toastStyles },
    // 添加 Antd 样式
    // { rel: "stylesheet", href: "https://cdn.jsdelivr.net/npm/antd@5/dist/reset.css" },
    { rel: "icon", type: "image/svg+xml", href: "/logo.svg" },
    // { rel: "preconnect", href: "https://fonts.googleapis.com" },
    // { rel: "preconnect", href: "https://fonts.gstatic.com", crossOrigin: "anonymous" },
    // { rel: "stylesheet", href: "https://fonts.googleapis.com/css2?family=Noto+Sans+SC:wght@400;500;700&display=swap" }
  ];
}

export default function App() {
  const { userRole, ENV, frontendJWT, isPublicPath } = useLoaderData<typeof loader>();


  return (
    <html lang="zh-CN">
      <head>
        <meta charSet="utf-8" />
        <meta name="viewport" content="width=device-width,initial-scale=1" />
        <style dangerouslySetInnerHTML={{
          __html: `
          :root {
            --color-primary: #00684a;
            --color-primary-hover: #005a3f;
            --color-primary-light: rgba(0, 104, 74, 0.1);
            --primary-color: #00684a;

            /* 成功、警告、错误颜色 */
            --color-success: #52c41a;
            --color-warning: #faad14;
            --color-error: #f5222d;
          }
        ` }} />
        <Meta />
        <Links />
        <script
          dangerouslySetInnerHTML={{
            __html: `window.__ENV = ${JSON.stringify(ENV)}`,
          }}
        />
      </head>
      <body className="font-sans">
        <MessageModalProvider>
          <ToastProvider>
            {/* 客户端认证守卫 - 在客户端检查 localStorage 中的 token */}
            <ClientAuthGuard isPublicPath={isPublicPath} />

            {/* 🔑 公共路径（登录页、回调页）不显示 Layout，直接渲染内容 */}
            {isPublicPath ? (
              <Outlet />
            ) : (
              <Layout userRole={userRole} frontendJWT={frontendJWT}>
                <Outlet />
              </Layout>
            )}
            <RouteChangeLoader />
          </ToastProvider>
        </MessageModalProvider>
        <ScrollRestoration />
        <Scripts />
        <LoadingBarContainer />
      </body>
    </html>
  );
}

export function ErrorBoundary() {
  const error = useRouteError();

  // 为错误页面设置标题和描述
  let title = "发生错误";
  let message = "发生了一个未知错误，请稍后重试";
  let statusText = "服务器错误";

  if (isRouteErrorResponse(error)) {
    title = `错误 ${error.status}`;

    // 特殊处理 403 错误
    if (error.status === 403) {
      title = "访问被拒绝";
      message = typeof error.data === 'string' ? error.data : "您没有权限访问此页面，请联系管理员获取相应权限";
      statusText = "无权访问";
    } else {
      message = error.data?.message || error.data || "发生了一个错误，请稍后重试";
      statusText = error.statusText || "错误";
    }
  } else {
    title = "意外错误";
    message = "服务器发生了意外错误，请稍后重试";
  }

  return (
    <html lang="zh-CN">
      <head>
        <meta charSet="utf-8" />
        <meta name="viewport" content="width=device-width,initial-scale=1" />
        <meta name="description" content={message} />
        <title>{title}</title>
        <Links />
      </head>
      <body>
        <AppErrorBoundary
          status={isRouteErrorResponse(error) ? error.status : 500}
          statusText={statusText}
          message={message}
        />
        <Scripts />
      </body>
    </html>
  );
}