/**
 * AutoSaveIndicator — small status chip showing auto-save state.
 *
 * Displays nothing while idle, a spinner while saving, a transient
 * "Saved" checkmark on success, and an error message with retry on failure.
 *
 * Always renders an ``aria-live`` region so screen readers receive
 * status change announcements even when the visible badge is absent.
 */

import { useEffect, useState } from "react";
import {
  Badge,
  Button,
  Spinner,
  Text,
  tokens,
} from "@fluentui/react-components";
import { Checkmark16Regular } from "@fluentui/react-icons";

/** Current save state driven by the parent (typically useAutoSave). */
export type AutoSaveStatus = "idle" | "saving" | "saved" | "error";

export interface AutoSaveIndicatorProps {
  /** Current save status. */
  status: AutoSaveStatus;
  /** Error text shown when status is "error". */
  errorText?: string | null;
  /** Called when the user clicks the retry link. */
  onRetry?: () => void;
}

/** Fade-out delay after "saved" status in milliseconds. */
const SAVED_FADE_DELAY_MS = 2000;

/**
 * Compact inline indicator for auto-save state.
 *
 * @param props - Component props.
 * @returns JSX element.
 */
export function AutoSaveIndicator({
  status,
  errorText,
  onRetry,
}: AutoSaveIndicatorProps): React.JSX.Element {
  const [fadingOut, setFadingOut] = useState(false);

  // Trigger the fade-out transition 2 s after the saved state is reached.
  useEffect((): (() => void) | undefined => {
    if (status !== "saved") {
      setFadingOut(false);
      return undefined;
    }
    const timer = window.setTimeout(() => {
      setFadingOut(true);
    }, SAVED_FADE_DELAY_MS);
    return () => {
      window.clearTimeout(timer);
    };
  }, [status]);

  // Always render the aria-live region so screen readers track changes.
  return (
    <span
      aria-live="polite"
      role="status"
      style={{
        display: "inline-flex",
        alignItems: "center",
        gap: tokens.spacingHorizontalXS,
        minWidth: 80,
      }}
    >
      {status === "saving" && (
        <>
          <Spinner size="extra-tiny" />
          <Text size={200} style={{ color: tokens.colorNeutralForeground2 }}>
            Saving…
          </Text>
        </>
      )}

      {status === "saved" && (
        <span
          style={{
            opacity: fadingOut ? 0 : 1,
            transform: fadingOut ? "scale(0.95)" : "scale(1)",
            transition: `opacity ${tokens.durationNormal} ${tokens.curveDecelerateMid}, transform ${tokens.durationNormal} ${tokens.curveDecelerateMid}`,
            animationName: fadingOut ? undefined : "fadeInScale",
            animationDuration: tokens.durationFast,
            animationTimingFunction: tokens.curveDecelerateMid,
            animationFillMode: "both",
          }}
        >
          <Badge
            appearance="tint"
            color="success"
            icon={<Checkmark16Regular />}
            size="small"
          >
            Saved
          </Badge>
        </span>
      )}

      {status === "error" && (
        <>
          <Text
            size={200}
            style={{ color: tokens.colorPaletteRedForeground3 }}
          >
            {errorText ?? "Save failed."}
          </Text>
          {onRetry && (
            <Button appearance="transparent" size="small" onClick={onRetry}>
              Retry
            </Button>
          )}
        </>
      )}
    </span>
  );
}
