import {
  makeStyles,
  mergeClasses,
  tokens,
  shorthands,
  useFieldControlProps_unstable
} from '@fluentui/react-components'

// A native <select> styled to match Fluent inputs. We use this instead of
// Fluent's <Dropdown> because Fluent's portal/popover menu is a composited
// overlay in the WebContents, and on this dev machine's GPU/driver that overlay
// paint blanks the whole window (same family as the documented flicker --
// hardware acceleration is already disabled; see memory "aerofetch-gpu-flicker").
// The native <select> popup is drawn by the OS, so it can't trigger the blank.
// The popup's light/dark styling follows the `color-scheme` set on the app root
// in App.tsx.
const useStyles = makeStyles({
  select: {
    width: '100%',
    height: '32px',
    padding: '0 8px',
    fontSize: tokens.fontSizeBase300,
    fontFamily: tokens.fontFamilyBase,
    color: tokens.colorNeutralForeground1,
    backgroundColor: tokens.colorNeutralBackground1,
    border: `1px solid ${tokens.colorNeutralStroke1}`,
    ...shorthands.borderRadius(tokens.borderRadiusMedium),
    cursor: 'pointer',
    ':hover': {
      ...shorthands.borderColor(tokens.colorNeutralStroke1Hover)
    },
    ':focus-visible': {
      outline: 'none',
      ...shorthands.borderColor(tokens.colorCompoundBrandStroke)
    }
  },
  large: {
    height: '40px',
    padding: '0 12px',
    fontSize: tokens.fontSizeBase400
  },
  disabled: {
    cursor: 'not-allowed',
    color: tokens.colorNeutralForegroundDisabled,
    backgroundColor: tokens.colorNeutralBackgroundDisabled,
    ...shorthands.borderColor(tokens.colorNeutralStrokeDisabled),
    ':hover': {
      ...shorthands.borderColor(tokens.colorNeutralStrokeDisabled)
    }
  }
})

export interface SelectOption {
  value: string
  label: string
}

interface SelectProps {
  value: string
  options: SelectOption[]
  onChange: (value: string) => void
  className?: string
  'aria-label'?: string
  size?: 'medium' | 'large'
  disabled?: boolean
}

export function Select({
  value,
  options,
  onChange,
  className,
  'aria-label': ariaLabel,
  size,
  disabled
}: SelectProps): React.JSX.Element {
  const styles = useStyles()
  // Integrate with a wrapping Fluent <Field> (L133): pick up the id + label/hint
  // association so the Field's visible label names the select natively (via
  // `htmlFor`), instead of every call site repeating the name in an `aria-label`.
  // Outside a Field this returns the props unchanged, so standalone selects keep
  // their own `aria-label`. `supportsLabelFor` = native <label for>, not aria-labelledby.
  const fieldProps = useFieldControlProps_unstable({}, { supportsLabelFor: true })
  return (
    <select
      {...fieldProps}
      aria-label={ariaLabel}
      className={mergeClasses(
        styles.select,
        size === 'large' && styles.large,
        disabled && styles.disabled,
        className
      )}
      value={value}
      onChange={(e) => onChange(e.target.value)}
      disabled={disabled}
    >
      {options.map((o) => (
        <option key={o.value} value={o.value}>
          {o.label}
        </option>
      ))}
    </select>
  )
}
