import { redirect } from "@remix-run/node";
import type { LoaderFunctionArgs } from "@remix-run/node";
import { githubApp } from "~/lib/github-app.server";
import { getSession, commitSession } from "~/lib/session.server";
import { accountLinkingService } from "~/lib/account-linking.server";

export async function loader({ request }: LoaderFunctionArgs) {
  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 installation_id = url.searchParams.get("installation_id");
  const setup_action = url.searchParams.get("setup_action");

  console.log('🔄 GitHub OAuth callback received');
  if (error) {
    console.log('- Error:', error);
  }
  if (installation_id) {
    console.log('- Installation ID:', installation_id);
  }

  // Handle OAuth errors
  if (error) {
    console.error("GitHub OAuth error:", error);
    return redirect(`/?error=oauth_failed&details=${encodeURIComponent(error)}`);
  }

  if (!code) {
    console.error("No authorization code received");
    return redirect("/?error=no_code");
  }

  try {
    // Exchange code for access token and get user info
    const userAuth = await githubApp.handleCallback(code, state || undefined);
    console.log('✅ GitHub OAuth successful for user:', userAuth.login);
    
    // Get existing session
    const session = await getSession(request.headers.get("Cookie"));
    let userSession = session.get('user') || { isLinked: false };

    // Add GitHub info to session
    userSession.github = {
      userId: userAuth.id.toString(),
      login: userAuth.login,
      name: userAuth.name,
      email: userAuth.email,
      avatar_url: userAuth.avatar_url,
    };

    // Check if we can link accounts (if HuggingFace auth exists)
    if (userSession.huggingface) {
      const linkCheck = accountLinkingService.canLink(
        userAuth.id.toString(),
        userSession.huggingface.username
      );

      if (linkCheck.canLink) {
        // Create account link
        const accountLink = accountLinkingService.createLink(
          userAuth.id.toString(),
          userAuth.login,
          userSession.huggingface.username
        );

        userSession.isLinked = true;
        userSession.linkedAt = accountLink.linkedAt;
        
        console.log(`🔗 Accounts automatically linked: ${userAuth.login} ↔ ${userSession.huggingface.username}`);
      } else {
        console.warn('⚠️ Cannot link accounts:', linkCheck.reason);
        userSession.isLinked = false;
      }
    } else {
      console.log('ℹ️ No HuggingFace authentication found, GitHub auth saved for later linking');
      userSession.isLinked = false;
    }

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

    const redirectUrl = installation_id ? "/install" : "/";

    return redirect(redirectUrl, {
      headers: {
        "Set-Cookie": await commitSession(session),
      },
    });
  } catch (error: any) {
    console.error("GitHub callback error:", error);
    
    // Provide more specific error information
    let errorCode = "callback_failed";
    if (error.message?.includes("bad_verification_code") || error.message?.includes("incorrect or expired")) {
      errorCode = "expired_code";
    } else if (error.message?.includes("client_id")) {
      errorCode = "invalid_client";
    }
    
    return redirect(`/?error=${errorCode}&message=${encodeURIComponent(error.message)}`);
  }
}
