import { type VariantProps, cva } from 'class-variance-authority';
import React from 'react';
import {
  BaseSelectContent,
  BaseSelectGroup,
  BaseSelectItem,
  BaseSelectLabel,
  BaseSelectScrollDownButton,
  BaseSelectScrollUpButton,
  BaseSelectSeparator,
  BaseSelectTrigger,
  BaseSelectValue,
  BaseSelect as Select,
} from './BaseSelect';
import styles from './Select.module.css';

const selectTriggerVariants = cva(styles.SelectTrigger, {
  variants: {
    variant: {
      default: styles.SelectTriggerDefault,
      outline: styles.SelectTriggerOutline,
    },
    size: {
      default: styles.SelectTriggerSizeDefault,
      sm: styles.SelectTriggerSizeSm,
      lg: styles.SelectTriggerSizeLg,
    },
  },
  defaultVariants: {
    variant: 'default',
    size: 'default',
  },
});

const selectContentVariants = cva(styles.SelectContent, {
  variants: {
    variant: {
      default: styles.SelectContentDefault,
      outline: styles.SelectContentOutline,
    },
  },
  defaultVariants: {
    variant: 'default',
  },
});

const selectItemVariants = cva(styles.SelectItem, {
  variants: {
    variant: {
      default: styles.SelectItemDefault,
      highlight: styles.SelectItemHighlight,
    },
  },
  defaultVariants: {
    variant: 'default',
  },
});

const selectLabelVariants = cva(styles.SelectLabel, {
  variants: {
    variant: {
      default: styles.SelectLabelDefault,
    },
  },
  defaultVariants: {
    variant: 'default',
  },
});

const SelectTrigger = React.forwardRef<
  React.ElementRef<typeof BaseSelectTrigger>,
  SelectTriggerProps
>(
  (
    {
      className,
      variant,
      size,
      children,
      'aria-label': ariaLabel,
      'aria-labelledby': ariaLabelledBy,
      ...props
    },
    ref,
  ) => {
    return (
      <BaseSelectTrigger
        ref={ref}
        className={selectTriggerVariants({
          variant,
          size,
          className,
        })}
        aria-label={ariaLabel || 'Select option'}
        aria-labelledby={ariaLabelledBy}
        {...props}
      >
        {children || (
          <span className={styles.SelectPlaceholder}>Select an option</span>
        )}
      </BaseSelectTrigger>
    );
  },
);

const SelectContent = React.forwardRef<
  React.ElementRef<typeof BaseSelectContent>,
  SelectContentProps
>(({ className, variant, ...props }, ref) => (
  <BaseSelectContent
    ref={ref}
    className={selectContentVariants({
      variant,
      className,
    })}
    {...props}
  />
));

const SelectItem = React.forwardRef<
  React.ElementRef<typeof BaseSelectItem>,
  SelectItemProps
>(({ className, variant, ...props }, ref) => (
  <BaseSelectItem
    ref={ref}
    className={selectItemVariants({ variant, className })}
    {...props}
  />
));

const SelectLabel = React.forwardRef<
  React.ElementRef<typeof BaseSelectLabel>,
  SelectLabelProps
>(({ className, variant, ...props }, ref) => (
  <BaseSelectLabel
    ref={ref}
    className={selectLabelVariants({ variant, className })}
    {...props}
  />
));

const SelectGroup = BaseSelectGroup;
const SelectValue = BaseSelectValue;
const SelectSeparator = BaseSelectSeparator;
const SelectScrollUpButton = BaseSelectScrollUpButton;
const SelectScrollDownButton = BaseSelectScrollDownButton;

SelectContent.displayName = 'SelectContent';
SelectItem.displayName = 'SelectItem';
SelectTrigger.displayName = 'SelectTrigger';
SelectLabel.displayName = 'SelectLabel';

export type SelectItemProps = React.ComponentPropsWithoutRef<
  typeof BaseSelectItem
> &
  VariantProps<typeof selectItemVariants>;

export type SelectContentProps = React.ComponentPropsWithoutRef<
  typeof BaseSelectContent
> &
  VariantProps<typeof selectContentVariants>;

export type SelectTriggerProps = React.ComponentPropsWithoutRef<
  typeof BaseSelectTrigger
> &
  VariantProps<typeof selectTriggerVariants>;

export type SelectLabelProps = React.ComponentPropsWithoutRef<
  typeof BaseSelectLabel
> &
  VariantProps<typeof selectLabelVariants>;

export {
  Select,
  SelectGroup,
  SelectValue,
  SelectTrigger,
  SelectContent,
  SelectLabel,
  SelectItem,
  SelectSeparator,
  SelectScrollUpButton,
  SelectScrollDownButton,
};
