/* auth.jsx - Firebase Google authentication and account UI */

function friendlyAuthError(error) {
  const code = error?.code || "";
  if (code === "auth/popup-closed-by-user") return "Sign-in was cancelled.";
  if (code === "auth/unauthorized-domain") return "This domain is not authorized in Firebase Authentication.";
  if (code === "auth/network-request-failed") return "Network error. Check your connection and try again.";
  return "Google sign-in failed. Please try again.";
}

const DEMO_USER = Object.freeze({
  uid: "demo-florence",
  displayName: "Sign in",
  email: "",
  photoURL: "",
  isDemo: true,
  getIdToken: async () => "",
});

const AuthContext = React.createContext({
  user: DEMO_USER,
  loading: true,
  busy: false,
  error: "",
  signIn: async () => {},
  signOut: async () => {},
});

const LEGACY_USER_STORAGE_KEYS = [
  "mos.activeAgent",
  "mos.knowledgeSources",
  "mos.playgroundMsgs",
  "mos.chatLogs",
  "mos.integrations",
];

function userStorageKey(uid, key) {
  if (!uid) throw new Error("A signed-in user is required for user-scoped storage.");
  return `mos.users.${uid}.${key}`;
}

const ModelOSUserStorage = Object.freeze({
  load(uid, key, fallback) {
    try {
      const raw = localStorage.getItem(userStorageKey(uid, key));
      return raw == null ? fallback : JSON.parse(raw);
    } catch {
      return fallback;
    }
  },
  save(uid, key, value) {
    try { localStorage.setItem(userStorageKey(uid, key), JSON.stringify(value)); } catch {}
  },
  remove(uid, key) {
    try { localStorage.removeItem(userStorageKey(uid, key)); } catch {}
  },
  clearLegacy() {
    try { LEGACY_USER_STORAGE_KEYS.forEach((key) => localStorage.removeItem(key)); } catch {}
  },
});

window.ModelOSUserStorage = ModelOSUserStorage;

function FirebaseAuthProvider({ children }) {
  const [user, setUser] = React.useState(null);
  const [loading, setLoading] = React.useState(false);
  const [busy, setBusy] = React.useState(false);
  const [error, setError] = React.useState("");

  React.useEffect(() => {
    let unsubscribe = () => {};
    let active = true;

    window.ModelOSAuth.initialize()
      .then(async ({ auth, db, authSdk, firestoreSdk }) => {
        try {
          await authSdk.getRedirectResult(auth);
        } catch (redirectError) {
          if (active) setError(friendlyAuthError(redirectError));
        }

        unsubscribe = authSdk.onAuthStateChanged(auth, async (nextUser) => {
          if (!active) return;
          setUser(nextUser);
          setLoading(false);
          setError("");

          if (nextUser) {
            try {
              await window.ModelOSAuth.saveUserProfile(nextUser);
            } catch (profileError) {
              console.error("Failed to save Firebase user profile:", profileError);
              if (active) setError("Signed in, but the user profile could not be saved.");
            }
          }
        });
      })
      .catch((initError) => {
        console.error("Firebase initialization failed:", initError);
        if (active) {
          setError("Authentication is temporarily unavailable.");
          setLoading(false);
        }
      });

    return () => {
      active = false;
      unsubscribe();
    };
  }, []);

  const signIn = React.useCallback(async () => {
    setBusy(true);
    setError("");
    try {
      await window.ModelOSAuth.signIn();
    } catch (signInError) {
      const code = signInError?.code || "";
      if (code !== "auth/cancelled-popup-request") {
        console.error("Google sign-in failed:", signInError);
        setError(friendlyAuthError(signInError));
      }
    } finally {
      setBusy(false);
    }
  }, []);

  const signOut = React.useCallback(async () => {
    setBusy(true);
    setError("");
    try {
      await window.ModelOSAuth.signOut();
      ModelOSUserStorage.clearLegacy();
    } catch (signOutError) {
      console.error("Google sign-out failed:", signOutError);
      setError("Sign-out failed. Please try again.");
    } finally {
      setBusy(false);
    }
  }, []);

  const effectiveUser = user || DEMO_USER;

  return (
    <AuthContext.Provider value={{ user: effectiveUser, realUser: user, loading, busy, error, signIn, signOut }}>
      {children}
    </AuthContext.Provider>
  );
}

function SignInGate() {
  if (typeof WorkspaceApp === "function") {
    return <WorkspaceApp key={DEMO_USER.uid} user={DEMO_USER} />;
  }
  return <main className="app" style={{ minHeight: "100vh", display: "grid", placeItems: "center" }}><span className="auth-spinner" /></main>;
}

function useFirebaseAuth() {
  return React.useContext(AuthContext);
}

function GoogleMark(props) {
  return (
    <svg viewBox="0 0 24 24" aria-hidden="true" {...props}>
      <path fill="#4285F4" d="M21.6 12.2c0-.7-.1-1.4-.2-2H12v3.8h5.4a4.6 4.6 0 0 1-2 3v2.5h3.2c1.9-1.8 3-4.3 3-7.3Z" />
      <path fill="#34A853" d="M12 22c2.7 0 5-.9 6.6-2.4L15.4 17c-.9.6-2 1-3.4 1-2.6 0-4.8-1.8-5.6-4.1H3.1v2.6A10 10 0 0 0 12 22Z" />
      <path fill="#FBBC05" d="M6.4 13.9A6 6 0 0 1 6.1 12c0-.7.1-1.3.3-1.9V7.5H3.1A10 10 0 0 0 2 12c0 1.6.4 3.1 1.1 4.5l3.3-2.6Z" />
      <path fill="#EA4335" d="M12 6c1.5 0 2.8.5 3.8 1.5l2.9-2.8A9.7 9.7 0 0 0 12 2a10 10 0 0 0-8.9 5.5l3.3 2.6C7.2 7.8 9.4 6 12 6Z" />
    </svg>
  );
}

function AccountMenu() {
  const { user, loading, busy, error, signIn, signOut } = useFirebaseAuth();
  const [open, setOpen] = React.useState(false);
  const menuRef = React.useRef(null);

  React.useEffect(() => {
    const close = (event) => {
      if (menuRef.current && !menuRef.current.contains(event.target)) setOpen(false);
    };
    document.addEventListener("pointerdown", close);
    return () => document.removeEventListener("pointerdown", close);
  }, []);

  if (loading) {
    return <div className="auth-loading" aria-label="Loading account"><span className="auth-spinner" /></div>;
  }

  if (!user) {
    return (
      <div className="auth-entry">
        <button className="btn btn-secondary auth-signin" onClick={signIn} disabled={busy}>
          <GoogleMark />
          {busy ? "Signing in..." : "Sign in"}
        </button>
        {error && <div className="auth-error" role="alert">{error}</div>}
      </div>
    );
  }

  if (user.isDemo) {
    return (
      <div className="account-menu" ref={menuRef}>
        <button className="account-trigger" onClick={() => setOpen((value) => !value)}
                aria-haspopup="menu" aria-expanded={open}>
          <span className="avatar"><GoogleMark style={{ width: 15, height: 15 }} /></span>
          <span className="account-name">Sign in</span>
          {I("chevD", { style: { width: 14, height: 14 } })}
        </button>
        {open && (
          <div className="account-popover" role="menu">
            <div className="account-profile">
              <b>Sign in to Model OS</b>
              <span className="auth-hint">Connect Google to save your bots, files, and deployments.</span>
            </div>
            <div className="divider" />
            <button role="menuitem" onClick={() => { setOpen(false); signIn(); }} disabled={busy}>
              <GoogleMark style={{ width: 15, height: 15, flex: "none" }} />
              {busy ? "Connecting..." : "Connect Google"}
            </button>
            {error && <div className="auth-error inline" role="alert">{error}</div>}
          </div>
        )}
      </div>
    );
  }

  const initials = (user.displayName || user.email || "U")
    .split(/\s+/)
    .map((part) => part[0])
    .join("")
    .slice(0, 2)
    .toUpperCase();

  return (
    <div className="account-menu" ref={menuRef}>
      <button className="account-trigger" onClick={() => setOpen((value) => !value)}
              aria-haspopup="menu" aria-expanded={open}>
        {user.photoURL ? <img src={user.photoURL} alt="" referrerPolicy="no-referrer" /> : <span className="avatar">{initials}</span>}
        <span className="account-name">{user.displayName || user.email}</span>
        {I("chevD", { style: { width: 14, height: 14 } })}
      </button>
      {open && (
        <div className="account-popover" role="menu">
          <div className="account-profile">
            <b>{user.displayName || "Model OS user"}</b>
            <span>{user.email}</span>
          </div>
          <div className="divider" />
          <button role="menuitem" onClick={() => { setOpen(false); signOut(); }} disabled={busy}>
            {I("logout", { style: { width: 15, height: 15 } })}
            {busy ? "Signing out..." : "Sign out"}
          </button>
          {error && <div className="auth-error inline" role="alert">{error}</div>}
        </div>
      )}
    </div>
  );
}

Object.assign(window, {
  FirebaseAuthProvider,
  useFirebaseAuth,
  AccountMenu,
  SignInGate,
  DEMO_USER,
  initializeFirebase: () => window.ModelOSAuth.initialize(),
});
