import { FunctionComponent, ReactNode } from 'react';
import ErrorState from '../ErrorState';

export interface QueryStateGateProps {
  isLoading: boolean;
  isError: boolean;
  onRetry: () => void;
  isEmpty: boolean;
  /** Already-translated, page-specific error copy — passed straight to `ErrorState`. */
  errorMessage: string;
  /** Already-translated retry label — passed straight to `ErrorState` (e.g. `t('common.retry')`). */
  retryLabel: string;
  /** Rendered while `isLoading` — pass a shaped skeleton, not a bare spinner. */
  skeleton: ReactNode;
  /** Rendered when the query succeeded but returned nothing. */
  empty: ReactNode;
  children: ReactNode;
}

/**
 * The convention this phase exists to enforce, as one component: **an errored query must never render
 * as empty**. Branches in a fixed order — skeleton → error (with a mandatory retry, via `ErrorState`) →
 * empty → data — so a page can't accidentally check `isEmpty` before `isError` and show "no results" for
 * a network failure. Pages with naturally inline branching (infinite lists with `fetchNextPage`) may
 * follow the same order by hand instead of reaching for this component; the convention is what matters.
 * @component QueryStateGate
 */
const QueryStateGate: FunctionComponent<QueryStateGateProps> = ({
  isLoading,
  isError,
  onRetry,
  isEmpty,
  errorMessage,
  retryLabel,
  skeleton,
  empty,
  children,
}) => {
  if (isLoading) return <>{skeleton}</>;
  if (isError) return <ErrorState message={errorMessage} retryLabel={retryLabel} onRetry={onRetry} />;
  if (isEmpty) return <>{empty}</>;
  return <>{children}</>;
};

export default QueryStateGate;
