import { useThemeContext } from "@/hooks/use-theme-context";
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 | (string | number)[];
  defaultValue?: string | number | (string | number)[];
  options: SelectOption[];
  onChange?: (value: string | number | (string | number)[] | undefined) => void;
  placeholder?: string;
  disabled?: boolean;
  loading?: boolean;
  allowClear?: boolean;
  showSearch?: boolean;
  mode?: "single" | "multiple";
  style?: StyleProp<ViewStyle>;
  size?: "small" | "middle" | "large";
  listStyle?: StyleProp<ViewStyle>;
}

/**
 * Select
 * A Select component inspired by Ant Design, adapted for React Native.
 * Supports single and multiple 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 initialValue = value ?? defaultValue;
  const [selectedValues, setSelectedValues] = useState<(string | number)[]>(
    Array.isArray(initialValue)
      ? initialValue
      : initialValue
      ? [initialValue]
      : []
  );
  const [isOpen, setIsOpen] = useState(false);
  const [searchText, setSearchText] = useState("");
  const [containerHeight, setContainerHeight] = useState(0);
  const [textHeight, setTextHeight] = useState(0);

  useEffect(() => {
    const newVal = value ?? defaultValue;
    setSelectedValues(Array.isArray(newVal) ? newVal : newVal ? [newVal] : []);
  }, [value, defaultValue]);

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

  const handleSelect = (val: string | number) => {
    let newSelected: (string | number)[];
    if (mode === "single") {
      newSelected = [val];
    } else {
      newSelected = selectedValues.includes(val)
        ? selectedValues.filter((v) => v !== val)
        : [...selectedValues, val];
    }
    setSelectedValues(newSelected);
    onChange?.(
      mode === "single"
        ? newSelected.length > 0
          ? newSelected[0]
          : undefined
        : newSelected
    );
    if (mode === "single") {
      setIsOpen(false);
      setSearchText("");
    }
  };

  const handleClear = () => {
    setSelectedValues([]);
    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];

  // Theme colors from context (consistent with other components)
  const { colors } = useThemeContext();
  const selectBackgroundColor = disabled
    ? colors.backgroundSecondary
    : colors.surface;

  let displayText = placeholder;
  if (selectedValues.length > 0) {
    if (mode === "single") {
      const opt = options.find((o) => o.value === selectedValues[0]);
      displayText = opt?.label || placeholder;
    } else {
      const labels = selectedValues
        .map((v) => options.find((o) => o.value === v)?.label)
        .filter(Boolean);
      displayText = labels.join(", ");
    }
  }

  return (
    <View style={styles.wrapper}>
      <TouchableOpacity
        style={[
          styles.container,
          {
            height: Math.max(sz.height, textHeight + 16), // Add padding
            paddingHorizontal: sz.paddingHorizontal,
            backgroundColor: selectBackgroundColor,
            borderColor: disabled ? colors.border : colors.primary,
          },
          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={colors.primary} />
          ) : (
            <Text
              style={[
                styles.text,
                {
                  fontSize: sz.fontSize,
                  color: disabled
                    ? colors.textSecondary
                    : selectedValues.length > 0
                    ? colors.text
                    : colors.textSecondary,
                },
              ]}
              onLayout={(e) => setTextHeight(e.nativeEvent.layout.height)}
            >
              {displayText}
            </Text>
          )}
        </View>
        <View style={styles.suffix}>
          {allowClear && selectedValues.length > 0 && !loading ? (
            <TouchableOpacity onPress={handleClear} style={styles.icon}>
              <AntDesign name="close" size={16} color={colors.textSecondary} />
            </TouchableOpacity>
          ) : null}
          <AntDesign
            name={isOpen ? "up" : "down"}
            size={14}
            color={colors.textSecondary}
            style={styles.arrow}
          />
        </View>
      </TouchableOpacity>

      {isOpen && (
        <View
          style={[
            styles.dropdown,
            {
              top: containerHeight,
              backgroundColor: colors.background,
              borderColor: colors.border,
            },
          ]}
        >
          {showSearch && (
            <TextInput
              style={[
                styles.searchInput,
                {
                  backgroundColor: colors.background,
                  borderColor: colors.border,
                  color: colors.text,
                },
              ]}
              placeholder="Search..."
              placeholderTextColor={colors.textSecondary}
              value={searchText}
              onChangeText={setSearchText}
              autoFocus
            />
          )}
          <ScrollView style={[styles.list, listStyle]}>
            {filteredOptions.map((item) => (
              <TouchableOpacity
                key={item.value}
                style={[
                  styles.option,
                  {
                    borderBottomColor: colors.separator,
                  },
                  item.disabled && styles.optionDisabled,
                  selectedValues.includes(item.value) && {
                    backgroundColor: colors.primary + "20", // Add transparency to primary color
                  },
                ]}
                onPress={() => !item.disabled && handleSelect(item.value)}
                disabled={item.disabled}
              >
                <Text
                  style={[
                    styles.optionText,
                    {
                      color: colors.text,
                    },
                    item.disabled && {
                      color: colors.textSecondary,
                    },
                    selectedValues.includes(item.value) && {
                      color: colors.primary,
                      fontWeight: "600",
                    },
                  ]}
                >
                  {item.label}
                </Text>
                {selectedValues.includes(item.value) && (
                  <AntDesign name="check" size={16} color={colors.primary} />
                )}
              </TouchableOpacity>
            ))}
          </ScrollView>
        </View>
      )}
    </View>
  );
};

const styles = StyleSheet.create({
  wrapper: {
    position: "relative",
  },
  container: {
    borderWidth: 1,
    borderRadius: 8,
    flexDirection: "row",
    alignItems: "center",
    justifyContent: "space-between",
  },
  content: {
    flex: 1,
  },
  text: {
    // Color is set dynamically via theme
  },
  suffix: {
    flexDirection: "row",
    alignItems: "center",
  },
  icon: {
    marginRight: 8,
  },
  arrow: {
    marginLeft: 4,
  },
  dropdown: {
    position: "absolute",
    left: 0,
    right: 0,
    borderWidth: 1,
    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,
    borderRadius: 4,
    padding: 8,
    margin: 8,
  },
  list: {
    maxHeight: 200,
  },
  option: {
    padding: 12,
    borderBottomWidth: 1,
    flexDirection: "row",
    justifyContent: "space-between",
    alignItems: "center",
  },
  optionDisabled: {
    opacity: 0.5,
  },
  // optionSelected is handled dynamically via inline styles
  optionText: {
    fontSize: 16,
  },
  // optionTextDisabled and optionTextSelected are handled dynamically via inline styles
});

export default Select;
