import { AntDesign } from "@expo/vector-icons";
import React, { useEffect, useState } from "react";
import {
  ActivityIndicator,
  ScrollView,
  StyleProp,
  StyleSheet,
  Text,
  TextInput,
  TouchableOpacity,
  View,
  ViewStyle,
} from "react-native";

export interface SelectOption {
  label: string;
  value: string | number;
  disabled?: boolean;
}

export interface SelectProps {
  value?: string | number;
  defaultValue?: string | number;
  options: SelectOption[];
  onChange?: (value: string | number | undefined) => void;
  placeholder?: string;
  disabled?: boolean;
  loading?: boolean;
  allowClear?: boolean;
  showSearch?: boolean;
  mode?: "single" | "multiple"; // multiple not implemented yet
  style?: StyleProp<ViewStyle>;
  size?: "small" | "middle" | "large";
  listStyle?: StyleProp<ViewStyle>;
}

/**
 * Select
 * A Select component inspired by Ant Design, adapted for React Native.
 * Supports single selection, search, clear, loading, disabled states.
 */
const Select: React.FC<SelectProps> = ({
  value,
  defaultValue,
  options,
  onChange,
  placeholder = "Select an option",
  disabled = false,
  loading = false,
  allowClear = false,
  showSearch = false,
  mode = "single",
  style,
  listStyle,
  size = "middle",
}) => {
  const [selectedValue, setSelectedValue] = useState<
    string | number | undefined
  >(value ?? defaultValue);
  const [isOpen, setIsOpen] = useState(false);
  const [searchText, setSearchText] = useState("");
  const [containerHeight, setContainerHeight] = useState(0);

  useEffect(() => {
    setSelectedValue(value);
  }, [value]);

  const filteredOptions = showSearch
    ? options.filter((opt) =>
        opt.label.toLowerCase().includes(searchText.toLowerCase())
      )
    : options;

  const selectedOption = options.find((opt) => opt.value === selectedValue);

  const handleSelect = (val: string | number) => {
    setSelectedValue(val);
    onChange?.(val);
    setIsOpen(false);
    setSearchText("");
  };

  const handleClear = () => {
    setSelectedValue(undefined);
    onChange?.(undefined);
  };

  const sizeMap = {
    small: { height: 32, fontSize: 14, paddingHorizontal: 10 },
    middle: { height: 40, fontSize: 16, paddingHorizontal: 14 },
    large: { height: 48, fontSize: 18, paddingHorizontal: 18 },
  };

  const sz = sizeMap[size];

  return (
    <View style={styles.wrapper}>
      <TouchableOpacity
        style={[
          styles.container,
          {
            height: sz.height,
            paddingHorizontal: sz.paddingHorizontal,
            opacity: disabled ? 0.6 : 1,
          },
          style,
        ]}
        onPress={() => !disabled && !loading && setIsOpen(!isOpen)}
        disabled={disabled || loading}
        activeOpacity={0.8}
        onLayout={(e) => setContainerHeight(e.nativeEvent.layout.height)}
      >
        <View style={styles.content}>
          {loading ? (
            <ActivityIndicator size="small" color="#4ecdc4" />
          ) : (
            <Text
              style={[
                styles.text,
                {
                  fontSize: sz.fontSize,
                  color: selectedValue ? "#111" : "#999",
                },
              ]}
              numberOfLines={1}
            >
              {selectedOption?.label || placeholder}
            </Text>
          )}
        </View>
        <View style={styles.suffix}>
          {allowClear && selectedValue && !loading ? (
            <TouchableOpacity onPress={handleClear} style={styles.icon}>
              <AntDesign name="close" size={16} color="#999" />
            </TouchableOpacity>
          ) : null}
          <AntDesign
            name={isOpen ? "up" : "down"}
            size={14}
            color="#999"
            style={styles.arrow}
          />
        </View>
      </TouchableOpacity>

      {isOpen && (
        <View style={[styles.dropdown, { top: containerHeight }]}>
          {showSearch && (
            <TextInput
              style={styles.searchInput}
              placeholder="Search..."
              value={searchText}
              onChangeText={setSearchText}
              autoFocus
            />
          )}
          <ScrollView style={[styles.list, listStyle]}>
            {filteredOptions.map((item) => (
              <TouchableOpacity
                key={item.value}
                style={[
                  styles.option,
                  item.disabled && styles.optionDisabled,
                  selectedValue === item.value && styles.optionSelected,
                ]}
                onPress={() => !item.disabled && handleSelect(item.value)}
                disabled={item.disabled}
              >
                <Text
                  style={[
                    styles.optionText,
                    item.disabled && styles.optionTextDisabled,
                    selectedValue === item.value && styles.optionTextSelected,
                  ]}
                >
                  {item.label}
                </Text>
                {selectedValue === item.value && (
                  <AntDesign name="check" size={16} color="#4ecdc4" />
                )}
              </TouchableOpacity>
            ))}
          </ScrollView>
        </View>
      )}
    </View>
  );
};

const styles = StyleSheet.create({
  wrapper: {
    position: "relative",
  },
  container: {
    borderWidth: 1,
    borderColor: "#e6e6e6",
    borderRadius: 8,
    backgroundColor: "#fff",
    flexDirection: "row",
    alignItems: "center",
    justifyContent: "space-between",
  },
  content: {
    flex: 1,
  },
  text: {
    color: "#111",
  },
  suffix: {
    flexDirection: "row",
    alignItems: "center",
  },
  icon: {
    marginRight: 8,
  },
  arrow: {
    marginLeft: 4,
  },
  dropdown: {
    position: "absolute",
    left: 0,
    right: 0,
    backgroundColor: "#fff",
    borderWidth: 1,
    borderColor: "#e6e6e6",
    borderTopWidth: 0,
    borderRadius: 10,
    borderBottomLeftRadius: 8,
    borderBottomRightRadius: 8,
    shadowColor: "#000",
    shadowOpacity: 0.1,
    shadowRadius: 4,
    shadowOffset: { width: 0, height: 2 },
    elevation: 5,
    zIndex: 1000,
  },
  searchInput: {
    borderWidth: 1,
    borderColor: "#e6e6e6",
    borderRadius: 4,
    padding: 8,
    margin: 8,
  },
  list: {
    maxHeight: 200,
  },
  option: {
    padding: 12,
    borderBottomWidth: 1,
    borderBottomColor: "#f0f0f0",
    flexDirection: "row",
    justifyContent: "space-between",
    alignItems: "center",
  },
  optionDisabled: {
    opacity: 0.5,
  },
  optionSelected: {
    backgroundColor: "#f6ffed",
  },
  optionText: {
    fontSize: 16,
    color: "#111",
  },
  optionTextDisabled: {
    color: "#999",
  },
  optionTextSelected: {
    color: "#4ecdc4",
    fontWeight: "600",
  },
});

export default Select;
