// @File: src/pages/OAuthCallback.tsx
// @Desc: Landing page for the social-login redirect. The backend's
//        /api/v1/auth/oauth/:provider/callback handler 302-redirects the
//        browser here with the app JWT embedded in the URL **fragment**
//        (never the query string) so the token is never captured by server
//        access logs, proxies, or Referer headers.
//
//        Expected URL shape on success:
//          /auth/oauth/callback#token=<jwt>&needs_profile=0
//        On error:
//          /auth/oauth/callback?error=<code>
//
//        We parse the fragment, call `setSession()` from lib/auth so the
//        rest of the app treats this exactly like an email/password login,
//        then redirect to /client (or /client?complete_profile=1 for brand
//        new accounts).
import { useEffect, useState } from "react";
import { useNavigate } from "react-router-dom";
import { setSession, fetchMe } from "@/lib/auth";

// Map backend error codes to friendly messages.
const ERROR_MESSAGES: Record<string, string> = {
  access_denied: "You cancelled the sign-in. Please try again if you'd like to continue.",
  consent_required: "Sign-in was cancelled before access was granted.",
  invalid_state: "This sign-in link has expired or already been used. Please start again.",
  state_expired: "The sign-in took too long to complete. Please try again.",
  state_provider_mismatch: "Something went wrong during sign-in. Please try again.",
  missing_code_or_state: "The provider did not return a valid sign-in response. Please try again.",
  token_exchange_failed: "We couldn't verify your sign-in with the provider. Please try again.",
  id_token_verification_failed: "Your social profile could not be verified. Please try another method.",
  email_not_verified: "Your social account's email is not verified. Please verify it at the provider first.",
  missing_email: "Your social profile doesn't expose an email address. Please use email sign-in instead.",
  whmcs_unavailable: "Our account system is temporarily unavailable. Please try again in a moment.",
  whmcs_add_client_failed: "We couldn't create your account just now. Please try again or contact support.",
  unexpected_error: "An unexpected error occurred. Please try again.",
  missing_token: "Sign-in response was incomplete. Please try again.",
};

function parseFragment(hash: string): Record<string, string> {
  const out: Record<string, string> = {};
  const raw = hash.startsWith("#") ? hash.slice(1) : hash;
  if (!raw) return out;
  for (const part of raw.split("&")) {
    if (!part) continue;
    const eq = part.indexOf("=");
    if (eq === -1) {
      out[decodeURIComponent(part)] = "";
    } else {
      out[decodeURIComponent(part.slice(0, eq))] = decodeURIComponent(part.slice(eq + 1));
    }
  }
  return out;
}

export default function OAuthCallback() {
  const navigate = useNavigate();
  const [status, setStatus] = useState<"working" | "error">("working");
  const [message, setMessage] = useState<string>("Completing sign-in…");

  useEffect(() => {
    let cancelled = false;

    (async () => {
      try {
        // Error path: backend put ?error=<code> on the query string.
        const query = new URLSearchParams(window.location.search);
        const errorCode = query.get("error");
        if (errorCode) {
          const friendly =
            ERROR_MESSAGES[errorCode] ||
            "We couldn't complete the social sign-in. Please try again.";
          if (!cancelled) {
            setStatus("error");
            setMessage(friendly);
          }
          // Send the user back to /login after a short pause so they can read the message.
          window.setTimeout(() => {
            if (!cancelled) navigate(`/login?error=${encodeURIComponent(errorCode)}`, { replace: true });
          }, 2500);
          return;
        }

        // Success path: backend put the token into the URL fragment.
        const frag = parseFragment(window.location.hash);
        const token = frag.token || "";
        const needsProfile = frag.needs_profile === "1";
        if (!token) {
          if (!cancelled) {
            setStatus("error");
            setMessage(ERROR_MESSAGES.missing_token);
          }
          window.setTimeout(() => {
            if (!cancelled) navigate("/login?error=missing_token", { replace: true });
          }, 2500);
          return;
        }

        // Resolve a minimal session shape from the app's own /me endpoint so
        // we don't try to decode the JWT in the browser. fetchMe() uses the
        // token we're about to store, so we need to write it first.
        setSession({
          token,
          user_id: "",
          email: "",
          name: null,
          client_id: 0,
        });

        // Strip the fragment from the URL so the token is never captured by
        // history, screenshots, or analytics that scrape `location.hash`.
        try {
          window.history.replaceState(null, "", window.location.pathname);
        } catch {
          /* ignore */
        }

        // Hydrate the full session with the real identity info.
        try {
          const me = await fetchMe();
          if (me && me.email) {
            setSession({
              token,
              user_id: me.user_id || "",
              email: me.email,
              name: me.name ?? null,
              client_id: me.client_id ?? 0,
            });
          }
        } catch {
          // Non-fatal — the app will fall back to fetching /me on demand.
        }

        if (cancelled) return;
        setMessage("Signed in! Redirecting…");
        const target = needsProfile ? "/client?complete_profile=1" : "/client";
        navigate(target, { replace: true });
      } catch (err) {
        if (cancelled) return;
        setStatus("error");
        setMessage(
          err instanceof Error
            ? err.message
            : "We couldn't complete the sign-in. Please try again.",
        );
        window.setTimeout(() => {
          if (!cancelled) navigate("/login?error=unexpected_error", { replace: true });
        }, 2500);
      }
    })();

    return () => {
      cancelled = true;
    };
  }, [navigate]);

  return (
    <div className="flex min-h-screen items-center justify-center bg-gradient-to-br from-slate-50 via-white to-blue-50 px-4">
      <div className="w-full max-w-md rounded-2xl border border-slate-200 bg-white p-8 text-center shadow-lg">
        {status === "working" ? (
          <>
            <div className="mx-auto mb-5 h-12 w-12 animate-spin rounded-full border-4 border-blue-200 border-t-blue-600" />
            <h1 className="mb-2 text-xl font-semibold text-slate-900">Finishing your sign-in</h1>
            <p className="text-sm text-slate-600">{message}</p>
          </>
        ) : (
          <>
            <div className="mx-auto mb-5 flex h-12 w-12 items-center justify-center rounded-full bg-rose-100 text-rose-600">
              <svg
                xmlns="http://www.w3.org/2000/svg"
                viewBox="0 0 24 24"
                fill="none"
                stroke="currentColor"
                strokeWidth="2"
                strokeLinecap="round"
                strokeLinejoin="round"
                className="h-6 w-6"
              >
                <circle cx="12" cy="12" r="10" />
                <line x1="12" y1="8" x2="12" y2="12" />
                <line x1="12" y1="16" x2="12.01" y2="16" />
              </svg>
            </div>
            <h1 className="mb-2 text-xl font-semibold text-slate-900">Sign-in didn't complete</h1>
            <p className="text-sm text-slate-600">{message}</p>
            <p className="mt-4 text-xs text-slate-400">Redirecting you back to the login page…</p>
          </>
        )}
      </div>
    </div>
  );
}