import { type LoaderFunctionArgs, redirect } from "@remix-run/node";
import { createUserSession, saveUserInfo, sessionStorage } from "~/api/login/auth.server";
import { OAuthClient } from "~/api/login/oauth-client";
import { getServerOAuthConfigRuntime } from "~/config/oauth-secret.server";
import { JWTUtils, type UserInfoForJWT } from "~/utils/jwt";

/**
 * 端口号到地区的映射关系
 * 根据 ecosystem.config.cjs 配置文件
 */
const PORT_TO_AREA_MAP: Record<string, string> = {
  '51703': '梅州',
  '51704': '云浮',
  '51705': '揭阳',
  '51706': '潮州',
  '51707': '省局'
};

/**
 * 根据端口号获取地区
 * @param port - 端口号
 * @returns 地区名称，如果未找到则返回 undefined
 */
function getAreaByPort(port: string): string | undefined {
  return PORT_TO_AREA_MAP[port];
}

/**
 * 辅助函数：使用 session flash 重定向到登录页面并传递错误信息
 */
async function redirectToLoginWithError(request: Request, errorMessage: string) {
  const session = await sessionStorage.getSession(request.headers.get("Cookie"));
  session.flash("loginError", errorMessage);

  return redirect("/login", {
    headers: {
      "Set-Cookie": await sessionStorage.commitSession(session)
    }
  });
}

export async function loader({ request }: LoaderFunctionArgs) {
  const url = new URL(request.url);
  // const origin = url.origin; // 获取请求的源 (e.g., "http://10.79.97.17:51703")
  const port = url.port; // 获取端口号
  const area = getAreaByPort(port); // 根据端口号获取地区
  const code = url.searchParams.get("code");
  const state = url.searchParams.get("state");
  const error = url.searchParams.get("error");
  const error_description = url.searchParams.get("error_description");

  // console.log("🔧 OAuth2.0回调参数:", {
  //   code: code ? `${code.substring(0, 10)}...` : null,
  //   state: state,
  //   error: error,
  //   error_description: error_description,
  //   fullUrl: request.url,
  //   port: port,
  //   area: area
  // });

  // 检查是否有错误
  if (error) {
    console.error("❌ OAuth2.0授权失败:", error, error_description);
    return redirectToLoginWithError(request, error_description || error || "授权失败");
  }

  // 检查是否有授权码
  if (!code) {
    console.error("❌ OAuth2.0回调缺少授权码");
    return redirectToLoginWithError(request, "登录过程中缺少授权码，请重新登录");
  }

  // 验证状态值
  if (!state || !state.endsWith("_idp")) {
    console.error("❌ OAuth2.0状态值验证失败:", { state, expectedSuffix: "_idp" });
    return redirectToLoginWithError(request, "登录状态验证失败，请重新登录");
  }

  console.log("✅ OAuth2.0回调参数验证通过");

  // 声明在 try 外部，以便在 catch 中访问
  let tokenResponse = null;
  const oauthClient = new OAuthClient(getServerOAuthConfigRuntime());

  try {
    console.log("🔧 开始处理OAuth2.0回调");

    // 开始获取访问令牌
    tokenResponse = await oauthClient.getAccessToken(code);
    if (!tokenResponse) {
      console.error("获取访问令牌失败");
      // 注意：此时还没有 access_token，无法调用 IDaaS 登出
      // 只能重定向到登录页，让用户重新开始登录流程
      return redirectToLoginWithError(request, "获取访问令牌失败，请重试");
    }
    console.log("✅ [Callback] 访问令牌获取成功");


    const userInfo = await oauthClient.getUserInfo(tokenResponse.access_token);
    if(!userInfo || !userInfo.success){
      console.error('获取用户信息失败：',userInfo);

      // 🔑 关键：此时 IDaaS 那边已经登录成功，但我们获取用户信息失败
      // 需要调用 IDaaS 登出，清除 IDaaS 的登录状态，避免用户下次登录时出现问题
      try {
        const logoutUrl = `${url.protocol}//${url.host}/login`;
        const logoutSuccess = await oauthClient.logout(tokenResponse.access_token, logoutUrl);
        if (logoutSuccess) {
          console.log("✅ [Callback] 已清除 IDaaS 登录状态");
        } else {
          console.warn("⚠️ [Callback] 清除 IDaaS 登录状态失败");
        }
      } catch (logoutError) {
        console.error("❌ [Callback] 调用 IDaaS 登出时出错:", logoutError);
      }

      return redirectToLoginWithError(request, "获取用户信息失败，请重试");
    }
    console.log("✅ [Callback] 用户信息获取成功");


    // TODO 根据用户信息判断用户角色，这里可以根据实际业务逻辑调整 暂定都是common
    const userRole = "common";

    // 获取重定向URL
    const redirectTo = url.searchParams.get("redirect") || "/";

    // 先生成一个临时 JWT
    const tempUserInfo =  {
      sub: userInfo.data.sub,
      // user_id: userInfo.data.user_id || "",
      user_id: "",
      username: userInfo.data.username,
      nick_name: userInfo.data.nickname,
      email: userInfo.data.email,
      phone_number: userInfo.data.phone_number,
      ou_id: userInfo.data.ou_id,
      ou_name: userInfo.data.ou_name,
      // is_leader: userInfo.data.is_leader,
      is_leader: false,
      user_role: userRole as 'common' | 'developer'
    };
    const tempToken = JWTUtils.generateJWT(tempUserInfo, tokenResponse.expires_in);

    // 成功获取用户信息之后通过auth.server.ts中的saveUserInfo方法去写入自己的数据库中，通过sub作为唯一值去添加数据
    const saveResult = await saveUserInfo(userInfo.data, tempToken, area);
    if (!saveResult.success) {
      console.error("保存用户信息到数据库失败:", saveResult.error);

      // 🔑 保存用户信息失败，需要清除 IDaaS 登录状态
      try {
        const logoutUrl = `${url.protocol}//${url.host}/login`;
        const logoutSuccess = await oauthClient.logout(tokenResponse.access_token, logoutUrl);
        if (logoutSuccess) {
          console.log("✅ [Callback] 已清除 IDaaS 登录状态（数据库保存失败）");
        } else {
          console.warn("⚠️ [Callback] 清除 IDaaS 登录状态失败（数据库保存失败）");
        }
      } catch (logoutError) {
        console.error("❌ [Callback] 调用 IDaaS 登出时出错（数据库保存失败）:", logoutError);
      }

      return redirectToLoginWithError(request, "保存用户信息失败，请重新登录");
    }

    console.log("用户信息已成功保存到数据库，地区:", area || "未设置");
    const savedUserData = saveResult.data!;

    // 生成前端专用JWT（使用完整的用户信息，包括数据库 ID）
    const jwtUserInfo: UserInfoForJWT = {
      sub: userInfo.data.sub,
      user_id: savedUserData.id!,
      username: savedUserData.username,
      nick_name: savedUserData.nick_name,
      email: savedUserData.email,
      phone_number: savedUserData.phone_number,
      ou_id: savedUserData.ou_id,
      ou_name: savedUserData.ou_name,
      is_leader: savedUserData.is_leader,
      user_role: userRole as 'common' | 'developer'
    };

    const frontendJWT = JWTUtils.generateJWT(jwtUserInfo, tokenResponse.expires_in);
    // console.log("前端JWT已生成");
    
    // 更新userInfo以包含数据库ID、JWT，并用数据库标准字段覆盖关键属性，确保 nick_name 等存在
    const enhancedUserInfo = {
      ...userInfo.data, // 保留OAuth返回的原字段（包含 nickname 等）
      username: savedUserData.username,
      nick_name: savedUserData.nick_name,
      phone_number: savedUserData.phone_number,
      email: savedUserData.email,
      ou_id: savedUserData.ou_id,
      ou_name: savedUserData.ou_name,
      status: savedUserData.status,
      is_leader: savedUserData.is_leader,
      user_id: savedUserData.id,
      user_role: userRole,
      frontend_jwt: frontendJWT
    };

    // 使用统一的session创建函数
    return createUserSession({
      isAuthenticated: true,
      userRole: userRole,
      redirectTo,
      accessToken: tokenResponse.access_token,
      refreshToken: tokenResponse.refresh_token,
      tokenExpiresIn: tokenResponse.expires_in,
      userInfo: enhancedUserInfo,
      frontendJWT
    });

  } catch (error) {
    console.error("OAuth2.0回调处理失败:", error);

    // 🔑 如果已经获取到了 access_token，需要清除 IDaaS 登录状态
    if (tokenResponse?.access_token) {
      try {
        const logoutUrl = `${url.protocol}//${url.host}/login`;
        const logoutSuccess = await oauthClient.logout(tokenResponse.access_token, logoutUrl);
        if (logoutSuccess) {
          console.log("✅ [Callback] 已清除 IDaaS 登录状态（回调处理异常）");
        } else {
          console.warn("⚠️ [Callback] 清除 IDaaS 登录状态失败（回调处理异常）");
        }
      } catch (logoutError) {
        console.error("❌ [Callback] 调用 IDaaS 登出时出错（回调处理异常）:", logoutError);
      }
    }

    return redirectToLoginWithError(request, "登录回调处理失败，请重新登录");
  }
}

export default function Callback() {
  return (
    <div className="flex items-center justify-center min-h-screen">
      <div className="text-center">
        <div className="animate-spin rounded-full h-12 w-12 border-b-2 border-blue-500 mx-auto"></div>
        <p className="mt-4 text-gray-600">正在处理登录...</p>
      </div>
    </div>
  );
}