import Feather from '@expo/vector-icons/Feather'
import { useMemo } from 'react'
import { ICON } from 'src/lib/icons'
import { Adapt, Label, Select, Separator, Sheet, View, XStack, YStack } from 'tamagui'

export type FormSelectOption = {
  value: string
  label?: string
}

type FormSelectProps = {
  value: string | undefined
  onValueChange: (value: string) => void
  options: FormSelectOption[]
  placeholder?: string
  label?: string
  title?: string
  triggerWidth?: number | '100%'
  disabled?: boolean
}

// Label + Select row. Use FormSelectItem directly when you don't want the
// label prefix (e.g. when the trigger should span the full width).
export function FormSelect({ label, ...rest }: FormSelectProps) {
  return (
    <YStack flexGrow={1} gap="$4">
      <XStack alignItems="center" justifyContent="space-between" gap="$4">
        {label ? (
          <Label minWidth={80} fontSize="$5" color="$colorSecondary">
            {label}
          </Label>
        ) : null}
        <FormSelectItem {...rest} />
      </XStack>
    </YStack>
  )
}

export function FormSelectItem({
  value,
  onValueChange,
  options,
  placeholder = 'Select an option',
  title,
  triggerWidth = 220,
  disabled,
}: Omit<FormSelectProps, 'label'>) {
  const items = useMemo(
    () =>
      options.map((opt, i) => (
        <View key={opt.value}>
          <Separator />
          <Select.Item index={i} value={opt.value} py="$3" alignItems="center">
            <YStack flexGrow={1} py="$2">
              <XStack>
                <Select.ItemText
                  flexWrap="wrap"
                  fontSize="$6"
                  fontWeight={value === opt.value ? 'bold' : 'normal'}
                >
                  {opt.label ?? opt.value}
                </Select.ItemText>
                <Select.ItemIndicator marginLeft="auto">
                  <Feather name="check" size={ICON.sm} />
                </Select.ItemIndicator>
              </XStack>
            </YStack>
          </Select.Item>
        </View>
      )),
    [options, value]
  )

  return (
    <Select value={value} onValueChange={onValueChange} disablePreventBodyScroll>
      <Select.Trigger
        width={triggerWidth as any}
        iconAfter={<Feather name="chevron-down" />}
        backgroundColor="$background"
        borderColor="$borderColor"
        borderWidth={1}
        disabled={disabled}
        opacity={disabled ? 0.5 : 1}
      >
        <Select.Value placeholder={placeholder} />
      </Select.Trigger>

      <Adapt when="sm" platform="touch">
        <Sheet
          modal
          dismissOnSnapToBottom
          transitionConfig={{
            type: 'spring',
            damping: 20,
            mass: 1.2,
            stiffness: 250,
          }}
        >
          <Sheet.Frame>
            <Sheet.ScrollView>
              <Adapt.Contents />
            </Sheet.ScrollView>
          </Sheet.Frame>
          <Sheet.Overlay
            transition="lazy"
            enterStyle={{ opacity: 0 }}
            exitStyle={{ opacity: 0 }}
          />
        </Sheet>
      </Adapt>

      <Select.Content>
        <Select.ScrollUpButton
          alignItems="center"
          justifyContent="center"
          position="relative"
          width="100%"
          height="$3"
        >
          <YStack zIndex={10}>
            <Feather name="chevron-up" size={ICON.md} />
          </YStack>
        </Select.ScrollUpButton>

        <Select.Viewport
          transition="quick"
          transitionProperty={['transform', 'opacity']}
          enterStyle={{ o: 0, y: -10 }}
          exitStyle={{ o: 0, y: 10 }}
        >
          <Select.Group>
            {title ? <Select.Label>{title}</Select.Label> : null}
            {items}
          </Select.Group>
        </Select.Viewport>

        <Select.ScrollDownButton
          alignItems="center"
          justifyContent="center"
          position="relative"
          width="100%"
          height="$3"
        >
          <YStack zIndex={10}>
            <Feather name="chevron-down" size={ICON.md} />
          </YStack>
        </Select.ScrollDownButton>
      </Select.Content>
    </Select>
  )
}
