import { redirect } from "@remix-run/node";
import type { LoaderFunctionArgs } from "@remix-run/node";
import { huggingFaceOAuth } from "~/lib/huggingface-oauth.server";
import { parseCookies } from "~/lib/oauth-utils.server";
import { getSession, commitSession } from "~/lib/session.server";
import { accountLinkingService } from "~/lib/account-linking.server";

export async function loader({ request }: LoaderFunctionArgs) {
  console.log("🔥 HuggingFace OAuth callback route hit");

  const url = new URL(request.url);
  const code = url.searchParams.get("code");
  const state = url.searchParams.get("state");
  const error = url.searchParams.get("error");
  const errorDescription = url.searchParams.get("error_description");

  console.log("Callback params:", {
    code: code ? `${code.substring(0, 4)}...` : null,
    state: state ? `${state.substring(0, 4)}...` : null,
    error,
    errorDescription,
  });

  // Handle OAuth errors
  if (error) {
    console.error("HuggingFace OAuth error:", error);
    if (errorDescription) {
      console.error("Error description:", errorDescription);
    }

    const redirectUrl = `/?error=hf_oauth_failed&details=${encodeURIComponent(
      errorDescription ? `${error}: ${errorDescription}` : error
    )}`;

    console.log("Redirecting to:", redirectUrl);
    return redirect(redirectUrl);
  }

  if (!code || !state) {
    console.error("Missing code or state in HuggingFace OAuth callback");
    return redirect("/?error=hf_missing_params");
  }

  // Get stored PKCE data from cookies
  const cookieHeader = request.headers.get("Cookie");
  const cookies = parseCookies(cookieHeader || "");

  console.log("Cookie keys available:", Object.keys(cookies));

  const storedState = cookies.hf_oauth_state;
  const codeVerifier = cookies.hf_oauth_code_verifier;
  const returnTo = cookies.hf_oauth_return_to
    ? decodeURIComponent(cookies.hf_oauth_return_to)
    : "/";

  console.log("Cookie values:", {
    storedState: storedState ? `${storedState.substring(0, 4)}...` : null,
    codeVerifier: codeVerifier ? `length: ${codeVerifier.length}` : null,
    returnTo,
  });

  // Verify state parameter (CSRF protection)
  if (!storedState || storedState !== state) {
    console.error("HuggingFace OAuth state mismatch");
    console.error(
      "Stored state:",
      storedState ? storedState.substring(0, 10) + "..." : "null"
    );
    console.error(
      "Received state:",
      state ? state.substring(0, 10) + "..." : "null"
    );
    return redirect("/?error=hf_state_mismatch");
  }

  if (!codeVerifier) {
    console.error("Missing code verifier for HuggingFace OAuth");
    return redirect("/?error=hf_missing_verifier");
  }

  try {
    console.log("🔄 Attempting to complete OAuth flow with code and verifier");

    // Complete OAuth flow
    const { accessToken, userInfo } = await huggingFaceOAuth.completeOAuthFlow(
      code,
      codeVerifier
    );

    console.log("✅ HuggingFace access token received:", accessToken);

    console.log("✅ HuggingFace OAuth successful for user:", userInfo.username);

    // Get existing session
    const session = await getSession(request.headers.get("Cookie"));
    let userSession = session.get("user") || { isLinked: false };

    // Add HuggingFace info to session
    userSession.huggingface = userInfo;

    // Check if we can link accounts (if GitHub auth exists)
    if (userSession.github) {
      const linkCheck = accountLinkingService.canLink(
        userSession.github.userId,
        userInfo.username
      );

      if (linkCheck.canLink) {
        // Create account link with access token
        const accountLink = accountLinkingService.createLink(
          userSession.github.userId,
          userSession.github.login,
          userInfo.username,
          accessToken
        );

        userSession.isLinked = true;
        userSession.linkedAt = accountLink.linkedAt;

        console.log(
          `🔗 Accounts automatically linked: ${userSession.github.login} ↔ ${userInfo.username}`
        );
      } else {
        console.warn("⚠️ Cannot link accounts:", linkCheck.reason);
        
        // Check if there's an existing link that needs token update
        const existingLink = accountLinkingService.findByHuggingFaceUser(userInfo.username);
        if (existingLink) {
          // Update the access token for the existing link
          accountLinkingService.updateAccessToken(existingLink.githubUserId, accessToken);
          console.log(`🔄 Updated access token for existing link: ${existingLink.githubLogin} ↔ ${userInfo.username}`);
          
          // If this is the same GitHub user, set session as linked
          if (existingLink.githubUserId === userSession.github.userId) {
            userSession.isLinked = true;
            userSession.linkedAt = existingLink.linkedAt;
          } else {
            userSession.isLinked = false;
          }
        } else {
          userSession.isLinked = false;
        }
      }
    } else {
      console.log(
        "ℹ️ No GitHub authentication found, HuggingFace auth saved for later linking"
      );
      userSession.isLinked = false;
    }

    // try {
    //   const serverConfig = {
    //     OAUTH2: {
    //       // PROVIDER_URL: process.env.OAUTH2_PROVIDER_URL,
    //       PROVIDER_URL: "https://huggingface.co",
    //       CLIENT_ID: process.env.OAUTH2_CLIENT_ID,
    //       CLIENT_SECRET: process.env.OAUTH2_CLIENT_SECRET,
    //       CALLBACK_URL: process.env.OAUTH2_CALLBACK_URL,
    //     },
    //   };

    //   // Exchange authorization code for access token
    //   const tokenResponse = await fetch(
    //     `${serverConfig.OAUTH2.PROVIDER_URL}/oauth/token`,
    //     {
    //       method: "POST",
    //       headers: {
    //         "Content-Type": "application/x-www-form-urlencoded",
    //         Accept: "application/json",
    //       },
    //       body: new URLSearchParams({
    //         grant_type: "authorization_code",
    //         client_id: serverConfig.OAUTH2.CLIENT_ID!,
    //         client_secret: serverConfig.OAUTH2.CLIENT_SECRET!,
    //         code,
    //         redirect_uri: "http://localhost:5173/api/auth/github/callback", // serverConfig.OAUTH2.CALLBACK_URL,
    //         code_verifier: codeVerifier,
    //       }),
    //     }
    //   );

    //   const tokenData = await tokenResponse.json();
    //   const accessToken = tokenData;

    //   console.log(
    //     "✅ Access token successfully exchanged for HuggingFace OAuth", accessToken
    //   );

    // } catch (tokenError) {
    //   console.error(
    //     "Failed to exchange authorization code for access token:",
    //     tokenError
    //   );
    //   return redirect(
    //     `/?error=hf_token_exchange_failed&message=${encodeURIComponent(
    //       "Failed to exchange authorization code for access token"
    //     )}`
    //   );
    // }

    // Save updated session
    session.set("user", userSession);

    // Create response with updated session cookie
    const response = redirect(returnTo);

    // Clear OAuth temporary cookies
    const clearCookieOptions = "Path=/; HttpOnly; SameSite=Lax; Max-Age=0";
    response.headers.append(
      "Set-Cookie",
      `hf_oauth_state=; ${clearCookieOptions}`
    );
    response.headers.append(
      "Set-Cookie",
      `hf_oauth_code_verifier=; ${clearCookieOptions}`
    );
    response.headers.append(
      "Set-Cookie",
      `hf_oauth_return_to=; ${clearCookieOptions}`
    );

    // Set session cookie
    response.headers.append("Set-Cookie", await commitSession(session));

    console.log("✅ Redirecting to:", returnTo);
    return response;
  } catch (error: any) {
    console.error("HuggingFace OAuth callback error:", error);
    const errorMessage = error.message || "Unknown error";
    console.error("Error details:", errorMessage);

    return redirect(
      `/?error=hf_callback_failed&message=${encodeURIComponent(errorMessage)}`
    );
  }
}
