/**
 * Componentes atômicos — Receptor de className sempre no topo,
 * spread de props SEMPRE por último.
 */

import { cn } from '../utils';

// =========================================================
// 🅱 Button
// =========================================================
type ButtonVariant = 'primary' | 'secondary' | 'ghost' | 'danger' | 'success';
type ButtonSize    = 'sm' | 'md' | 'lg';

interface ButtonProps extends React.ButtonHTMLAttributes<HTMLButtonElement> {
  variant?: ButtonVariant;
  size?:    ButtonSize;
  loading?: boolean;
  leftIcon?:  React.ReactNode;
  rightIcon?: React.ReactNode;
}

const variantStyles: Record<ButtonVariant, string> = {
  primary:   'bg-indigo-600 text-white hover:bg-indigo-700 active:bg-indigo-800 disabled:bg-indigo-300',
  secondary: 'border border-gray-300 text-gray-700 bg-white hover:bg-gray-50 active:bg-gray-100',
  ghost:     'text-gray-600 hover:bg-gray-100 active:bg-gray-200',
  danger:    'bg-red-600 text-white hover:bg-red-700 active:bg-red-800',
  success:   'bg-emerald-600 text-white hover:bg-emerald-700 active:bg-emerald-800',
};

const sizeStyles: Record<ButtonSize, string> = {
  sm: 'px-2.5 py-1 text-xs rounded',
  md: 'px-4 py-2 text-sm rounded-md',
  lg: 'px-6 py-3 text-base rounded-lg',
};

export function Button({
  className, variant = 'primary', size = 'md',
  loading, leftIcon, rightIcon,
  children, disabled, ...rest
}: ButtonProps) {
  return (
    <button
      className={cn(
        'inline-flex items-center justify-center gap-2 font-medium transition-colors',
        'focus:outline-none focus:ring-2 focus:ring-indigo-500 focus:ring-offset-2',
        'disabled:cursor-not-allowed disabled:opacity-50',
        variantStyles[variant], sizeStyles[size], className
      )}
      disabled={disabled || loading}
      {...rest}
    >
      {loading ? <Spinner size={16} /> : (leftIcon ?? null)}
      {children}
      {!loading && rightIcon}
    </button>
  );
}

// =========================================================
// 🅸 Input
// =========================================================
interface InputProps extends React.InputHTMLAttributes<HTMLInputElement> {
  label?:    string;
  error?:    string;
  hint?:     string;
}

export function Input({ className, label, error, hint, id, ...rest }: InputProps) {
  const inputId = id ?? label?.toLowerCase().replace(/\s+/g, '-');
  return (
    <div className="flex flex-col gap-1">
      {label && <label htmlFor={inputId} className="text-sm font-medium text-gray-700">{label}</label>}
      <input
        id={inputId}
        className={cn(
          'w-full rounded-md border border-gray-300 px-3 py-2 text-sm',
          'placeholder:text-gray-400',
          'focus:outline-none focus:ring-2 focus:ring-indigo-500 focus:border-indigo-500',
          'disabled:bg-gray-100 disabled:cursor-not-allowed',
          error && 'border-red-500 focus:ring-red-500 focus:border-red-500',
          className
        )}
        {...rest}
      />
      {error  && <span className="text-xs text-red-500">{error}</span>}
      {hint   && !error && <span className="text-xs text-gray-400">{hint}</span>}
    </div>
  );
}

// =========================================================
// 🔔 Toast / Alert
// =========================================================
type AlertVariant = 'info' | 'success' | 'warning' | 'error';

interface AlertProps {
  variant?:  AlertVariant;
  title?:    string;
  children:  React.ReactNode;
  onClose?:  () => void;
}

const alertStyles: Record<AlertVariant, { container: string; icon: string }> = {
  info:    { container: 'bg-blue-50 border-blue-200 text-blue-800',         icon: 'ℹ️' },
  success: { container: 'bg-emerald-50 border-emerald-200 text-emerald-800', icon: '✅' },
  warning: { container: 'bg-amber-50 border-amber-200 text-amber-800',       icon: '⚠️' },
  error:   { container: 'bg-red-50 border-red-200 text-red-800',             icon: '❌' },
};

export function Alert({ variant = 'info', title, children, onClose }: AlertProps) {
  const s = alertStyles[variant];
  return (
    <div className={cn('flex items-start gap-2 rounded-lg border px-4 py-3', s.container)}>
      <span className="text-base leading-none">{s.icon}</span>
      <div className="flex-1">
        {title && <p className="font-semibold text-sm">{title}</p>}
        <p className="text-sm">{children}</p>
      </div>
      {onClose && <button onClick={onClose} className="ml-auto text-lg leading-none opacity-50 hover:opacity-100">×</button>}
    </div>
  );
}

// =========================================================
// 🃏 Card
// =========================================================
interface CardProps extends React.HTMLAttributes<HTMLDivElement> { children: React.ReactNode; }
export const Card: React.FC<CardProps> = ({ className, children, ...rest }) => (
  <div className={cn('rounded-xl border border-gray-200 bg-white shadow-sm', className)} {...rest}>{children}</div>
);
export const CardHeader: React.FC<CardProps> = ({ className, children, ...rest }) => (
  <div className={cn('px-5 py-4 border-b border-gray-100', className)} {...rest}>{children}</div>
);
export const CardTitle: React.FC<{ children: React.ReactNode }> = ({ children }) => (
  <h3 className="font-semibold text-gray-900 text-base">{children}</h3>
);
export const CardBody: React.FC<CardProps> = ({ className, children, ...rest }) => (
  <div className={cn('px-5 py-4', className)} {...rest}>{children}</div>
);

// ── Spinner (reutilizável) ─────────────────────────────────
export function Spinner({ size = 16, className = '' }: { size?: number; className?: string }) {
  return (
    <svg className={cn('animate-spin', className)} width={size} height={size} viewBox="0 0 24 24" fill="none">
      <circle className="opacity-25" cx="12" cy="12" r="10" stroke="currentColor" strokeWidth="4" />
      <path className="opacity-75" fill="currentColor" d="M4 12a8 8 0 018-8V0C5.373 0 0 5.373 0 12h4z" />
    </svg>
  );
}

// ── Cn helper re-export ────────────────────────────────────
export { cn } from '../utils';
