import React, { ButtonHTMLAttributes, ReactNode } from 'react';
import styled, { css } from 'styled-components';

export interface ButtonProps extends ButtonHTMLAttributes<HTMLButtonElement> {
  variant?: 'primary' | 'secondary' | 'ghost' | 'destructive' | 'outline';
  size?: 'sm' | 'md' | 'lg';
  fullWidth?: boolean;
  loading?: boolean;
  icon?: ReactNode;
  iconPosition?: 'left' | 'right';
}

type StyledButtonTransientProps = {
  $variant: NonNullable<ButtonProps['variant']>;
  $size: NonNullable<ButtonProps['size']>;
  $fullWidth: boolean;
  $loading: boolean;
};

const StyledButton = styled.button<StyledButtonTransientProps>`
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: ${({ theme }) => theme.spacing[2]};
  border: 1px solid transparent;
  border-radius: ${({ theme }) => theme.borderRadius.md};
  font-weight: ${({ theme }) => theme.typography.fontWeight.medium};
  font-family: inherit;
  cursor: pointer;
  transition:
    background-color ${({ theme }) => theme.transitions.fast},
    border-color ${({ theme }) => theme.transitions.fast},
    color ${({ theme }) => theme.transitions.fast},
    box-shadow ${({ theme }) => theme.transitions.fast},
    transform ${({ theme }) => theme.transitions.fast};
  text-decoration: none;
  white-space: nowrap;

  @media (prefers-reduced-motion: reduce) {
    transition:
      background-color ${({ theme }) => theme.transitions.fast},
      border-color ${({ theme }) => theme.transitions.fast},
      color ${({ theme }) => theme.transitions.fast};
  }

  svg {
    width: 1.125em;
    height: 1.125em;
    flex-shrink: 0;
  }

  &:active:not(:disabled) {
    transform: ${({ theme }) => theme.motion.pressScale};
  }

  &:disabled {
    opacity: 0.45;
    cursor: not-allowed;
    transform: none;
    box-shadow: none;
  }

  &:focus-visible {
    outline: 2px solid ${({ theme }) => theme.colors.primary};
    outline-offset: 2px;
  }

  ${({ $size = 'md' }) => {
    switch ($size) {
      case 'sm':
        return css`
          min-height: 30px;
          padding: ${({ theme }) => `${theme.spacing[1]} ${theme.spacing[3]}`};
          font-size: ${({ theme }) => theme.typography.fontSize.sm};
        `;
      case 'lg':
        return css`
          min-height: 40px;
          padding: ${({ theme }) => `${theme.spacing[2]} ${theme.spacing[6]}`};
          font-size: ${({ theme }) => theme.typography.fontSize.base};
        `;
      default:
        return css`
          min-height: 36px;
          padding: ${({ theme }) => `0.5rem ${theme.spacing[5]}`};
          font-size: ${({ theme }) => theme.typography.fontSize.sm};
        `;
    }
  }}

  ${({ $variant = 'primary', theme }) => {
    switch ($variant) {
      case 'primary':
        return css`
          background-color: ${theme.colors.primary};
          color: ${theme.colors.text.inverse};
          box-shadow: ${theme.shadows.xs};
          &:hover:not(:disabled) {
            background-color: ${theme.colors.primaryDark};
            box-shadow: ${theme.shadows.sm};
            transform: ${theme.motion.hoverLift};
          }
        `;
      case 'secondary':
        return css`
          background-color: ${theme.colors.surface};
          color: ${theme.colors.text.primary};
          border-color: ${theme.colors.border};
          box-shadow: ${theme.shadows.xs};
          &:hover:not(:disabled) {
            background-color: ${theme.colors.surfaceMuted};
            border-color: ${theme.colors.borderStrong};
          }
        `;
      case 'outline':
        return css`
          background-color: ${theme.colors.surface};
          color: ${theme.colors.primary};
          border-color: ${theme.colors.border};
          &:hover:not(:disabled) {
            background-color: ${theme.colors.primaryLight};
            border-color: ${theme.colors.primary};
          }
        `;
      case 'ghost':
        return css`
          background-color: transparent;
          color: ${theme.colors.text.secondary};
          &:hover:not(:disabled) {
            background-color: ${theme.colors.surfaceMuted};
            color: ${theme.colors.text.primary};
          }
        `;
      case 'destructive':
        return css`
          background-color: ${theme.colors.errorLight};
          color: ${theme.colors.errorDark};
          border-color: ${theme.colors.status.error.border};
          box-shadow: none;
          &:hover:not(:disabled) {
            background-color: ${theme.colors.error};
            color: ${theme.colors.text.inverse};
            border-color: ${theme.colors.error};
            transform: ${theme.motion.hoverLift};
          }
        `;
    }
  }}

  ${({ $fullWidth }) =>
    $fullWidth &&
    css`
      width: 100%;
    `}

  ${({ $loading }) =>
    $loading &&
    css`
      position: relative;
      color: transparent;
      pointer-events: none;

      &::after {
        content: '';
        position: absolute;
        width: 16px;
        height: 16px;
        top: 50%;
        left: 50%;
        margin-left: -8px;
        margin-top: -8px;
        border: 2px solid currentColor;
        border-radius: 50%;
        border-right-color: transparent;
        animation: rotate 0.6s linear infinite;
      }

      @keyframes rotate {
        to {
          transform: rotate(360deg);
        }
      }
    `}
`;

export const Button: React.FC<ButtonProps> = ({
  children,
  variant = 'primary',
  size = 'md',
  fullWidth = false,
  icon,
  iconPosition = 'left',
  loading = false,
  type = 'button',
  disabled,
  ...props
}) => {
  return (
    <StyledButton
      $variant={variant}
      $size={size}
      $fullWidth={fullWidth}
      $loading={loading}
      {...props}
      type={type}
      disabled={disabled || loading}
    >
      {icon && iconPosition === 'left' && !loading && icon}
      {children}
      {icon && iconPosition === 'right' && !loading && icon}
    </StyledButton>
  );
};
