import type { Meta, StoryObj } from '@storybook/react'
import React from 'react'
import { LabeledCheckbox } from '../Checkbox'
import {
  Combobox,
  ComboboxContent,
  ComboboxEmpty,
  ComboboxInput,
  ComboboxItem,
  ComboboxList,
  ComboboxTagsValue,
  ComboboxTrigger,
  ComboboxValue,
} from '../Combobox/Combobox'
import { Field, FieldLabel } from '../Field'
import { RadioGroup, RadioGroupItem } from '../RadioGroup'
import {
  Select,
  SelectTrigger,
  SelectContent,
  SelectItem,
  SelectValue,
} from '../Select/Select'
import { SimpleSelect } from '../Select/SimpleSelect'
import { Textarea } from '../Textarea'
import { Typography } from '../Typography'
import { FieldInput } from './FieldInput'
import { Input } from './Input'
import {
  assertAllInputTokens,
  assertDropdownContentTokens,
  comboboxOptions,
  manyOptions,
  multiSelectOptions,
  selectOptions,
  type StateTokens,
} from './storybook-test-utils'

type SimpleOption = { label: string; value: string }

const stateTokens: Record<string, StateTokens> = {
  default: {
    border: '--input-border',
    bg: '--input',
    text: '--input-foreground',
    placeholder: '--input-muted-foreground',
    caret: '--input-foreground',
    badgeText: '--pill-foreground',
    badgeRemoveColor: '--muted-more-foreground',
  },
  hover: { border: '--input-border-hover', bg: '--input' },
  active: {
    border: '--input-border-active',
    bg: '--input',
    dropdown: {
      checkmarkColor: '--brand',
      unselectedText: '--muted-foreground',
      searchPlaceholder: '--input-muted-foreground',
      searchIconColor: '--input-muted-foreground',
    },
  },
  disabled: {
    border: '--input-border-disabled',
    bg: '--input-disabled',
    text: '--input-muted-more-foreground',
    placeholder: '--input-muted-more-foreground',
    caret: '--input-muted-more-foreground',
    badgeText: '--input-muted-more-foreground',
    badgeRemoveColor: '--input-muted-more-foreground',
  },
}

const meta = {
  title: 'Form/Inputs comparison',
  parameters: {
    layout: 'padded',
  },
} satisfies Meta

export default meta

type Story = StoryObj<typeof meta>

export const Default: Story = {
  render: (_args) => (
    <div className="flex flex-col gap-8 p-8">
      <Typography variant="h4">Default State — Input Components</Typography>

      <div className="grid grid-cols-2 gap-x-12 gap-y-6">
        <InputRow label="Input">
          <Input placeholder="Placeholder" />
        </InputRow>

        <InputRow label="Input (with value)">
          <Input defaultValue="John Doe" />
        </InputRow>

        <InputRow label="FieldInput">
          <FieldInput placeholder="Placeholder" />
        </InputRow>

        <InputRow label="FieldInput (with value)">
          <FieldInput defaultValue="John Doe" />
        </InputRow>

        <InputRow label="Textarea">
          <Textarea placeholder="Type something..." />
        </InputRow>

        <InputRow label="Textarea (with value)">
          <Textarea defaultValue="Some pre-filled content here." />
        </InputRow>

        <SelectBlock label="Select" />

        <SelectBlock label="Select (with value)" defaultValue="option1" />

        <SimpleSelectBlock label="SimpleSelect" />

        <SimpleSelectBlock
          label="SimpleSelect (with value)"
          defaultValue="option1"
        />

        <ComboboxSingleBlock label="Combobox" />

        <ComboboxSingleBlock
          label="Combobox (with value)"
          defaultValue={comboboxOptions[0]}
        />

        <ComboboxMultiBlock label="Combobox (multiple)" />

        <ComboboxMultiBlock
          label="Combobox multiple (with value)"
          defaultValue={[multiSelectOptions[0]]}
        />

        <InputRow label="FieldInput (not clearable, with value)">
          <FieldInput defaultValue="John Doe" clearable={false} />
        </InputRow>

        <SelectBlock
          label="Select (not clearable, with value)"
          defaultValue="option1"
          clearable={false}
        />

        <ComboboxSingleBlock
          label="Combobox (not clearable, with value)"
          defaultValue={comboboxOptions[0]}
          clearable={false}
        />

        <InputRow label="Checkbox (unchecked)">
          <LabeledCheckbox>Accept terms</LabeledCheckbox>
        </InputRow>

        <InputRow label="Checkbox (checked)">
          <LabeledCheckbox defaultChecked>Accept terms</LabeledCheckbox>
        </InputRow>

        <InputRow label="RadioGroup (unchecked)">
          <RadioGroup>
            <RadioGroupItem value="a">Option A</RadioGroupItem>
            <RadioGroupItem value="b">Option B</RadioGroupItem>
          </RadioGroup>
        </InputRow>

        <InputRow label="RadioGroup (with value)">
          <RadioGroup defaultValue="a">
            <RadioGroupItem value="a">Option A</RadioGroupItem>
            <RadioGroupItem value="b">Option B</RadioGroupItem>
          </RadioGroup>
        </InputRow>
      </div>
    </div>
  ),
  play: async ({ canvasElement }) => {
    await assertAllInputTokens(canvasElement, stateTokens.default)
  },
}

export const ActiveInputs: Story = {
  render: (_args) => (
    <div className="flex flex-col gap-8 p-8">
      <Typography variant="h4">Active State — Input & Textarea</Typography>

      <div className="flex items-start gap-12">
        <Field>
          <FieldLabel>Input</FieldLabel>
          <Input placeholder="Placeholder" className="focus" />
        </Field>

        <Field>
          <FieldLabel>Input (filled)</FieldLabel>
          <Input defaultValue="Ethereum" className="focus" />
        </Field>
      </div>

      <div className="flex items-start gap-12">
        <Field>
          <FieldLabel>FieldInput</FieldLabel>
          <FieldInput placeholder="Placeholder" className="focus" />
        </Field>

        <Field>
          <FieldLabel>FieldInput (filled)</FieldLabel>
          <FieldInput defaultValue="Ethereum" className="focus" />
        </Field>
      </div>

      <div className="flex items-start gap-12">
        <Field>
          <FieldLabel>Textarea</FieldLabel>
          <Textarea placeholder="Type something..." className="focus" />
        </Field>

        <Field>
          <FieldLabel>Textarea (filled)</FieldLabel>
          <Textarea defaultValue="Some content here" className="focus" />
        </Field>
      </div>
    </div>
  ),
  play: async ({ canvasElement }) => {
    await assertAllInputTokens(canvasElement, stateTokens.active)
  },
}

export const ActiveDropdowns: Story = {
  render: (_args) => (
    <div className="flex flex-col gap-8 p-8">
      <Typography variant="h4">Active State — Dropdowns</Typography>

      <div className="flex items-start gap-12">
        <Field>
          <FieldLabel>Select</FieldLabel>
          <Select defaultOpen>
            <SelectTrigger>
              <SelectValue placeholder="Select network..." />
            </SelectTrigger>
            <SelectContent>
              {manyOptions.map((opt) => (
                <SelectItem key={opt.value} value={opt.value}>
                  {opt.label}
                </SelectItem>
              ))}
            </SelectContent>
          </Select>
        </Field>

        <Field>
          <FieldLabel>Combobox</FieldLabel>
          <Combobox
            items={manyOptions}
            itemToStringValue={(opt: SimpleOption) => opt.label}
            defaultOpen
          >
            <ComboboxTrigger>
              <ComboboxValue placeholder="Select network..." />
            </ComboboxTrigger>
            <ComboboxContent>
              <ComboboxInput placeholder="Search..." />
              <ComboboxEmpty>No results found.</ComboboxEmpty>
              <ComboboxList>
                {(option: SimpleOption) => (
                  <ComboboxItem key={option.value} value={option}>
                    {option.label}
                  </ComboboxItem>
                )}
              </ComboboxList>
            </ComboboxContent>
          </Combobox>
        </Field>

        <Field>
          <FieldLabel>Combobox (multiple)</FieldLabel>
          <Combobox
            multiple
            items={manyOptions}
            itemToStringValue={(opt: SimpleOption) => opt.label}
            defaultOpen
          >
            <ComboboxTrigger>
              <ComboboxTagsValue<SimpleOption>
                placeholder="Select networks..."
                maxCount={3}
              >
                {(opt: SimpleOption) => opt.label}
              </ComboboxTagsValue>
            </ComboboxTrigger>
            <ComboboxContent>
              <ComboboxInput placeholder="Search..." />
              <ComboboxEmpty>No results found.</ComboboxEmpty>
              <ComboboxList>
                {(option: SimpleOption) => (
                  <ComboboxItem key={option.value} value={option}>
                    {option.label}
                  </ComboboxItem>
                )}
              </ComboboxList>
            </ComboboxContent>
          </Combobox>
        </Field>
      </div>
    </div>
  ),
  play: async ({ canvasElement }) => {
    await assertAllInputTokens(canvasElement, stateTokens.active)
  },
}

const MULTI_MAX_COUNT = 3

function ActiveDropdownsFilledMulti() {
  const [selected, setSelected] = React.useState<SimpleOption[]>([
    manyOptions[1],
    manyOptions[2],
    manyOptions[3],
    manyOptions[4],
  ])

  return (
    <Combobox
      multiple
      items={manyOptions}
      itemToStringValue={(opt: SimpleOption) => opt.label}
      defaultOpen
      value={selected}
      onValueChange={(val: unknown) =>
        setSelected((val ?? []) as SimpleOption[])
      }
    >
      <ComboboxTrigger>
        <ComboboxTagsValue<SimpleOption>
          placeholder="Select networks..."
          maxCount={MULTI_MAX_COUNT}
        >
          {(opt: SimpleOption) => opt.label}
        </ComboboxTagsValue>
      </ComboboxTrigger>
      <ComboboxContent>
        <ComboboxInput placeholder="Search..." />
        <ComboboxEmpty>No results found.</ComboboxEmpty>
        <ComboboxList>
          {(option: SimpleOption) => (
            <ComboboxItem key={option.value} value={option}>
              {option.label}
            </ComboboxItem>
          )}
        </ComboboxList>
      </ComboboxContent>
    </Combobox>
  )
}

export const ActiveDropdownsFilled: Story = {
  render: (_args) => (
    <div className="flex flex-col gap-8 p-8">
      <Typography variant="h4">Active State — Dropdowns (filled)</Typography>

      <div className="flex items-start gap-12">
        <Field>
          <FieldLabel>Select (filled)</FieldLabel>
          <Select defaultOpen defaultValue="ethereum">
            <SelectTrigger>
              <SelectValue placeholder="Select network..." />
            </SelectTrigger>
            <SelectContent>
              {manyOptions.map((opt) => (
                <SelectItem key={opt.value} value={opt.value}>
                  {opt.label}
                </SelectItem>
              ))}
            </SelectContent>
          </Select>
        </Field>

        <Field>
          <FieldLabel>Combobox (filled)</FieldLabel>
          <Combobox
            items={manyOptions}
            itemToStringValue={(opt: SimpleOption) => opt.label}
            defaultValue={manyOptions[0]}
            defaultOpen
          >
            <ComboboxTrigger>
              <ComboboxValue placeholder="Select network..." />
            </ComboboxTrigger>
            <ComboboxContent>
              <ComboboxInput placeholder="Search..." />
              <ComboboxEmpty>No results found.</ComboboxEmpty>
              <ComboboxList>
                {(option: SimpleOption) => (
                  <ComboboxItem key={option.value} value={option}>
                    {option.label}
                  </ComboboxItem>
                )}
              </ComboboxList>
            </ComboboxContent>
          </Combobox>
        </Field>

        <Field>
          <FieldLabel>Combobox multiple (filled)</FieldLabel>
          <ActiveDropdownsFilledMulti />
        </Field>
      </div>
    </div>
  ),
  play: async ({ canvasElement }) => {
    await assertAllInputTokens(canvasElement, stateTokens.active)
    await assertDropdownContentTokens(
      canvasElement,
      stateTokens.active.dropdown!,
    )
  },
}

function InputRow({
  label,
  children,
}: {
  label: string
  children: React.ReactNode
}) {
  return (
    <Field>
      <FieldLabel>{label}</FieldLabel>
      {children}
    </Field>
  )
}

function SelectBlock({
  label,
  triggerClassName,
  ...props
}: {
  label: string
  triggerClassName?: string
} & React.ComponentPropsWithoutRef<typeof Select>) {
  return (
    <InputRow label={label}>
      <Select {...props}>
        <SelectTrigger className={triggerClassName}>
          <SelectValue placeholder="Select an option" />
        </SelectTrigger>
        <SelectContent>
          <SelectItem value="option1">Option 1</SelectItem>
          <SelectItem value="option2">Option 2</SelectItem>
          <SelectItem value="option3">Option 3</SelectItem>
        </SelectContent>
      </Select>
    </InputRow>
  )
}

function SimpleSelectBlock({
  label,
  defaultValue,
  disabled,
  className,
}: {
  label: string
  defaultValue?: string
  disabled?: boolean
  className?: string
}) {
  return (
    <InputRow label={label}>
      <SimpleSelect
        options={selectOptions}
        placeholder="Select an option"
        defaultValue={defaultValue}
        disabled={disabled}
        className={className}
      />
    </InputRow>
  )
}

function ComboboxSingleBlock({
  label,
  triggerClassName,
  ...props
}: { label: string; triggerClassName?: string } & Partial<
  React.ComponentPropsWithoutRef<typeof Combobox>
>) {
  return (
    <InputRow label={label}>
      <Combobox
        items={comboboxOptions}
        itemToStringValue={(opt: SimpleOption) => opt.label}
        {...props}
      >
        <ComboboxTrigger className={triggerClassName}>
          <ComboboxValue placeholder="Select network..." />
        </ComboboxTrigger>
        <ComboboxContent>
          <ComboboxInput placeholder="Search..." />
          <ComboboxEmpty>No results found.</ComboboxEmpty>
          <ComboboxList>
            {(option: SimpleOption) => (
              <ComboboxItem key={option.value} value={option}>
                {option.label}
              </ComboboxItem>
            )}
          </ComboboxList>
        </ComboboxContent>
      </Combobox>
    </InputRow>
  )
}

function ComboboxMultiBlock({
  label,
  triggerClassName,
  defaultValue: defaultValueProp,
  ...props
}: {
  label: string
  triggerClassName?: string
  defaultValue?: SimpleOption[]
} & Partial<React.ComponentPropsWithoutRef<typeof Combobox>>) {
  const [selected, setSelected] = React.useState<SimpleOption[]>(
    defaultValueProp ?? [],
  )
  return (
    <InputRow label={label}>
      <Combobox
        multiple
        items={multiSelectOptions}
        itemToStringValue={(opt: SimpleOption) => opt.label}
        value={selected}
        onValueChange={(val: unknown) =>
          setSelected((val ?? []) as SimpleOption[])
        }
        {...props}
      >
        <ComboboxTrigger className={triggerClassName}>
          <ComboboxTagsValue<SimpleOption>
            placeholder="Select frameworks"
            maxCount={3}
          >
            {(opt: SimpleOption) => opt.label}
          </ComboboxTagsValue>
        </ComboboxTrigger>
        <ComboboxContent>
          <ComboboxInput placeholder="Search..." />
          <ComboboxEmpty>No results found.</ComboboxEmpty>
          <ComboboxList>
            {(option: SimpleOption) => (
              <ComboboxItem key={option.value} value={option}>
                {option.label}
              </ComboboxItem>
            )}
          </ComboboxList>
        </ComboboxContent>
      </Combobox>
    </InputRow>
  )
}

export const Hover: Story = {
  render: (_args) => (
    <div className="flex flex-col gap-8 p-8">
      <Typography variant="h4">Hover State — Input Components</Typography>

      <div className="grid grid-cols-2 gap-x-12 gap-y-6">
        <InputRow label="Input">
          <Input placeholder="Placeholder" className="hover" />
        </InputRow>

        <InputRow label="Input (with value)">
          <Input defaultValue="John Doe" className="hover" />
        </InputRow>

        <InputRow label="FieldInput">
          <FieldInput placeholder="Placeholder" className="hover" />
        </InputRow>

        <InputRow label="FieldInput (with value)">
          <FieldInput defaultValue="John Doe" className="hover" />
        </InputRow>

        <InputRow label="Textarea">
          <Textarea placeholder="Type something..." className="hover" />
        </InputRow>

        <InputRow label="Textarea (with value)">
          <Textarea
            defaultValue="Some pre-filled content here."
            className="hover"
          />
        </InputRow>

        <SelectBlock label="Select" triggerClassName="hover" />

        <SelectBlock
          label="Select (with value)"
          defaultValue="option1"
          triggerClassName="hover"
        />

        <SimpleSelectBlock label="SimpleSelect" className="hover" />

        <SimpleSelectBlock
          label="SimpleSelect (with value)"
          defaultValue="option1"
          className="hover"
        />

        <ComboboxSingleBlock label="Combobox" triggerClassName="hover" />

        <ComboboxSingleBlock
          label="Combobox (with value)"
          defaultValue={comboboxOptions[0]}
          triggerClassName="hover"
        />

        <ComboboxMultiBlock
          label="Combobox (multiple)"
          triggerClassName="hover"
        />

        <ComboboxMultiBlock
          label="Combobox multiple (with value)"
          defaultValue={[multiSelectOptions[0]]}
          triggerClassName="hover"
        />

        <InputRow label="Checkbox (unchecked)">
          <LabeledCheckbox>Accept terms</LabeledCheckbox>
        </InputRow>

        <InputRow label="Checkbox (checked)">
          <LabeledCheckbox defaultChecked>Accept terms</LabeledCheckbox>
        </InputRow>

        <InputRow label="RadioGroup (unchecked)">
          <RadioGroup>
            <RadioGroupItem value="a">Option A</RadioGroupItem>
            <RadioGroupItem value="b">Option B</RadioGroupItem>
          </RadioGroup>
        </InputRow>

        <InputRow label="RadioGroup (with value)">
          <RadioGroup defaultValue="a">
            <RadioGroupItem value="a">Option A</RadioGroupItem>
            <RadioGroupItem value="b">Option B</RadioGroupItem>
          </RadioGroup>
        </InputRow>
      </div>
    </div>
  ),
  play: async ({ canvasElement }) => {
    await assertAllInputTokens(canvasElement, stateTokens.hover)
  },
}

export const Disabled: Story = {
  render: (_args) => (
    <div className="flex flex-col gap-8 p-8">
      <Typography variant="h4">Disabled State — Input Components</Typography>

      <div className="grid grid-cols-2 gap-x-12 gap-y-6">
        <Field>
          <FieldLabel>Input</FieldLabel>
          <Input placeholder="Placeholder" disabled />
        </Field>

        <Field>
          <FieldLabel>Input (with value)</FieldLabel>
          <Input defaultValue="John Doe" disabled />
        </Field>

        <Field>
          <FieldLabel>FieldInput</FieldLabel>
          <FieldInput placeholder="Placeholder" disabled />
        </Field>

        <Field>
          <FieldLabel>FieldInput (with value)</FieldLabel>
          <FieldInput defaultValue="John Doe" disabled />
        </Field>

        <Field>
          <FieldLabel>Textarea</FieldLabel>
          <Textarea placeholder="Type something..." disabled />
        </Field>

        <Field>
          <FieldLabel>Textarea (with value)</FieldLabel>
          <Textarea defaultValue="Some pre-filled content here." disabled />
        </Field>

        <Field>
          <FieldLabel>Select</FieldLabel>
          <Select disabled>
            <SelectTrigger>
              <SelectValue placeholder="Select an option" />
            </SelectTrigger>
            <SelectContent>
              <SelectItem value="option1">Option 1</SelectItem>
              <SelectItem value="option2">Option 2</SelectItem>
              <SelectItem value="option3">Option 3</SelectItem>
            </SelectContent>
          </Select>
        </Field>

        <Field>
          <FieldLabel>Select (with value)</FieldLabel>
          <Select disabled defaultValue="option1">
            <SelectTrigger>
              <SelectValue placeholder="Select an option" />
            </SelectTrigger>
            <SelectContent>
              <SelectItem value="option1">Option 1</SelectItem>
              <SelectItem value="option2">Option 2</SelectItem>
              <SelectItem value="option3">Option 3</SelectItem>
            </SelectContent>
          </Select>
        </Field>

        <Field>
          <FieldLabel>SimpleSelect</FieldLabel>
          <SimpleSelect
            options={selectOptions}
            placeholder="Select an option"
            disabled
          />
        </Field>

        <Field>
          <FieldLabel>SimpleSelect (with value)</FieldLabel>
          <SimpleSelect
            options={selectOptions}
            placeholder="Select an option"
            defaultValue="option1"
            disabled
          />
        </Field>

        <ComboboxSingleBlock label="Combobox" disabled />

        <ComboboxSingleBlock
          label="Combobox (with value)"
          defaultValue={comboboxOptions[0]}
          disabled
        />

        <ComboboxMultiBlock label="Combobox (multiple)" disabled />

        <ComboboxMultiBlock
          label="Combobox multiple (with value)"
          defaultValue={[multiSelectOptions[0]]}
          disabled
        />

        <Field>
          <FieldLabel>Checkbox (unchecked)</FieldLabel>
          <LabeledCheckbox disabled>Accept terms</LabeledCheckbox>
        </Field>

        <Field>
          <FieldLabel>Checkbox (checked)</FieldLabel>
          <LabeledCheckbox disabled defaultChecked>
            Accept terms
          </LabeledCheckbox>
        </Field>

        <Field>
          <FieldLabel>RadioGroup (unchecked)</FieldLabel>
          <RadioGroup disabled>
            <RadioGroupItem value="a">Option A</RadioGroupItem>
            <RadioGroupItem value="b">Option B</RadioGroupItem>
          </RadioGroup>
        </Field>

        <Field>
          <FieldLabel>RadioGroup (with value)</FieldLabel>
          <RadioGroup disabled defaultValue="a">
            <RadioGroupItem value="a">Option A</RadioGroupItem>
            <RadioGroupItem value="b">Option B</RadioGroupItem>
          </RadioGroup>
        </Field>
      </div>
    </div>
  ),
  play: async ({ canvasElement }) => {
    await assertAllInputTokens(canvasElement, stateTokens.disabled)
  },
}

const widthVariants = ['responsive', 'hug', 'full'] as const

function WidthSection({ width }: { width: 'responsive' | 'hug' | 'full' }) {
  return (
    <div className="flex flex-col gap-4 rounded border border-dashed border-muted-foreground/30 p-4">
      <Typography variant="body-semi-s">{width}</Typography>
      <Input placeholder="Input" width={width} />
      <FieldInput placeholder="FieldInput" width={width} />
      <Textarea placeholder="Textarea" width={width} />
      <Select>
        <SelectTrigger width={width}>
          <SelectValue placeholder="Select" />
        </SelectTrigger>
        <SelectContent>
          <SelectItem value="option1">Option 1</SelectItem>
          <SelectItem value="option2">Option 2</SelectItem>
        </SelectContent>
      </Select>
      <Combobox
        items={comboboxOptions}
        itemToStringValue={(opt: SimpleOption) => opt.label}
      >
        <ComboboxTrigger width={width}>
          <ComboboxValue placeholder="Combobox" />
        </ComboboxTrigger>
        <ComboboxContent>
          <ComboboxInput placeholder="Search..." />
          <ComboboxEmpty>No results found.</ComboboxEmpty>
          <ComboboxList>
            {(option: SimpleOption) => (
              <ComboboxItem key={option.value} value={option}>
                {option.label}
              </ComboboxItem>
            )}
          </ComboboxList>
        </ComboboxContent>
      </Combobox>
      <Combobox
        multiple
        items={multiSelectOptions}
        itemToStringValue={(opt: SimpleOption) => opt.label}
      >
        <ComboboxTrigger width={width}>
          <ComboboxTagsValue<SimpleOption>
            placeholder="MultiSelect"
            maxCount={3}
          >
            {(opt: SimpleOption) => opt.label}
          </ComboboxTagsValue>
        </ComboboxTrigger>
        <ComboboxContent>
          <ComboboxInput placeholder="Search..." />
          <ComboboxEmpty>No results found.</ComboboxEmpty>
          <ComboboxList>
            {(option: SimpleOption) => (
              <ComboboxItem key={option.value} value={option}>
                {option.label}
              </ComboboxItem>
            )}
          </ComboboxList>
        </ComboboxContent>
      </Combobox>
    </div>
  )
}

export const WidthVariants: Story = {
  render: (_args) => (
    <div className="flex flex-col gap-8 p-8">
      <Typography variant="h4">Width Variants</Typography>
      <div className="flex flex-col gap-8">
        {widthVariants.map((w) => (
          <WidthSection key={w} width={w} />
        ))}
      </div>
    </div>
  ),
}

const fewOptions = manyOptions.slice(0, 6)

function SizeMultiSelect({
  size,
  options,
}: {
  size: 'default' | 'sm' | 'xs'
  options: SimpleOption[]
}) {
  const [selected, setSelected] = React.useState<SimpleOption[]>([])

  return (
    <Combobox
      defaultOpen
      multiple
      items={options}
      itemToStringValue={(opt: SimpleOption) => opt.label}
      value={selected}
      onValueChange={(val: unknown) =>
        setSelected((val ?? []) as SimpleOption[])
      }
      size={size}
    >
      <ComboboxTrigger>
        <ComboboxTagsValue<SimpleOption>
          placeholder="Select network..."
          maxCount={3}
        >
          {(opt: SimpleOption) => opt.label}
        </ComboboxTagsValue>
      </ComboboxTrigger>
      <ComboboxContent>
        <ComboboxInput placeholder="Search..." />
        <ComboboxEmpty>No results found.</ComboboxEmpty>
        <ComboboxList>
          {(option: SimpleOption) => (
            <ComboboxItem key={option.value} value={option}>
              {option.label}
            </ComboboxItem>
          )}
        </ComboboxList>
      </ComboboxContent>
    </Combobox>
  )
}

function SizeInputsStory({ size }: { size: 'default' | 'sm' | 'xs' }) {
  return (
    <div className="flex items-start gap-8 p-8">
      <Field>
        <FieldLabel>Input</FieldLabel>
        <Input placeholder="Placeholder" size={size} />
      </Field>
      <Field>
        <FieldLabel>FieldInput</FieldLabel>
        <FieldInput placeholder="Placeholder" size={size} />
      </Field>
      <Field>
        <FieldLabel>Textarea</FieldLabel>
        <Textarea placeholder="Type something..." size={size} />
      </Field>
    </div>
  )
}

function SizeDropdownsStory({
  size,
  options,
}: {
  size: 'default' | 'sm' | 'xs'
  options: SimpleOption[]
}) {
  return (
    <div className="flex items-start gap-8 p-8 pb-48">
      <Field>
        <FieldLabel>Select</FieldLabel>
        <Select size={size} defaultOpen>
          <SelectTrigger>
            <SelectValue placeholder="Select an option" />
          </SelectTrigger>
          <SelectContent>
            {options.map((opt) => (
              <SelectItem key={opt.value} value={opt.value}>
                {opt.label}
              </SelectItem>
            ))}
          </SelectContent>
        </Select>
      </Field>
      <Field>
        <FieldLabel>Combobox</FieldLabel>
        <Combobox
          defaultOpen
          items={options}
          itemToStringValue={(opt: SimpleOption) => opt.label}
          size={size}
        >
          <ComboboxTrigger>
            <ComboboxValue placeholder="Select network..." />
          </ComboboxTrigger>
          <ComboboxContent>
            <ComboboxInput placeholder="Search..." />
            <ComboboxEmpty>No results found.</ComboboxEmpty>
            <ComboboxList>
              {(option: SimpleOption) => (
                <ComboboxItem key={option.value} value={option}>
                  {option.label}
                </ComboboxItem>
              )}
            </ComboboxList>
          </ComboboxContent>
        </Combobox>
      </Field>
      <Field>
        <FieldLabel>MultiSelect</FieldLabel>
        <SizeMultiSelect size={size} options={options} />
      </Field>
    </div>
  )
}

export const SizeDefaultInputs: Story = {
  render: (_args) => <SizeInputsStory size="default" />,
}

export const SizeDefaultDropdowns: Story = {
  render: (_args) => (
    <SizeDropdownsStory size="default" options={manyOptions} />
  ),
}

export const SizeDefaultDropdownsFew: Story = {
  render: (_args) => <SizeDropdownsStory size="default" options={fewOptions} />,
}

export const SizeSmInputs: Story = {
  render: (_args) => <SizeInputsStory size="sm" />,
}

export const SizeSmDropdowns: Story = {
  render: (_args) => <SizeDropdownsStory size="sm" options={manyOptions} />,
}

export const SizeSmDropdownsFew: Story = {
  render: (_args) => <SizeDropdownsStory size="sm" options={fewOptions} />,
}

export const SizeXsInputs: Story = {
  render: (_args) => <SizeInputsStory size="xs" />,
}

export const SizeXsDropdowns: Story = {
  render: (_args) => <SizeDropdownsStory size="xs" options={manyOptions} />,
}

export const SizeXsDropdownsFew: Story = {
  render: (_args) => <SizeDropdownsStory size="xs" options={fewOptions} />,
}

function SizeEmptyStatesStory({ size }: { size: 'default' | 'sm' | 'xs' }) {
  return (
    <div className="flex items-start gap-8 p-8 pb-48">
      <Field>
        <FieldLabel>Combobox</FieldLabel>
        <Combobox
          defaultOpen
          items={comboboxOptions}
          itemToStringValue={(opt: SimpleOption) => opt.label}
          defaultInputValue="zzz"
          size={size}
        >
          <ComboboxTrigger>
            <ComboboxValue placeholder="Select network..." />
          </ComboboxTrigger>
          <ComboboxContent>
            <ComboboxInput placeholder="Search..." />
            <ComboboxEmpty>No results found.</ComboboxEmpty>
            <ComboboxList>
              {(option: SimpleOption) => (
                <ComboboxItem key={option.value} value={option}>
                  {option.label}
                </ComboboxItem>
              )}
            </ComboboxList>
          </ComboboxContent>
        </Combobox>
      </Field>
      <Field>
        <FieldLabel>MultiSelect</FieldLabel>
        <Combobox
          defaultOpen
          multiple
          items={multiSelectOptions}
          itemToStringValue={(opt: SimpleOption) => opt.label}
          defaultInputValue="zzz"
          size={size}
        >
          <ComboboxTrigger>
            <ComboboxTagsValue<SimpleOption>
              placeholder="Select network..."
              maxCount={3}
            >
              {(opt: SimpleOption) => opt.label}
            </ComboboxTagsValue>
          </ComboboxTrigger>
          <ComboboxContent>
            <ComboboxInput placeholder="Search..." />
            <ComboboxEmpty>No results found.</ComboboxEmpty>
            <ComboboxList>
              {(option: SimpleOption) => (
                <ComboboxItem key={option.value} value={option}>
                  {option.label}
                </ComboboxItem>
              )}
            </ComboboxList>
          </ComboboxContent>
        </Combobox>
      </Field>
    </div>
  )
}

export const SizeDefaultEmptyStates: Story = {
  render: (_args) => <SizeEmptyStatesStory size="default" />,
}

export const SizeSmEmptyStates: Story = {
  render: (_args) => <SizeEmptyStatesStory size="sm" />,
}

export const SizeXsEmptyStates: Story = {
  render: (_args) => <SizeEmptyStatesStory size="xs" />,
}
