import React, { useRef } from 'react';
import {
  Animated,
  TouchableWithoutFeedback,
  Text,
  StyleSheet,
  ActivityIndicator,
  ViewStyle,
  TextStyle,
  View,
} from 'react-native';
import { COLORS, RADIUS, SPACING, FONT_SIZE, FONT, SHADOWS } from '../../theme';
import { useTheme } from '../../theme';

type Variant = 'primary' | 'secondary' | 'outline' | 'ghost' | 'danger';
type Size = 'sm' | 'md' | 'lg';

interface ButtonProps {
  title: string;
  onPress: () => void;
  variant?: Variant;
  size?: Size;
  loading?: boolean;
  disabled?: boolean;
  style?: ViewStyle;
  textStyle?: TextStyle;
  fullWidth?: boolean;
}

export function Button({
  title,
  onPress,
  variant = 'primary',
  size = 'md',
  loading = false,
  disabled = false,
  style,
  textStyle,
  fullWidth = false,
}: ButtonProps) {
  const { theme, isDark } = useTheme();
  const scale = useRef(new Animated.Value(1)).current;

  const onPressIn = () =>
    Animated.spring(scale, { toValue: 0.96, useNativeDriver: true, speed: 50, bounciness: 0 }).start();

  const onPressOut = () =>
    Animated.spring(scale, { toValue: 1, useNativeDriver: true, speed: 30, bounciness: 4 }).start();

  const containerBg = getContainerBg(variant, theme, isDark);
  const labelColor = getLabelColor(variant);
  const shadow = variant === 'primary' ? SHADOWS.primary : variant === 'danger' ? SHADOWS.sm : {};

  return (
    <TouchableWithoutFeedback
      onPress={onPress}
      onPressIn={onPressIn}
      onPressOut={onPressOut}
      disabled={disabled || loading}>
      <Animated.View
        style={[
          styles.base,
          styles[`size_${size}`],
          containerBg,
          shadow,
          fullWidth && styles.fullWidth,
          (disabled || loading) && styles.disabled,
          { transform: [{ scale }] },
          style,
        ]}>
        {loading ? (
          <ActivityIndicator
            size="small"
            color={variant === 'primary' || variant === 'danger' ? COLORS.white : COLORS.primary}
          />
        ) : (
          <Text style={[styles.label, styles[`label_${size}`], { color: labelColor }, textStyle]}>
            {title}
          </Text>
        )}
      </Animated.View>
    </TouchableWithoutFeedback>
  );
}

function getContainerBg(variant: Variant, theme: any, isDark: boolean): ViewStyle {
  switch (variant) {
    case 'primary':
      return { backgroundColor: COLORS.primary };
    case 'secondary':
      return { backgroundColor: isDark ? theme.surfaceHover : theme.bgSecondary };
    case 'outline':
      return { backgroundColor: 'transparent', borderWidth: 1.5, borderColor: COLORS.primary };
    case 'ghost':
      return { backgroundColor: 'transparent' };
    case 'danger':
      return { backgroundColor: COLORS.error };
  }
}

function getLabelColor(variant: Variant): string {
  switch (variant) {
    case 'primary':
    case 'danger':
      return COLORS.white;
    case 'secondary':
      return COLORS.primary;
    case 'outline':
    case 'ghost':
      return COLORS.primary;
  }
}

const styles = StyleSheet.create({
  base: {
    borderRadius: RADIUS.md,
    alignItems: 'center',
    justifyContent: 'center',
    flexDirection: 'row',
  },
  fullWidth: { width: '100%' },
  disabled: { opacity: 0.55 },

  size_sm: { paddingVertical: SPACING.xs + 2, paddingHorizontal: SPACING.md, borderRadius: RADIUS.sm },
  size_md: { paddingVertical: SPACING.md - 1, paddingHorizontal: SPACING.xl, borderRadius: RADIUS.md },
  size_lg: { paddingVertical: SPACING.md + 1, paddingHorizontal: SPACING.xxl, borderRadius: RADIUS.lg, minHeight: 52 },

  label: { fontWeight: FONT.semibold as any, letterSpacing: 0.1 },
  label_sm: { fontSize: FONT_SIZE.sm },
  label_md: { fontSize: FONT_SIZE.md },
  label_lg: { fontSize: FONT_SIZE.md },
});
