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

export type RefusalReason =
  | 'safety'
  | 'policy'
  | 'capability'
  | 'authorization'
  | 'rate-limit'
  | 'unknown';

export interface RefusalAction {
  label: string;
  onClick: () => void;
  /** Render this action as the primary CTA. Default: false. */
  primary?: boolean;
}

export interface RefusalCardProps {
  /**
   * Why the model declined. Drives the icon + the friendly heading
   * shown above the explanation.
   */
  reason: RefusalReason;
  /** Plain-language explanation. Keep it short, kind, specific. */
  explanation: string;
  /** Optional title override; defaults to a reason-specific heading. */
  title?: string;
  /** Up to 3 actions the user can take next. */
  actions?: RefusalAction[];
  /** Optional appendix slot — links to policy doc, support, etc. */
  footer?: ReactNode;
  className?: string;
  style?: CSSProperties;
}

const HEADINGS: Record<RefusalReason, { title: string; icon: string }> = {
  safety: { title: "I can't help with that", icon: '🛡️' },
  policy: { title: 'Outside policy', icon: '📕' },
  capability: { title: "I'm not sure I can help here", icon: '🤔' },
  authorization: { title: 'Permission required', icon: '🔒' },
  'rate-limit': { title: 'Easy there — slow down', icon: '⏳' },
  unknown: { title: 'Declined', icon: '⚪' },
};

/**
 * `<RefusalCard>` — honest, kind, structured "no" from the model.
 *
 * Trust surface (Wave 13.C.3). The pattern every product reinvents
 * poorly: when the LLM declines, we shouldn't dump the raw refusal
 * string into the chat. Instead we render a small card with:
 *   - a reason-typed heading + glyph
 *   - one paragraph of plain-language explanation
 *   - up to three actionable next steps
 *
 * Calm, not alarming. Token-tinted with the warning palette but never
 * red — refusals are not errors.
 */
export function RefusalCard({
  reason,
  explanation,
  title,
  actions,
  footer,
  className,
  style,
}: RefusalCardProps) {
  const heading = HEADINGS[reason] ?? HEADINGS.unknown;
  const acts = (actions ?? []).slice(0, 3);

  return (
    <section
      role="note"
      aria-label={`${heading.title}: ${explanation}`}
      data-testid="bl-refusal-card"
      data-reason={reason}
      className={className}
      style={{
        display: 'flex',
        flexDirection: 'column',
        gap: 12,
        maxWidth: 480,
        padding: 16,
        borderRadius: 14,
        backgroundColor:
          'color-mix(in srgb, var(--bl-warning, #f59e0b) 8%, var(--bl-surface-card, #fff))',
        border: '1px solid color-mix(in srgb, var(--bl-warning, #f59e0b) 35%, transparent)',
        color: 'var(--bl-text-primary, #111)',
        ...style,
      }}
    >
      <header style={{ display: 'flex', alignItems: 'center', gap: 10 }}>
        <span
          aria-hidden="true"
          style={{
            fontSize: 18,
            lineHeight: 1,
            display: 'inline-grid',
            placeItems: 'center',
            width: 32,
            height: 32,
            borderRadius: 10,
            backgroundColor:
              'color-mix(in srgb, var(--bl-warning, #f59e0b) 18%, transparent)',
          }}
        >
          {heading.icon}
        </span>
        <h4
          style={{
            margin: 0,
            fontSize: 14,
            fontWeight: 600,
            color: 'var(--bl-warning-strong, var(--bl-warning, #b45309))',
          }}
        >
          {title ?? heading.title}
        </h4>
      </header>
      <p
        style={{
          margin: 0,
          fontSize: 14,
          lineHeight: 1.55,
          color: 'var(--bl-text-secondary, #444)',
        }}
      >
        {explanation}
      </p>
      {acts.length > 0 && (
        <div
          role="group"
          aria-label="Available actions"
          style={{ display: 'flex', flexWrap: 'wrap', gap: 8 }}
        >
          {acts.map((a, i) => (
            <button
              key={`${a.label}-${i}`}
              type="button"
              onClick={a.onClick}
              data-testid={`bl-refusal-card-action-${i}`}
              style={{
                padding: '6px 12px',
                borderRadius: 999,
                fontSize: 13,
                fontWeight: 500,
                cursor: 'pointer',
                border: a.primary
                  ? '1px solid transparent'
                  : '1px solid var(--bl-border, rgba(0,0,0,0.14))',
                backgroundColor: a.primary
                  ? 'var(--bl-accent, #6366f1)'
                  : 'transparent',
                color: a.primary
                  ? 'var(--bl-on-accent, #fff)'
                  : 'var(--bl-text-primary, #111)',
              }}
            >
              {a.label}
            </button>
          ))}
        </div>
      )}
      {footer && (
        <footer
          style={{
            marginTop: 4,
            paddingTop: 10,
            borderTop: '1px dashed color-mix(in srgb, var(--bl-warning, #f59e0b) 25%, transparent)',
            fontSize: 12,
            color: 'var(--bl-text-tertiary, #666)',
          }}
        >
          {footer}
        </footer>
      )}
    </section>
  );
}
