import * as React from 'react';
import {
  Badge as CommonBadge,
  Button as CommonButton,
  Input as CommonInput,
  Select as CommonSelect,
  type BadgeProps as CommonBadgeProps,
  type ButtonProps as CommonButtonProps,
  type InputProps as CommonInputProps,
  type SelectProps as CommonSelectProps,
} from '@bytelyst/ui';
import { cn } from '@/lib/utils';

export {
  Card,
  CardDescription,
  CardHeader,
  CardTitle,
  DataTable,
  DataTableBody,
  DataTableCell,
  DataTableHead,
  DataTableHeader,
  DataTableRow,
  MetricCard,
  PageHeader,
  Panel,
  PanelBody,
  PanelDescription,
  PanelHeader,
  PanelTitle,
  Timeline,
  type TimelineItem,
} from '@bytelyst/ui';

export type ButtonProps = CommonButtonProps;

export const Button = React.forwardRef<HTMLButtonElement, ButtonProps>(
  ({ variant = 'primary', size = 'md', asChild, className, children, ...props }, ref) => {
    if (asChild) {
      const child = React.Children.toArray(children).find(React.isValidElement);
      const classes = cn(
        'inline-flex shrink-0 items-center justify-center whitespace-nowrap rounded-lg font-semibold tracking-normal transition duration-150 focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-[var(--bl-focus-ring)] focus-visible:ring-offset-2 focus-visible:ring-offset-[var(--bl-bg-canvas)] disabled:pointer-events-none disabled:opacity-50',
        variant === 'primary' && 'border border-transparent bg-[var(--bl-accent)] text-[var(--bl-accent-foreground)] shadow-sm shadow-black/10 hover:brightness-105 active:brightness-95',
        variant === 'secondary' && 'border border-[var(--bl-border)] bg-[var(--bl-surface-card)] text-[var(--bl-text-primary)] shadow-sm shadow-black/5 hover:border-[var(--bl-border-strong)] hover:bg-[var(--bl-surface-highlight)]',
        variant === 'ghost' && 'border border-transparent text-[var(--bl-text-secondary)] hover:bg-[var(--bl-surface-muted)] hover:text-[var(--bl-text-primary)]',
        variant === 'destructive' && 'border border-transparent bg-[var(--bl-danger)] text-[var(--bl-danger-foreground)] shadow-sm shadow-black/10 hover:brightness-105 active:brightness-95',
        variant === 'outline' && 'border border-[var(--bl-border)] bg-transparent text-[var(--bl-text-primary)] hover:border-[var(--bl-accent)] hover:bg-[var(--bl-accent-muted)]',
        variant === 'subtle' && 'border border-transparent bg-[var(--bl-surface-muted)] text-[var(--bl-text-primary)] hover:bg-[var(--bl-surface-highlight)]',
        variant === 'link' && 'h-auto rounded-md border border-transparent p-0 text-[var(--bl-accent)] underline-offset-4 hover:underline',
        size === 'sm' && 'h-8 px-3 text-xs gap-1.5',
        size === 'md' && 'h-10 px-4 text-sm gap-2',
        size === 'lg' && 'h-11 px-5 text-sm gap-2.5',
        className,
      );

      if (React.isValidElement<{ className?: string }>(child)) {
        return React.cloneElement(child, {
          className: cn(child.props.className, classes),
        });
      }
    }

    return (
      <CommonButton
        ref={ref}
        variant={variant}
        size={size}
        className={className}
        {...props}
      >
        {children}
      </CommonButton>
    );
  },
);

Button.displayName = 'Button';

export interface BadgeProps extends Omit<CommonBadgeProps, 'variant'> {
  variant?: CommonBadgeProps['variant'] | 'danger';
}

export function Badge({ variant = 'neutral', dot = false, className, children, ...props }: BadgeProps) {
  return (
    <CommonBadge variant={variant === 'danger' ? 'error' : variant} dot={dot} className={className} {...props}>
      {children}
    </CommonBadge>
  );
}

export type InputProps = CommonInputProps;

export const Input = React.forwardRef<HTMLInputElement, InputProps>(
  ({ className, ...props }, ref) => <CommonInput ref={ref} className={className} {...props} />,
);

Input.displayName = 'Input';

export interface SelectProps extends Omit<CommonSelectProps, 'options'> {
  options: CommonSelectProps['options'];
}

export const Select = React.forwardRef<HTMLSelectElement, SelectProps>(
  ({ controlSize = 'md', variant = 'surface', className, ...props }, ref) => (
    <CommonSelect
      ref={ref}
      controlSize={controlSize}
      variant={variant}
      className={cn('min-w-0', className)}
      {...props}
    />
  ),
);

Select.displayName = 'Select';
