import { useState, type CSSProperties, type ReactNode } from 'react';
import { Check, CircleX, Info, TriangleAlert, X } from 'lucide-react';

function classNames(...values: Array<string | false | null | undefined>): string {
  return values.filter(Boolean).join(' ');
}

export interface SpinnerProps {
  size?: number;
  tone?: 'accent' | 'muted' | 'ok';
  stroke?: number;
  style?: CSSProperties;
}

export function Spinner({ size = 18, tone = 'accent', stroke = 2.4, style }: SpinnerProps) {
  return (
    <span
      className={classNames(
        'ctv-spinner',
        tone === 'muted' && 'ctv-spinner-muted',
        tone === 'ok' && 'ctv-spinner-ok'
      )}
      style={style}
    >
      <svg width={size} height={size} viewBox="0 0 24 24" fill="none" aria-hidden="true">
        <circle cx="12" cy="12" r="9" stroke="currentColor" strokeOpacity="0.2" strokeWidth={stroke} />
        <path d="M21 12a9 9 0 0 0-9-9" stroke="currentColor" strokeWidth={stroke} strokeLinecap="round" />
      </svg>
    </span>
  );
}

export interface ToastProps {
  tone?: 'info' | 'ok' | 'warn' | 'error';
  title?: ReactNode;
  message?: ReactNode;
  onClose?: () => void;
  style?: CSSProperties;
}

const toastStyle: Record<NonNullable<ToastProps['tone']>, { color: string; bg: string }> = {
  info: { color: 'var(--action-primary)', bg: 'var(--ctv-accent-soft)' },
  ok: { color: 'var(--status-ok)', bg: 'var(--ctv-ok-soft)' },
  warn: { color: 'var(--status-warn)', bg: 'var(--ctv-warn-soft)' },
  error: { color: 'var(--status-error)', bg: 'var(--ctv-error-soft)' }
};

export function Toast({ tone = 'info', title, message, onClose, style }: ToastProps) {
  const toneStyle = toastStyle[tone];
  const Icon = {
    error: CircleX,
    info: Info,
    ok: Check,
    warn: TriangleAlert
  }[tone];

  return (
    <div
      className="ctv-toast"
      role="status"
      style={
        {
          '--ctv-toast-color': toneStyle.color,
          '--ctv-toast-bg': toneStyle.bg,
          ...style
        } as CSSProperties
      }
    >
      <span className="ctv-toast-icon">
        <Icon aria-hidden="true" size={14} />
      </span>
      <div className="ctv-toast-body">
        {title && <div className="ctv-toast-title">{title}</div>}
        {message && <div className="ctv-toast-message">{message}</div>}
      </div>
      {onClose && (
        <button type="button" className="ctv-toast-close" aria-label="Dismiss" onClick={onClose}>
          <X aria-hidden="true" size={14} />
        </button>
      )}
    </div>
  );
}

export interface TooltipProps {
  label: ReactNode;
  placement?: 'top' | 'bottom' | 'left' | 'right';
  children: ReactNode;
  style?: CSSProperties;
}

export function Tooltip({ label, placement = 'top', children, style }: TooltipProps) {
  const [visible, setVisible] = useState(false);

  return (
    <span
      className="ctv-tooltip-wrap"
      style={style}
      onMouseEnter={() => setVisible(true)}
      onMouseLeave={() => setVisible(false)}
      onFocus={() => setVisible(true)}
      onBlur={() => setVisible(false)}
    >
      {children}
      {visible && label && (
        <span role="tooltip" className={classNames('ctv-tooltip', `ctv-tooltip-${placement}`)}>
          {label}
        </span>
      )}
    </span>
  );
}
