/**
 * Shared user accounts (Firebase Authentication), sitting alongside the
 * existing code-based cross-device sync in cloud-sync.jsx. Same Firebase
 * project, same free tier - reuses FIREBASE_CONFIG and the
 * loadFirebaseScript()/ensureFirebaseAppInitialized() helpers cloud-sync.jsx
 * already defines (this file must load AFTER cloud-sync.jsx, and only
 * `var`-safe/plain function declarations are used at top level for the same
 * shared-sibling-script-scope reason documented at the top of navbar.jsx).
 *
 * Unlike cloud-sync.jsx's lazy, opt-in Firestore load (most visitors never
 * touch manual sync codes), the Auth SDK loads on every page load here -
 * navbar.jsx needs to know sign-in state immediately to render "Sign In" vs
 * the account icon, and that's now a site-wide feature rather than an
 * opt-in one.
 *
 * Setup (one-time, in the Firebase console, same project cloud-sync.jsx's
 * comment already walks through):
 * 1. Authentication -> Sign-in method -> enable "Email/Password" and "Google".
 * 2. Authentication -> Settings -> Authorized domains -> add the live site's
 *    domain (needed for Google sign-in's redirect/popup to be trusted).
 */

const FIREBASE_AUTH_URL = `https://www.gstatic.com/firebasejs/${FIREBASE_SDK_VERSION}/firebase-auth-compat.js`;

// Auth-compat only - checks window.firebase.auth specifically (not just
// window.firebase) since cloud-sync.jsx may have already loaded the app
// compat script alone, or together with Firestore's, on this same page.
const loadFirebaseAuthSdk = async () => {
    await loadFirebaseScript(FIREBASE_APP_URL);
    if (!window.firebase.auth) await loadFirebaseScript(FIREBASE_AUTH_URL);
};

let firebaseAuthInstance = null;
const getFirebaseAuthInstance = () => {
    if (firebaseAuthInstance) return firebaseAuthInstance;
    if (!window.firebase || !window.firebase.auth) return null;
    try {
        if (!ensureFirebaseAppInitialized()) return null;
        firebaseAuthInstance = window.firebase.auth();
        return firebaseAuthInstance;
    } catch (e) {
        console.warn("Firebase Auth init failed:", e.message);
        return null;
    }
};

// Wraps a signUp/logIn/Google-popup promise so every caller gets the same
// { ok, user, isNewUser, error, code } shape rather than a raw Firebase
// UserCredential/error - isNewUser (from Firebase's own
// additionalUserInfo, present for both email/password and Google sign-in)
// is what a later phase uses to decide whether cloud-sync's connect()
// should seed a brand-new synced library from this device's local data, or
// pull+merge an existing one.
const wrapAuthResult = (credentialPromise) => credentialPromise
    .then((cred) => ({
        ok: true,
        user: cred.user,
        isNewUser: !!(cred.additionalUserInfo && cred.additionalUserInfo.isNewUser)
    }))
    .catch((err) => ({ ok: false, error: err, code: err && err.code }));

/**
 * useAuth() - site-wide Firebase Authentication state + actions.
 *
 * Returns { user, authReady, signUp, logIn, logInWithGoogle, logOut,
 * resetPassword, getIdToken }.
 *
 *   user      - undefined until authReady, then either a Firebase User
 *               object (signed in) or null (signed out).
 *   authReady - true once the SDK has loaded and Firebase has reported the
 *               real starting auth state (restored from its own persisted
 *               session, or confirmed signed-out) - lets callers avoid a
 *               "flash of signed out" before the real state is known.
 */
function useAuth() {
    const [user, setUser] = useState(undefined);
    const [authReady, setAuthReady] = useState(false);

    useEffect(() => {
        let unsubscribe = null;
        let cancelled = false;
        loadFirebaseAuthSdk().then(() => {
            if (cancelled) return;
            const auth = getFirebaseAuthInstance();
            if (!auth) { setUser(null); setAuthReady(true); return; }
            unsubscribe = auth.onAuthStateChanged((firebaseUser) => {
                setUser(firebaseUser);
                setAuthReady(true);
            });
        }).catch((err) => {
            console.warn("Auth: couldn't load Firebase Auth SDK:", err.message);
            setUser(null);
            setAuthReady(true);
        });
        return () => {
            cancelled = true;
            if (unsubscribe) unsubscribe();
        };
    }, []);

    const signUp = (email, password) => {
        const auth = getFirebaseAuthInstance();
        if (!auth) return Promise.resolve({ ok: false, code: 'not-configured' });
        return wrapAuthResult(auth.createUserWithEmailAndPassword(email, password));
    };

    const logIn = (email, password) => {
        const auth = getFirebaseAuthInstance();
        if (!auth) return Promise.resolve({ ok: false, code: 'not-configured' });
        return wrapAuthResult(auth.signInWithEmailAndPassword(email, password));
    };

    const logInWithGoogle = () => {
        const auth = getFirebaseAuthInstance();
        if (!auth) return Promise.resolve({ ok: false, code: 'not-configured' });
        return wrapAuthResult(auth.signInWithPopup(new firebase.auth.GoogleAuthProvider()));
    };

    const logOut = () => {
        const auth = getFirebaseAuthInstance();
        return auth ? auth.signOut() : Promise.resolve();
    };

    const resetPassword = (email) => {
        const auth = getFirebaseAuthInstance();
        if (!auth) return Promise.reject(new Error('not-configured'));
        return auth.sendPasswordResetEmail(email);
    };

    // Used by a later phase to authenticate GET /account/data - not called
    // by anything in this phase yet.
    const getIdToken = () => {
        const auth = getFirebaseAuthInstance();
        if (!auth || !auth.currentUser) return Promise.resolve(null);
        return auth.currentUser.getIdToken();
    };

    return { user, authReady, signUp, logIn, logInWithGoogle, logOut, resetPassword, getIdToken };
}

// Friendly text for Firebase Auth's own error codes - its default messages
// ("Firebase: Error (auth/email-already-in-use).") aren't fit to show a
// customer directly.
const AUTH_ERROR_MESSAGES = {
    'auth/email-already-in-use': "An account already exists for that email - try signing in instead.",
    'auth/invalid-email': "That doesn't look like a valid email address.",
    'auth/weak-password': "Choose a password with at least 6 characters.",
    'auth/wrong-password': "Incorrect password - try again, or reset it below.",
    'auth/invalid-credential': "Incorrect email or password.",
    'auth/user-not-found': "No account found for that email.",
    'auth/too-many-requests': "Too many attempts - please wait a moment and try again.",
    'auth/popup-closed-by-user': "Google sign-in was cancelled.",
    'auth/network-request-failed': "Couldn't reach the server - check your connection and try again.",
    'not-configured': "Accounts aren't set up yet - check the Firebase config in auth.jsx."
};
const authErrorMessage = (code) => AUTH_ERROR_MESSAGES[code] || "Something went wrong - please try again.";
