// @File: src/components/auth/SocialLoginButtons.tsx
// @Desc: Reusable "Continue with Google / Microsoft / LinkedIn" button row for
//        the Login and Register pages. The buttons simply navigate the browser
//        (full page) to the backend's /api/v1/auth/oauth/:provider/start
//        endpoint, which then 302-redirects to the provider's own consent
//        screen. After the user consents, the provider redirects back to our
//        /api/v1/auth/oauth/:provider/callback endpoint, which finishes the
//        flow and lands the browser on /auth/oauth/callback with the JWT.
//
//        We query /api/v1/auth/oauth/providers on mount to learn which
//        providers are actually configured on this deployment, and disable
//        any button whose credentials aren't set yet.
import { useEffect, useState } from "react";

interface ProviderInfo {
  slug: string;
  display_name: string;
  configured: boolean;
}

interface Props {
  mode?: "login" | "register";
  /** Shown above the button row. Pass null to hide the divider. */
  dividerLabel?: string | null;
  className?: string;
}

// Inline SVG brand marks — keeps us off any icon-font dependency and keeps
// each logo visually authentic without pulling in a large icon pack.
function GoogleMark() {
  return (
    <svg viewBox="0 0 24 24" className="h-5 w-5" aria-hidden="true">
      <path
        fill="#EA4335"
        d="M12 10.2v3.9h5.5c-.24 1.4-1.68 4.1-5.5 4.1-3.32 0-6.02-2.75-6.02-6.2S8.68 5.8 12 5.8c1.88 0 3.14.8 3.86 1.49l2.63-2.54C16.84 3.21 14.65 2.2 12 2.2 6.9 2.2 2.8 6.3 2.8 12S6.9 21.8 12 21.8c6.9 0 9.2-4.85 9.2-7.35 0-.49-.05-.86-.12-1.25H12z"
      />
    </svg>
  );
}

function MicrosoftMark() {
  return (
    <svg viewBox="0 0 24 24" className="h-5 w-5" aria-hidden="true">
      <rect x="2" y="2" width="9" height="9" fill="#F25022" />
      <rect x="13" y="2" width="9" height="9" fill="#7FBA00" />
      <rect x="2" y="13" width="9" height="9" fill="#00A4EF" />
      <rect x="13" y="13" width="9" height="9" fill="#FFB900" />
    </svg>
  );
}

function LinkedInMark() {
  return (
    <svg viewBox="0 0 24 24" className="h-5 w-5" aria-hidden="true">
      <rect width="24" height="24" rx="4" fill="#0A66C2" />
      <path
        fill="#fff"
        d="M7.1 9.4H4.8v8h2.3v-8zM5.95 6.4a1.35 1.35 0 1 1 0 2.7 1.35 1.35 0 0 1 0-2.7zM9.3 9.4h2.2v1.1h.03c.31-.58 1.07-1.2 2.2-1.2 2.35 0 2.78 1.55 2.78 3.56v4.54h-2.3v-4.03c0-.96-.02-2.2-1.34-2.2-1.34 0-1.55 1.05-1.55 2.13v4.1H9.3v-8z"
      />
    </svg>
  );
}

const MARKS: Record<string, () => JSX.Element> = {
  google: GoogleMark,
  microsoft: MicrosoftMark,
  linkedin: LinkedInMark,
};

export default function SocialLoginButtons({
  mode = "login",
  dividerLabel = "or continue with",
  className = "",
}: Props) {
  const [providers, setProviders] = useState<ProviderInfo[]>([]);
  const [loading, setLoading] = useState(true);
  const [clicked, setClicked] = useState<string | null>(null);

  useEffect(() => {
    let cancelled = false;
    (async () => {
      try {
        const res = await fetch("/api/v1/auth/oauth/providers", {
          headers: { Accept: "application/json" },
        });
        if (!res.ok) throw new Error(`HTTP ${res.status}`);
        const data: ProviderInfo[] = await res.json();
        if (!cancelled && Array.isArray(data)) setProviders(data);
      } catch {
        // Render a disabled-row fallback so the UI still explains what's
        // coming — users see the option exists, and we log nothing.
        if (!cancelled) {
          setProviders([
            { slug: "google", display_name: "Google", configured: false },
            { slug: "microsoft", display_name: "Microsoft", configured: false },
            { slug: "linkedin", display_name: "LinkedIn", configured: false },
          ]);
        }
      } finally {
        if (!cancelled) setLoading(false);
      }
    })();
    return () => {
      cancelled = true;
    };
  }, []);

  const onClick = (slug: string, configured: boolean) => {
    if (!configured || clicked) return;
    setClicked(slug);
    const url = `/api/v1/auth/oauth/${encodeURIComponent(slug)}/start?mode=${encodeURIComponent(mode)}`;
    // Full-page navigation is required: the endpoint returns a 302 to the
    // provider's authorize page, which a fetch() call cannot follow.
    window.location.assign(url);
  };

  // Nothing at all configured? Still render the row so UI doesn't jump; just
  // keep everything disabled with a helpful tooltip.
  const visible = providers.length
    ? providers
    : [
        { slug: "google", display_name: "Google", configured: false },
        { slug: "microsoft", display_name: "Microsoft", configured: false },
        { slug: "linkedin", display_name: "LinkedIn", configured: false },
      ];

  return (
    <div className={className}>
      {dividerLabel && (
        <div className="relative my-5">
          <div className="absolute inset-0 flex items-center" aria-hidden="true">
            <div className="w-full border-t border-slate-200" />
          </div>
          <div className="relative flex justify-center text-xs">
            <span className="bg-white px-3 uppercase tracking-wider text-slate-400">
              {dividerLabel}
            </span>
          </div>
        </div>
      )}
      <div className="grid grid-cols-1 gap-2.5 sm:grid-cols-3">
        {visible.map((p) => {
          const Mark = MARKS[p.slug] || GoogleMark;
          const disabled = loading || !p.configured || (clicked !== null && clicked !== p.slug);
          const isLoading = clicked === p.slug;
          return (
            <button
              key={p.slug}
              type="button"
              disabled={disabled}
              onClick={() => onClick(p.slug, p.configured)}
              title={
                p.configured
                  ? `Continue with ${p.display_name}`
                  : `${p.display_name} sign-in is not configured yet`
              }
              className={[
                "group relative flex items-center justify-center gap-2",
                "rounded-lg border border-slate-200 bg-white px-4 py-2.5 text-sm font-medium text-slate-700",
                "transition-all duration-150",
                "hover:border-slate-300 hover:bg-slate-50 hover:shadow-sm",
                "focus:outline-none focus:ring-2 focus:ring-blue-500 focus:ring-offset-1",
                "disabled:cursor-not-allowed disabled:opacity-60 disabled:hover:bg-white disabled:hover:shadow-none",
              ].join(" ")}
              aria-label={`Continue with ${p.display_name}`}
            >
              {isLoading ? (
                <span className="h-5 w-5 animate-spin rounded-full border-2 border-slate-300 border-t-slate-700" />
              ) : (
                <Mark />
              )}
              <span className="truncate">
                {isLoading ? "Redirecting…" : p.display_name}
              </span>
            </button>
          );
        })}
      </div>
    </div>
  );
}