/**
 * ChartStateWrapper — shared wrapper that handles loading, error, and empty
 * states for all dashboard chart components.
 *
 * Renders the chart `children` only when the data is ready and non-empty.
 * Otherwise displays the appropriate state UI with consistent styling.
 */

import {
  Button,
  MessageBar,
  MessageBarActions,
  MessageBarBody,
  Spinner,
  Text,
  makeStyles,
  tokens,
} from "@fluentui/react-components";
import { ArrowClockwiseRegular } from "@fluentui/react-icons";

// ---------------------------------------------------------------------------
// Types
// ---------------------------------------------------------------------------

/** Props for {@link ChartStateWrapper}. */
interface ChartStateWrapperProps {
  /** True while data is loading. Shows a `<Spinner>` when active. */
  isLoading: boolean;
  /** Error message string, or `null` when no error has occurred. */
  error: string | null;
  /**
   * Callback invoked when the user clicks the "Retry" button in error state.
   * Must trigger a re-fetch in the parent component or hook.
   */
  onRetry: () => void;
  /** True when data loaded successfully but there are zero records to display. */
  isEmpty: boolean;
  /** Human-readable message shown in the empty state (default provided). */
  emptyMessage?: string;
  /** Minimum height in pixels for the state placeholder (default: 200). */
  minHeight?: number;
  /** The chart content to render when data is ready. */
  children: React.ReactNode;
}

// ---------------------------------------------------------------------------
// Constants
// ---------------------------------------------------------------------------

const DEFAULT_MIN_HEIGHT = 200;
const DEFAULT_EMPTY_MESSAGE = "No bans in this time range.";

// ---------------------------------------------------------------------------
// Styles
// ---------------------------------------------------------------------------

const useStyles = makeStyles({
  centred: {
    display: "flex",
    alignItems: "center",
    justifyContent: "center",
    width: "100%",
  },
  emptyText: {
    color: tokens.colorNeutralForeground3,
  },
});

// ---------------------------------------------------------------------------
// Component
// ---------------------------------------------------------------------------

/**
 * Wrap a chart component to provide consistent loading, error, and empty states.
 *
 * Usage:
 * ```tsx
 * <ChartStateWrapper isLoading={isLoading} error={error} onRetry={reload} isEmpty={data.length === 0}>
 *   <MyChart data={data} />
 * </ChartStateWrapper>
 * ```
 *
 * @param props - Loading/error/empty state flags and the chart children.
 */
export function ChartStateWrapper({
  isLoading,
  error,
  onRetry,
  isEmpty,
  emptyMessage = DEFAULT_EMPTY_MESSAGE,
  minHeight = DEFAULT_MIN_HEIGHT,
  children,
}: ChartStateWrapperProps): React.JSX.Element {
  const styles = useStyles();
  const placeholderStyle = { minHeight: `${String(minHeight)}px` };

  if (error != null) {
    return (
      <MessageBar intent="error">
        <MessageBarBody>{error}</MessageBarBody>
        <MessageBarActions>
          <Button
            icon={<ArrowClockwiseRegular />}
            size="small"
            onClick={onRetry}
          >
            Retry
          </Button>
        </MessageBarActions>
      </MessageBar>
    );
  }

  if (isLoading) {
    return (
      <div className={styles.centred} style={placeholderStyle}>
        <Spinner label="Loading chart data…" />
      </div>
    );
  }

  if (isEmpty) {
    return (
      <div className={styles.centred} style={placeholderStyle}>
        <Text className={styles.emptyText}>{emptyMessage}</Text>
      </div>
    );
  }

  return <>{children}</>;
}
