/**
 * Route guard component.
 *
 * Protects all routes by ensuring the initial setup wizard has been
 * completed.  If setup is not done yet, the user is redirected to `/setup`.
 * While the status is loading a full-screen spinner is shown.
 */

import { Navigate } from "react-router-dom";
import {
  Button,
  MessageBar,
  MessageBarBody,
  Spinner,
  makeStyles,
  tokens,
} from "@fluentui/react-components";
import { useSetup } from "../hooks/useSetup";

/**
 * Component is intentionally simple; status load is handled by the hook.
 */

interface SetupGuardProps {
  /** The protected content to render when setup is complete. */
  children: React.JSX.Element;
}

/**
 * Render `children` only when setup has been completed.
 *
 * Redirects to `/setup` only when setup status is known and incomplete.
 */
const useStyles = makeStyles({
  loadingWrapper: {
    display: "flex",
    justifyContent: "center",
    alignItems: "center",
    minHeight: "100vh",
  },
  errorContainer: {
    display: "flex",
    justifyContent: "center",
    alignItems: "center",
    minHeight: "100vh",
    padding: tokens.spacingHorizontalM,
    backgroundColor: tokens.colorNeutralBackground2,
  },
  errorCard: {
    width: "100%",
    maxWidth: "520px",
    display: "flex",
    flexDirection: "column",
    gap: tokens.spacingVerticalM,
    padding: tokens.spacingVerticalL,
    backgroundColor: tokens.colorNeutralBackground1,
    borderRadius: tokens.borderRadiusXLarge,
    boxShadow: tokens.shadow8,
  },
});

export function SetupGuard({ children }: SetupGuardProps): React.JSX.Element {
  const styles = useStyles();
  const { status, loading, error, refresh } = useSetup();

  if (loading) {
    return (
      <div className={styles.loadingWrapper}>
        <Spinner size="large" label="Loading…" />
      </div>
    );
  }

  if (error && status === null) {
    return (
      <div className={styles.errorContainer}>
        <div className={styles.errorCard}>
          <MessageBar intent="error">
            <MessageBarBody>{error}</MessageBarBody>
          </MessageBar>
          <Button appearance="primary" onClick={() => void refresh()}>
            Retry
          </Button>
        </div>
      </div>
    );
  }

  if (!status?.completed) {
    return <Navigate to="/setup" replace />;
  }

  return children;
}
