import { Canvas, Stories, Controls, Meta, Story } from '@storybook/addon-docs/blocks';
import Box from '@mui/material/Box';
import Demo from '@lunit/design-system-icons/Demo';
import ViewfinderT1 from '@lunit/design-system-icons/ViewfinderT1';
import RulerT2 from '@lunit/design-system-icons/RulerT2';

import Dropdown, { DropdownItem, DropdownDivider, DropdownSubtitle } from '@/components/Dropdown';
import * as DropdownStories from './Dropdown.stories';
import * as DropdownExampleStories from './DropdownExamples.stories';
import * as DropdownItemStories from './DropdownItem.stories';

<Meta name="Dropdown Docs" of={DropdownStories} />

# Dropdown

Dropdowns allow users to select one or multiple options from a list of choices.

## Usage

### Basic Dropdown

```tsx
import { Dropdown, DropdownItem } from '@lunit/design-system';
// or
import Dropdown, { DropdownItem } from '@lunit/design-system/Dropdown';

<Dropdown value={selectedValue} onChange={handleChange}>
  <DropdownItem value="option1">Option 1</DropdownItem>
  <DropdownItem value="option2">Option 2</DropdownItem>
</Dropdown>;
```

### Demo

<Canvas of={DropdownStories.BasicDropdown} sourceState="none" />

<Controls />

### Size

The Dropdown has three sizes: `small`, `medium` and `large`.<br />
Using the `size` prop, you can change the size of the Dropdown.<br />
Default size is `medium`.

<Canvas of={DropdownStories.Size} meta={DropdownStories} sourceState="none" />

```tsx
<Dropdown size="small" value={selectedValue} onChange={handleChange}>
  <DropdownItem value="option1">Small Option 1</DropdownItem>
  <DropdownItem value="option2">Small Option 2</DropdownItem>
</Dropdown>

<Dropdown size="medium" value={selectedValue} onChange={handleChange}>
  <DropdownItem value="option1">Medium Option 1</DropdownItem>
  <DropdownItem value="option2">Medium Option 2</DropdownItem>
</Dropdown>

<Dropdown size="large" value={selectedValue} onChange={handleChange}>
  <DropdownItem value="option1">Large Option 1</DropdownItem>
  <DropdownItem value="option2">Large Option 2</DropdownItem>
</Dropdown>
```

### Select Type

The Dropdown has two select types: `single` and `multiple`.<br />
Using the `select` prop, you can change the select type of the Dropdown.<br />
Default select type is `single`.

<Canvas of={DropdownStories.SelectType} meta={DropdownStories} sourceState="none" />

```tsx
// Single select
<Dropdown select="single" value={selectedValue} onChange={handleChange}>
  <DropdownItem value="option1">Single Option 1</DropdownItem>
  <DropdownItem value="option2">Single Option 2</DropdownItem>
</Dropdown>

// Multiple select
<Dropdown select="multiple" value={selectedValues} onChange={handleChange}>
  <DropdownItem value="option1">Multiple Option 1</DropdownItem>
  <DropdownItem value="option2">Multiple Option 2</DropdownItem>
</Dropdown>
```

### Error State

If you want to show an error state, you can use the `error` prop.<br />
Default error is `false`.

<Canvas of={DropdownStories.Error} sourceState="none" />

```tsx
<Dropdown error value={selectedValue} onChange={handleChange}>
  <DropdownItem value="option1">Option 1</DropdownItem>
  <DropdownItem value="option2">Option 2</DropdownItem>
</Dropdown>
```

### Disabled

If you want to disable the Dropdown, you can use the `disabled` prop.<br />
Default disabled is `false`.

<Canvas of={DropdownStories.Disabled} sourceState="none" />

```tsx
<Dropdown disabled value={selectedValue} onChange={handleChange}>
  <DropdownItem value="option1">Option 1</DropdownItem>
  <DropdownItem value="option2">Option 2</DropdownItem>
</Dropdown>
```

## DropdownItem

### Basic DropdownItem

<Canvas of={DropdownItemStories.BasicDropdownItem} sourceState="none" />

```tsx
<DropdownItem value="option1">Basic Option</DropdownItem>
```

### DropdownItem Filled Style

For GNB or specific single select situations, you can use the `isFilledStyle` prop.<br />
Default isFilledStyle is `false`.

<Canvas
  of={DropdownItemStories.DropdownItemSelectStyle}
  meta={DropdownItemStories}
  sourceState="none"
/>

```tsx
// Filled Style DropdownItem in GNB
<DropdownItem value="option1" isFilledStyle>
  Filled Style Option
</DropdownItem>
```

### DropdownItem with Left Icon and Right Text

DropdownItem can have a left icon and right text using the `leftIcon` and `rightText` props.

<Canvas
  of={DropdownItemStories.DropdownItemWithIconText}
  meta={DropdownItemStories}
  sourceState="none"
/>

```tsx
<DropdownItem value="option1" leftIcon={<Demo fontSize="small" />} rightText="shortcut">
  Option with Icon
</DropdownItem>
```

### DropdownItem with Divider and Subtitle

You can organize dropdown items using `DropdownDivider` and `DropdownSubtitle` components.

<Canvas
  of={DropdownItemStories.DropdownItemDividerSubtitle}
  meta={DropdownItemStories}
  sourceState="none"
/>

```tsx
<Dropdown value={selectedValue} onChange={handleChange}>
  <DropdownSubtitle title="Category 1" />
  <DropdownItem value="option1">Option 1</DropdownItem>
  <DropdownItem value="option2">Option 2</DropdownItem>
  <DropdownDivider />
  <DropdownSubtitle title="Category 2" />
  <DropdownItem value="option3">Option 3</DropdownItem>
  <DropdownItem value="option4">Option 4</DropdownItem>
</Dropdown>
```

## Advanced Examples

<Canvas
  of={DropdownExampleStories.DropdownExamples}
  meta={DropdownExampleStories}
  sourceState="none"
/>

### Placeholder

You can implement placeholder functionality using the `displayEmpty` and `renderValue` props.<br /><br />
This example is simplified for demonstration purposes and may not fully match the default component behavior.<br />
For multiple select, the selected items in this example are shown in the order the user selected them.
However, the default Dropdown component displays selected items based on their order in the option list.

```tsx
// Single select with placeholder
<Dropdown
  value={selectedValue}
  onChange={handleChange}
  displayEmpty
  renderValue={(selected) => {
    if (!selected) {
      // This code applies styling to the placeholder text
      return <Box sx={{ color: 'text.secondary' }}>Select an option</Box>;
    }
    return selected;
  }}
>
  <DropdownItem value="option1">Option 1</DropdownItem>
  <DropdownItem value="option2">Option 2</DropdownItem>
</Dropdown>

// Multiple select with placeholder
<Dropdown
  select="multiple"
  value={selectedValues}
  onChange={handleChange}
  displayEmpty
  renderValue={(selected) => {
    if ((selected as string[]).length === 0) {
       // This code applies styling to the placeholder text
      return <Box sx={{ color: 'text.secondary' }}>Select options</Box>;
    }
    return (selected as string[]).join(', ');
  }}
>
  <DropdownItem value="option1">Option 1</DropdownItem>
  <DropdownItem value="option2">Option 2</DropdownItem>
</Dropdown>
```

### Button Dropdown

You can create a button-triggered dropdown by controlling the `open`, `onClose`, and `onOpen` props.<br /><br />
In most cases, you don’t need to manage the `open` state manually, as the Dropdown handles it internally.
This example explicitly defines the `open` state to demonstrate how a dropdown can be controlled using an external trigger, such as a button.

```tsx
const [open, setOpen] = useState(false);

<Box sx={{ position: 'relative' }}>
  <Button onClick={() => setOpen(true)}>Dropdown Button</Button>
  <Dropdown
    value={selectedValue}
    onChange={handleChange}
    open={open}
    onClose={() => setOpen(false)}
    onOpen={() => setOpen(true)}
    sx={{
      position: 'absolute',
      clip: 'rect(0 0 0 0)',
      clipPath: 'inset(50%)',
      height: '1px',
      overflow: 'hidden',
      whiteSpace: 'nowrap',
      width: '1px',
    }}
  >
    <DropdownItem value="option1">Option 1</DropdownItem>
    <DropdownItem value="option2">Option 2</DropdownItem>
  </Dropdown>
</Box>;
```

## Reference

- [Material-UI Select](https://mui.com/material-ui/react-select/)
- [Material-UI Select API](https://mui.com/material-ui/api/select/)
- [Material-UI MenuItem API](https://mui.com/material-ui/api/menu-item/)
- [Lunit Design System Dropdown Figma](https://www.figma.com/design/9CoirIDPof6exynJosiGXi/Design-System_2.0.0_Latest?node-id=474-56086&m=dev)

## Support

- Github: [Create a new issue](https://github.com/lunit-io/design-system/issues/new)
- Slack: #tf_design_system
