"use client";

import { useEffect, useRef, useState } from "react";
import { googleSignIn, type User } from "@/lib/api/auth";
import { FormAlert, readError } from "./Form";

const CLIENT_ID = process.env.NEXT_PUBLIC_GOOGLE_CLIENT_ID;

type Gsi = {
  accounts: {
    id: {
      initialize: (o: { client_id: string; callback: (r: { credential: string }) => void }) => void;
      renderButton: (el: HTMLElement, o: Record<string, string | number>) => void;
    };
  };
};

let script: Promise<void> | null = null;
const loadGsi = () =>
  (script ??= new Promise<void>((resolve, reject) => {
    const s = document.createElement("script");
    s.src = "https://accounts.google.com/gsi/client";
    s.async = true;
    s.onload = () => resolve();
    s.onerror = () => {
      script = null;
      reject(new Error("Google sign-in could not load."));
    };
    document.head.appendChild(s);
  }));

/**
 * "Continue with Google" via Google Identity Services. The ID token goes to `auth/google`.
 * Hidden until NEXT_PUBLIC_GOOGLE_CLIENT_ID is set (the backend needs the same GOOGLE_CLIENT_ID).
 */
export default function GoogleButton({ onSignedIn }: { onSignedIn: (token: string, user: User) => void }) {
  const box = useRef<HTMLDivElement>(null);
  const [error, setError] = useState<string | null>(null);

  useEffect(() => {
    if (!CLIENT_ID) return;
    let live = true;
    loadGsi()
      .then(() => {
        const g = (window as unknown as { google?: Gsi }).google;
        if (!live || !g || !box.current) return;
        g.accounts.id.initialize({
          client_id: CLIENT_ID,
          callback: async ({ credential }) => {
            setError(null);
            try {
              const s = await googleSignIn(credential);
              onSignedIn(s.token, s.user);
            } catch (err) {
              setError(readError(err).message ?? "Google sign-in failed. Please try again.");
            }
          },
        });
        g.accounts.id.renderButton(box.current, { theme: "outline", size: "large", shape: "pill", text: "continue_with", width: box.current.offsetWidth || 320 });
      })
      .catch((e: Error) => live && setError(e.message));
    return () => {
      live = false;
    };
  }, [onSignedIn]);

  if (!CLIENT_ID) return null;
  return (
    <div className="acct-google">
      <p className="acct-or">
        <span>or</span>
      </p>
      <div ref={box} className="acct-google-btn" />
      {error && <FormAlert>{error}</FormAlert>}
    </div>
  );
}
