import React, { useState } from 'react';
import type { StyleProp, ViewStyle } from 'react-native';
import { FlatList, TouchableOpacity, View } from 'react-native';
import type { BottomSheetProps } from '../../BottomSheet';
import BottomSheet from '../../BottomSheet';
import Typography from '../../Typography';
import Icon from '../../Icon';
import List from '../../List';
import { deepCompareValue, useKeyboard } from '../../../utils/helpers';
import { StyledHeaderContainer } from './StyledChartSelect';

/**
 * Represents a selectable option for ChartSelect.
 * @template V The type of the option value.
 * @property value The value of the option. Used for selection and comparison.
 * @property text The display text for the option.
 * @property key (Optional) A unique key for the option. If provided, used as the FlatList key for better performance and stability.
 */
type OptionType<V> = {
  value: V;
  text: string;
  key?: string;
};

export interface SingleSelectProps<V> {
  /**
   * The currently selected value. Should match one of the values in the options array.
   */
  value: V | null;
  /**
   * Callback fired when an option is selected.
   * @param value The value of the selected option.
   */
  onConfirm: (value: V) => void;
  /**
   * Array of supported orientations for the Select modal (iOS only).
   * Defaults to ['portrait'].
   */
  supportedOrientations?: ('portrait' | 'landscape')[];
  /**
   * The list of selectable options. Each option should have a value and display text.
   */
  options: OptionType<V>[];
  /**
   * Callback fired when the selection modal is dismissed without selecting an option.
   */
  onDismiss?: () => void;
  /**
   * Configuration for the bottom sheet modal.
   * - variant: The visual variant of the bottom sheet.
   * - header: Optional header text to display at the top of the bottom sheet.
   */
  bottomSheetConfig?: {
    variant?: BottomSheetProps['variant'];
    header?: BottomSheetProps['header'];
  };
  /**
   * If true, the select is disabled and cannot be interacted with.
   * @default false
   */
  disabled?: boolean;
  /**
   * Additional style to apply to the select container.
   */
  style?: StyleProp<ViewStyle>;
  /**
   * Optional test ID for testing purposes. Applied to the main touchable area.
   */
  testID?: string;
}

const SingleSelect = <V,>({
  onConfirm,
  onDismiss,
  options = [],
  disabled = false,
  style,
  testID,
  value,
  supportedOrientations = ['portrait'],
  bottomSheetConfig = {},
}: SingleSelectProps<V>) => {
  const { isKeyboardVisible, keyboardHeight } = useKeyboard();
  const [open, setOpen] = useState(false);

  const displayedValue =
    options.find((opt) => deepCompareValue(opt.value, value))?.text || '';

  const { variant: bottomSheetVariant, header: bottomSheetHeader = '' } =
    bottomSheetConfig;

  return (
    <>
      <View pointerEvents={disabled ? 'none' : 'auto'} style={style}>
        <TouchableOpacity onPress={() => setOpen(true)}>
          <StyledHeaderContainer pointerEvents="none" testID={testID}>
            <Typography.Body variant="small-bold">
              {displayedValue}
            </Typography.Body>
            <Icon icon="arrow-down" intent="primary" size="small" />
          </StyledHeaderContainer>
        </TouchableOpacity>
      </View>

      <BottomSheet
        variant={bottomSheetVariant || 'fixed'}
        open={open}
        onRequestClose={() => {
          onDismiss?.();
          setOpen(false);
        }}
        header={bottomSheetHeader}
        style={{
          paddingBottom: isKeyboardVisible ? keyboardHeight : 0,
        }}
        supportedOrientations={supportedOrientations}
        testID="bottomSheet"
      >
        <FlatList
          data={options}
          keyExtractor={(item) => item.key ?? String(item.value)}
          renderItem={({ item }) => (
            <List.BasicItem
              selected={deepCompareValue(item.value, value)}
              title={item.text}
              onPress={() => {
                setOpen(false);
                onConfirm?.(item.value);
              }}
            />
          )}
        />
      </BottomSheet>
    </>
  );
};

export default SingleSelect;
