import type { CSSProperties } from 'react';

export type ConfidenceLevel = 'high' | 'medium' | 'low' | 'unknown';

export interface ConfidenceTagProps {
  /**
   * Either a `[0..1]` score (we bucket it) or one of the four explicit
   * levels. Out-of-range numbers fall back to 'unknown'.
   */
  value: number | ConfidenceLevel;
  /** Optional short label override (default: 'High' / 'Medium' / …). */
  label?: string;
  /** Show the underlying numeric score next to the label. */
  showScore?: boolean;
  /** Custom thresholds for bucketing (default 0.8 / 0.5). */
  thresholds?: { high?: number; medium?: number };
  className?: string;
  style?: CSSProperties;
}

const LEVEL_TINTS: Record<
  ConfidenceLevel,
  { bg: string; fg: string; ring: string; dot: string; label: string }
> = {
  high: {
    bg: 'color-mix(in srgb, var(--bl-success, #10b981) 14%, transparent)',
    fg: 'var(--bl-success, #047857)',
    ring: 'color-mix(in srgb, var(--bl-success, #10b981) 35%, transparent)',
    dot: 'var(--bl-success, #10b981)',
    label: 'High',
  },
  medium: {
    bg: 'color-mix(in srgb, var(--bl-warning, #f59e0b) 14%, transparent)',
    fg: 'var(--bl-warning, #b45309)',
    ring: 'color-mix(in srgb, var(--bl-warning, #f59e0b) 35%, transparent)',
    dot: 'var(--bl-warning, #f59e0b)',
    label: 'Medium',
  },
  low: {
    bg: 'color-mix(in srgb, var(--bl-danger, #ef4444) 14%, transparent)',
    fg: 'var(--bl-danger, #b91c1c)',
    ring: 'color-mix(in srgb, var(--bl-danger, #ef4444) 35%, transparent)',
    dot: 'var(--bl-danger, #ef4444)',
    label: 'Low',
  },
  unknown: {
    bg: 'var(--bl-surface-muted, rgba(0,0,0,0.05))',
    fg: 'var(--bl-text-secondary, #555)',
    ring: 'var(--bl-border, rgba(0,0,0,0.12))',
    dot: 'var(--bl-text-tertiary, #999)',
    label: '—',
  },
};

function bucket(value: number, t: { high: number; medium: number }): ConfidenceLevel {
  if (!Number.isFinite(value) || value < 0 || value > 1) return 'unknown';
  if (value >= t.high) return 'high';
  if (value >= t.medium) return 'medium';
  return 'low';
}

/**
 * `<ConfidenceTag>` — show the model's confidence as a coloured chip.
 *
 * Trust surface (Wave 13.C.2). Users should be able to tell at-a-glance
 * how much to trust an AI suggestion. Accepts either an explicit level
 * (`'high'`/`'medium'`/`'low'`/`'unknown'`) or a `[0..1]` numeric score
 * that is bucketed against configurable thresholds.
 *
 * Pairs naturally with `<CitationChip>` (citations + confidence form
 * the two halves of "show your work").
 */
export function ConfidenceTag({
  value,
  label,
  showScore = false,
  thresholds,
  className,
  style,
}: ConfidenceTagProps) {
  const t = { high: thresholds?.high ?? 0.8, medium: thresholds?.medium ?? 0.5 };
  const level: ConfidenceLevel =
    typeof value === 'string' ? value : bucket(value, t);
  const tint = LEVEL_TINTS[level];
  const displayLabel = label ?? tint.label;
  const score = typeof value === 'number' && Number.isFinite(value) ? value : null;

  return (
    <span
      role="status"
      data-testid="bl-confidence-tag"
      data-level={level}
      aria-label={`Confidence: ${displayLabel}${
        score !== null ? ` (${(score * 100).toFixed(0)} percent)` : ''
      }`}
      className={className}
      style={{
        display: 'inline-flex',
        alignItems: 'center',
        gap: 6,
        padding: '2px 8px',
        borderRadius: 999,
        backgroundColor: tint.bg,
        border: `1px solid ${tint.ring}`,
        color: tint.fg,
        fontSize: 11,
        fontWeight: 600,
        letterSpacing: 0.2,
        textTransform: 'uppercase',
        ...style,
      }}
    >
      <span
        aria-hidden="true"
        style={{
          display: 'inline-block',
          width: 6,
          height: 6,
          borderRadius: 999,
          backgroundColor: tint.dot,
        }}
      />
      {displayLabel}
      {showScore && score !== null && (
        <span style={{ opacity: 0.75, fontWeight: 400, fontVariantNumeric: 'tabular-nums' }}>
          {(score * 100).toFixed(0)}%
        </span>
      )}
    </span>
  );
}
