import { type CSSProperties, type ReactNode } from 'react';

export type ImageGenStatus = 'idle' | 'streaming' | 'complete' | 'error';

export interface ImageGenSnapshot {
  /** Progress 0..1. */
  progress: number;
  /** Optional partial image URL (e.g. data: or blob:). */
  partialUrl?: string;
  /** Step label (e.g. "denoising 24/50"). */
  label?: string;
}

export interface ImageGenStreamProps {
  /** Live status. */
  status: ImageGenStatus;
  /** Latest snapshot from the upstream stream. */
  snapshot?: ImageGenSnapshot;
  /** Final image URL (rendered when status === 'complete'). */
  finalUrl?: string;
  /** Optional error message (rendered when status === 'error'). */
  errorMessage?: string;
  /** Aspect ratio (w/h). Default 1 (square). */
  aspect?: number;
  /** Width in px. Default 320. */
  width?: number;
  /** Optional caption slot. */
  caption?: ReactNode;
  ariaLabel?: string;
  className?: string;
  style?: CSSProperties;
}

/**
 * `<ImageGenStream>` — surface that animates a streaming image-generation
 * job. Driven entirely by props; the host pipes whatever transport
 * (SSE / WebSocket / polling) into the `status` + `snapshot` props.
 *
 * Wave 13.G.1. Pure presentation. Status drives visual:
 *   - idle:       empty placeholder with helpful copy
 *   - streaming:  partial image + progress bar + label
 *   - complete:   final image with subtle fade-in
 *   - error:      muted error card
 */
export function ImageGenStream({
  status,
  snapshot,
  finalUrl,
  errorMessage,
  aspect = 1,
  width = 320,
  caption,
  ariaLabel,
  className,
  style,
}: ImageGenStreamProps) {
  const height = Math.round(width / Math.max(0.1, aspect));
  const progress = Math.max(0, Math.min(1, snapshot?.progress ?? 0));
  // Pick the visible source: prefer the final URL when complete, otherwise
  // the partial. If neither is supplied yet the host gets the placeholder
  // shell — never an <img> with `src={undefined}` (browser broken-image).
  const visibleSrc =
    status === 'complete'
      ? finalUrl ?? snapshot?.partialUrl
      : status === 'streaming'
        ? snapshot?.partialUrl
        : undefined;

  return (
    <figure
      data-testid="bl-image-gen-stream"
      data-status={status}
      className={className}
      style={{
        margin: 0,
        display: 'inline-flex',
        flexDirection: 'column',
        gap: 8,
        ...style,
      }}
      aria-label={ariaLabel}
    >
      <div
        style={{
          position: 'relative',
          width,
          height,
          borderRadius: 14,
          overflow: 'hidden',
          background: 'var(--bl-surface-muted, rgba(0,0,0,0.06))',
          border: '1px solid var(--bl-border-subtle, rgba(0,0,0,0.06))',
        }}
      >
        {status === 'idle' && (
          <Placeholder text="Ready to generate." />
        )}
        {(status === 'streaming' || status === 'complete') &&
          (visibleSrc ? (
            <img
              src={visibleSrc}
              alt={ariaLabel ?? 'Generated image'}
              data-testid="bl-image-gen-stream-img"
              style={{
                width: '100%',
                height: '100%',
                objectFit: 'cover',
                filter: status === 'streaming' ? 'blur(4px)' : 'none',
                transition: 'filter 200ms ease',
              }}
            />
          ) : (
            <Placeholder text="Waiting for first frame…" />
          ))}
        {status === 'streaming' && (
          <div
            data-testid="bl-image-gen-stream-progress"
            style={{
              position: 'absolute',
              left: 0,
              right: 0,
              bottom: 0,
              padding: '6px 8px 8px',
              background:
                'linear-gradient(to top, rgba(0,0,0,0.6), transparent)',
              color: 'white',
              fontSize: 11,
              fontFamily:
                'ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas, monospace',
            }}
          >
            <div
              style={{
                height: 4,
                background: 'rgba(255,255,255,0.18)',
                borderRadius: 999,
                overflow: 'hidden',
              }}
            >
              <div
                style={{
                  height: '100%',
                  width: `${progress * 100}%`,
                  background: 'var(--bl-accent, #6366f1)',
                  transition: 'width 240ms ease',
                }}
              />
            </div>
            <div style={{ marginTop: 4 }}>{snapshot?.label ?? `${Math.round(progress * 100)}%`}</div>
          </div>
        )}
        {status === 'error' && <Placeholder text={errorMessage ?? 'Something went wrong.'} kind="error" />}
      </div>
      {caption && (
        <figcaption
          style={{
            fontSize: 12,
            color: 'var(--bl-text-tertiary, #888)',
            fontFamily: 'ui-sans-serif, system-ui, sans-serif',
          }}
        >
          {caption}
        </figcaption>
      )}
    </figure>
  );
}

function Placeholder({ text, kind }: { text: string; kind?: 'error' }) {
  return (
    <div
      data-testid={kind === 'error' ? 'bl-image-gen-stream-error' : 'bl-image-gen-stream-idle'}
      style={{
        width: '100%',
        height: '100%',
        display: 'grid',
        placeItems: 'center',
        padding: 16,
        textAlign: 'center',
        color:
          kind === 'error'
            ? 'var(--bl-danger, #ef4444)'
            : 'var(--bl-text-tertiary, #888)',
        fontSize: 12,
        fontFamily: 'ui-sans-serif, system-ui, sans-serif',
      }}
    >
      {text}
    </div>
  );
}
