import React from "react";
import {
  ActivityIndicator,
  GestureResponderEvent,
  StyleProp,
  StyleSheet,
  Text,
  TouchableOpacity,
  View,
  ViewStyle,
} from "react-native";

type ButtonType = "primary" | "default" | "dashed" | "text" | "link" | "danger";
type ButtonShape = "default" | "circle" | "round";
type ButtonSize = "small" | "middle" | "large";

export interface IconButtonProps {
  type?: ButtonType;
  shape?: ButtonShape;
  size?: ButtonSize;
  icon?: React.ReactNode; // render an icon component, e.g. <AntDesign name="plus" />
  loading?: boolean;
  disabled?: boolean;
  onPress?: (e?: GestureResponderEvent) => void;
  children?: React.ReactNode; // label text
  style?: StyleProp<ViewStyle>;
  block?: boolean; // full width
  activeOpacity?: number;
}

/**
 * IconButton
 * A lightweight Button component inspired by Ant Design Button API, tuned for React Native.
 * Accepts an `icon` prop as a React node for maximum flexibility.
 */
const IconButton: React.FC<IconButtonProps> = ({
  type = "default",
  shape = "default",
  size = "middle",
  icon,
  loading = false,
  disabled = false,
  onPress,
  children,
  style,
  block = false,
  activeOpacity = 0.8,
}) => {
  const sizeMap = {
    small: { height: 32, fontSize: 14, paddingHorizontal: 10 },
    middle: { height: 40, fontSize: 16, paddingHorizontal: 14 },
    large: { height: 48, fontSize: 18, paddingHorizontal: 18 },
  } as const;

  const colors: Record<
    ButtonType,
    { backgroundColor?: string; textColor: string; borderColor?: string }
  > = {
    primary: { backgroundColor: "#4ecdc4", textColor: "#fff" },
    default: {
      backgroundColor: "#f2f2f2",
      textColor: "#111",
      borderColor: "#e6e6e6",
    },
    dashed: {
      backgroundColor: "#fff",
      textColor: "#111",
      borderColor: "#d9d9d9",
    },
    text: { backgroundColor: "transparent", textColor: "#111" },
    link: { backgroundColor: "transparent", textColor: "#4ecdc4" },
    danger: { backgroundColor: "#e74c3c", textColor: "#fff" },
  };

  const sz = sizeMap[size];
  const color = colors[type];

  const isCircle = shape === "circle";
  const isRound = shape === "round";

  const handlePress = (e: GestureResponderEvent) => {
    if (disabled || loading) return;
    onPress?.(e);
  };

  return (
    <TouchableOpacity
      activeOpacity={activeOpacity}
      onPress={handlePress}
      disabled={disabled || loading}
      style={[
        styles.button,
        {
          height: sz.height,
          paddingHorizontal: isCircle ? 0 : sz.paddingHorizontal,
          backgroundColor: color.backgroundColor ?? "transparent",
          borderColor: color.borderColor ?? "transparent",
          borderWidth: type === "dashed" ? 1 : color.borderColor ? 1 : 0,
          width: isCircle ? sz.height : block ? "100%" : undefined,
          borderRadius: isCircle ? sz.height / 2 : isRound ? 999 : 8,
          opacity: disabled ? 0.6 : 1,
        },
        type === "dashed" ? { borderStyle: "dashed" } : null,
        style,
      ]}
    >
      <View style={styles.content}>
        {loading ? (
          <ActivityIndicator
            size={"small"}
            color={color.textColor}
            style={styles.iconContainer}
          />
        ) : icon ? (
          <View style={styles.iconContainer}>{icon}</View>
        ) : null}

        {children ? (
          <Text
            numberOfLines={1}
            style={[
              styles.text,
              {
                color: color.textColor,
                fontSize: sz.fontSize,
                marginLeft: icon || loading ? 6 : 0,
              },
            ]}
          >
            {children}
          </Text>
        ) : null}
      </View>
    </TouchableOpacity>
  );
};

const styles = StyleSheet.create({
  button: {
    flexDirection: "row",
    alignItems: "center",
    justifyContent: "center",
    borderRadius: 8,
    borderColor: "transparent",
  },
  content: {
    flexDirection: "row",
    alignItems: "center",
  },
  iconContainer: {
    alignItems: "center",
    justifyContent: "center",
  },
  text: {
    fontWeight: "600",
  },
});

export default IconButton;
