"use client";

import type { ReactElement } from "react";
import { Suspense, useEffect } from "react";
import { useRouter, useSearchParams } from "next/navigation";
import { useAuth } from "@/lib/auth/auth-context";

/**
 * Allowlist of valid OAuth 2.0 and OpenID Connect error codes.
 * RFC 6749 Section 4.1.2.1 and OpenID Connect Core Section 3.1.2.6
 */
const VALID_OAUTH_ERRORS = new Set([
  // OAuth 2.0 RFC 6749
  "access_denied",
  "invalid_request",
  "unauthorized_client",
  "unsupported_response_type",
  "invalid_scope",
  "server_error",
  "temporarily_unavailable",
  // OpenID Connect Core
  "interaction_required",
  "login_required",
  "account_selection_required",
  "consent_required",
  "invalid_request_uri",
  "invalid_request_object",
  "request_not_supported",
  "request_uri_not_supported",
  "registration_not_supported",
  // Internal error codes
  "session_failed",
]);

/**
 * Sanitizes an OAuth error parameter to prevent open redirect attacks.
 * Returns the error if it's in the allowlist, otherwise returns a generic error.
 */
function sanitizeOAuthError(error: string | null): string | null {
  if (!error) {
    return null;
  }
  return VALID_OAUTH_ERRORS.has(error) ? error : "authentication_error";
}

function CallbackContent(): ReactElement {
  const router = useRouter();
  const searchParams = useSearchParams();
  const { refreshSession } = useAuth();

  useEffect(() => {
    async function handleCallback(): Promise<void> {
      // Check for OAuth errors
      const rawError = searchParams.get("error");
      const error = sanitizeOAuthError(rawError);
      if (error) {
        console.error("OAuth error:", rawError, searchParams.get("error_description"));
        router.push(`/login?error=${encodeURIComponent(error)}`);
        return;
      }

      // Refresh the session to load the authenticated user
      try {
        await refreshSession();
        router.push("/tasks");
      } catch (_error) {
        console.error("Session refresh failed:", _error);
        router.push("/login?error=session_failed");
      }
    }

    void handleCallback();
  }, [router, searchParams, refreshSession]);

  return (
    <div className="flex min-h-screen flex-col items-center justify-center p-8">
      <div className="text-center">
        <div className="animate-spin rounded-full h-12 w-12 border-b-2 border-gray-900 mx-auto mb-4"></div>
        <h1 className="text-2xl font-semibold mb-2">Completing authentication...</h1>
        <p className="text-gray-600">You will be redirected shortly.</p>
      </div>
    </div>
  );
}

export default function CallbackPage(): ReactElement {
  return (
    <Suspense
      fallback={
        <div className="flex min-h-screen flex-col items-center justify-center p-8">
          <div className="text-center">
            <div className="animate-spin rounded-full h-12 w-12 border-b-2 border-gray-900 mx-auto mb-4"></div>
            <h1 className="text-2xl font-semibold mb-2">Loading...</h1>
          </div>
        </div>
      }
    >
      <CallbackContent />
    </Suspense>
  );
}
