'use client';

import type { ReactElement } from 'react';
import { formatAge, type FreshnessLabel } from '@/lib/freshness/model';

/**
 * Rendering rules for non-current freshness states (RI-5-001).
 *
 * - `unavailable` renders an explicit failure panel — never an empty
 *   healthy collection.
 * - `stale` may render last-known data, but only under a visible label
 *   carrying source identity, snapshot version, and age.
 * - `partial` renders the verified parts plus an explicit list of what is
 *   missing.
 */

interface RetryableNoticeProps {
  readonly onRetry?: () => void;
  readonly retryLabel?: string;
}

function RetryButton({ onRetry, retryLabel }: RetryableNoticeProps): ReactElement | null {
  if (!onRetry) return null;
  return (
    <button
      type="button"
      onClick={onRetry}
      className="mt-2 rounded-lg border border-surface-border px-3 py-1.5 text-xs transition-colors hover:border-gray-500"
    >
      {retryLabel ?? 'Retry'}
    </button>
  );
}

export interface UnavailableDataNoticeProps extends RetryableNoticeProps {
  /** What is unavailable, e.g. "Tasks". */
  readonly title: string;
  /** Optional underlying failure detail (network message, invalidation reason). */
  readonly detail?: string | null;
}

/** Explicit `unavailable` state. Never renders as an empty healthy collection. */
export function UnavailableDataNotice({
  title,
  detail,
  onRetry,
  retryLabel,
}: UnavailableDataNoticeProps): ReactElement {
  return (
    <div role="alert" className="rounded-lg border border-error/40 px-4 py-3 text-sm">
      <p className="font-medium text-text-primary">{title} are unavailable</p>
      <p className="mt-1 text-text-muted">
        This is not an empty result — the data could not be verified from the gateway.
        {detail ? ` ${detail}` : ''}
      </p>
      <RetryButton onRetry={onRetry} retryLabel={retryLabel} />
    </div>
  );
}

export interface StaleDataNoticeProps extends RetryableNoticeProps {
  /** Provenance of the last-known snapshot being displayed. */
  readonly label: FreshnessLabel;
}

/**
 * Situational-awareness banner for `stale` data: last-known data may render,
 * but visibly labeled with source identity, snapshot version, and age.
 */
export function StaleDataNotice({
  label,
  onRetry,
  retryLabel,
}: StaleDataNoticeProps): ReactElement {
  return (
    <div role="status" className="rounded-lg border border-warning/40 px-4 py-3 text-sm">
      <p className="font-medium text-warning">Showing last-known data — it may be out of date</p>
      <p className="mt-1 text-xs text-text-muted">
        Source {label.source} · snapshot v{label.version} · fetched{' '}
        {formatAge(label.fetchedAt, Date.now())}. Verdicts derived from this data are unknown and
        changes are disabled until it is revalidated.
      </p>
      <RetryButton onRetry={onRetry} retryLabel={retryLabel ?? 'Revalidate'} />
    </div>
  );
}

export interface PartialDataNoticeProps extends RetryableNoticeProps {
  /** Display names of the sections whose collections are unavailable. */
  readonly missing: readonly string[];
}

/** `partial` surface banner: verified parts render, missing parts are explicit. */
export function PartialDataNotice({
  missing,
  onRetry,
  retryLabel,
}: PartialDataNoticeProps): ReactElement {
  return (
    <div role="status" className="rounded-lg border border-warning/40 px-4 py-3 text-sm">
      <p className="font-medium text-warning">Some data could not be loaded</p>
      <p className="mt-1 text-xs text-text-muted">
        {missing.join(', ')} {missing.length === 1 ? 'is' : 'are'} unavailable — sections below show
        an explicit unavailable state instead of an empty list. Derived verdicts remain unknown
        until every collection is revalidated.
      </p>
      <RetryButton onRetry={onRetry} retryLabel={retryLabel ?? 'Revalidate'} />
    </div>
  );
}
