import type { Meta, StoryObj } from '@storybook/vue3-vite';
import { ref, computed } from 'vue';
import { useFilter } from 'reka-ui';
import UiListbox from './UiListbox.vue';
import UiListboxContent from './UiListboxContent.vue';
import UiListboxFilter from './UiListboxFilter.vue';
import UiListboxItem from './UiListboxItem.vue';
import UiListboxItemIndicator from './UiListboxItemIndicator.vue';
import UiListboxGroup from './UiListboxGroup.vue';
import UiListboxGroupLabel from './UiListboxGroupLabel.vue';

/**
 * UiListbox is a scrollable, single- or multi-select option list with optional filtering and grouping.
 * Use it inside popovers and command palettes, or directly when an always-visible selection list fits the layout.
 * For compact, dropdown-style single selection, prefer `UiSelect`.
 */
const meta: Meta<typeof UiListbox> = {
  title: 'Components/UiListbox',
  component: UiListbox,
  tags: ['autodocs'],
  argTypes: {
    disabled: {
      control: 'boolean',
      description: 'Disable the listbox',
    },
    multiple: {
      control: 'boolean',
      description: 'Allow multiple selections',
    },
    highlightOnHover: {
      control: 'boolean',
      description: 'Highlight items on hover',
    },
  },
  args: {
    disabled: false,
    multiple: false,
    highlightOnHover: false,
  },
};

export default meta;

type Story = StoryObj<typeof UiListbox>;

const fruits = [
  { value: 'apple', label: 'Apple' },
  { value: 'banana', label: 'Banana' },
  { value: 'cherry', label: 'Cherry' },
  { value: 'date', label: 'Date' },
  { value: 'elderberry', label: 'Elderberry' },
];

const defaultTemplateSource = `<script setup lang="ts">
import { ref } from 'vue'
import {
  UiListbox,
  UiListboxContent,
  UiListboxItem,
  UiListboxItemIndicator
} from '@aleph-alpha/ui-library'

const selected = ref('apple')
const fruits = [
  { value: 'apple', label: 'Apple' },
  { value: 'banana', label: 'Banana' },
  { value: 'cherry', label: 'Cherry' },
]
</script>

<template>
  <UiListbox v-model="selected" class="w-[200px] p-1">
    <UiListboxContent>
      <UiListboxItem
        v-for="fruit in fruits"
        :key="fruit.value"
        :value="fruit.value"
      >
        <span>{{ fruit.label }}</span>
        <UiListboxItemIndicator />
      </UiListboxItem>
    </UiListboxContent>
  </UiListbox>
</template>`;

/**
 * Default single-selection listbox.
 */
export const Default: Story = {
  render: (args) => ({
    components: {
      UiListbox,
      UiListboxContent,
      UiListboxItem,
      UiListboxItemIndicator,
    },
    setup() {
      const selected = ref('apple');
      return { args, selected, fruits };
    },
    template: `
      <UiListbox
        v-model="selected"
        class="w-[200px] p-1"
        :disabled="args.disabled"
        :highlight-on-hover="args.highlightOnHover"
      >
        <UiListboxContent>
          <UiListboxItem
            v-for="fruit in fruits"
            :key="fruit.value"
            :value="fruit.value"
          >
            <span>{{ fruit.label }}</span>
            <UiListboxItemIndicator />
          </UiListboxItem>
        </UiListboxContent>
      </UiListbox>
    `,
  }),
  parameters: {
    docs: {
      source: {
        code: defaultTemplateSource,
      },
    },
  },
};

const multipleTemplateSource = `<script setup lang="ts">
import { ref } from 'vue'
import {
  UiListbox,
  UiListboxContent,
  UiListboxItem,
  UiListboxItemIndicator
} from '@aleph-alpha/ui-library'

const selected = ref(['apple', 'cherry'])
const fruits = [
  { value: 'apple', label: 'Apple' },
  { value: 'banana', label: 'Banana' },
  { value: 'cherry', label: 'Cherry' },
]
</script>

<template>
  <UiListbox v-model="selected" multiple class="w-[200px] p-1">
    <UiListboxContent>
      <UiListboxItem
        v-for="fruit in fruits"
        :key="fruit.value"
        :value="fruit.value"
      >
        <span>{{ fruit.label }}</span>
        <UiListboxItemIndicator />
      </UiListboxItem>
    </UiListboxContent>
  </UiListbox>
</template>`;

/**
 * Multiple selection listbox.
 */
export const Multiple: Story = {
  render: () => ({
    components: {
      UiListbox,
      UiListboxContent,
      UiListboxItem,
      UiListboxItemIndicator,
    },
    setup() {
      const selected = ref(['apple', 'cherry']);
      return { selected, fruits };
    },
    template: `
      <UiListbox v-model="selected" multiple class="w-[200px] p-1">
        <UiListboxContent>
          <UiListboxItem
            v-for="fruit in fruits"
            :key="fruit.value"
            :value="fruit.value"
          >
            <span>{{ fruit.label }}</span>
            <UiListboxItemIndicator />
          </UiListboxItem>
        </UiListboxContent>
      </UiListbox>
    `,
  }),
  parameters: {
    docs: {
      source: {
        code: multipleTemplateSource,
      },
    },
  },
};

const withFilterTemplateSource = `<script setup lang="ts">
import { ref, computed } from 'vue'
import { useFilter } from 'reka-ui'
import {
  UiListbox,
  UiListboxContent,
  UiListboxFilter,
  UiListboxItem,
  UiListboxItemIndicator
} from '@aleph-alpha/ui-library'

const selected = ref('apple')
const searchTerm = ref('')
const fruits = [
  { value: 'apple', label: 'Apple' },
  { value: 'banana', label: 'Banana' },
  { value: 'cherry', label: 'Cherry' },
]

const { contains } = useFilter({ sensitivity: 'base' })
const filteredFruits = computed(() =>
  searchTerm.value === ''
    ? fruits
    : fruits.filter(fruit => contains(fruit.label, searchTerm.value))
)
</script>

<template>
  <UiListbox v-model="selected" class="w-[200px]">
    <UiListboxFilter v-model="searchTerm" placeholder="Search fruits..." class="border-b" />
    <UiListboxContent class="p-1">
      <UiListboxItem
        v-for="fruit in filteredFruits"
        :key="fruit.value"
        :value="fruit.value"
      >
        <span>{{ fruit.label }}</span>
        <UiListboxItemIndicator />
      </UiListboxItem>
    </UiListboxContent>
  </UiListbox>
</template>`;

/**
 * Listbox with filter/search functionality.
 */
export const WithFilter: Story = {
  render: () => ({
    components: {
      UiListbox,
      UiListboxContent,
      UiListboxFilter,
      UiListboxItem,
      UiListboxItemIndicator,
    },
    setup() {
      const selected = ref('apple');
      const searchTerm = ref('');
      const { contains } = useFilter({ sensitivity: 'base' });

      const filteredFruits = computed(() =>
        searchTerm.value === ''
          ? fruits
          : fruits.filter((fruit) => contains(fruit.label, searchTerm.value)),
      );

      return { selected, searchTerm, filteredFruits };
    },
    template: `
      <UiListbox v-model="selected" class="w-[200px]">
        <UiListboxFilter v-model="searchTerm" placeholder="Search fruits..." class="border-b" />
        <UiListboxContent class="p-1">
          <UiListboxItem
            v-for="fruit in filteredFruits"
            :key="fruit.value"
            :value="fruit.value"
          >
            <span>{{ fruit.label }}</span>
            <UiListboxItemIndicator />
          </UiListboxItem>
        </UiListboxContent>
      </UiListbox>
    `,
  }),
  parameters: {
    docs: {
      source: {
        code: withFilterTemplateSource,
      },
    },
  },
};

const withGroupsTemplateSource = `<script setup lang="ts">
import { ref } from 'vue'
import {
  UiListbox,
  UiListboxContent,
  UiListboxItem,
  UiListboxItemIndicator,
  UiListboxGroup,
  UiListboxGroupLabel
} from '@aleph-alpha/ui-library'

const selected = ref('apple')
</script>

<template>
  <UiListbox v-model="selected" class="w-[200px] p-1">
    <UiListboxContent>
      <UiListboxGroup>
        <UiListboxGroupLabel>Fruits</UiListboxGroupLabel>
        <UiListboxItem value="apple">
          <span>Apple</span>
          <UiListboxItemIndicator />
        </UiListboxItem>
        <UiListboxItem value="banana">
          <span>Banana</span>
          <UiListboxItemIndicator />
        </UiListboxItem>
      </UiListboxGroup>
      <UiListboxGroup>
        <UiListboxGroupLabel>Vegetables</UiListboxGroupLabel>
        <UiListboxItem value="carrot">
          <span>Carrot</span>
          <UiListboxItemIndicator />
        </UiListboxItem>
        <UiListboxItem value="broccoli">
          <span>Broccoli</span>
          <UiListboxItemIndicator />
        </UiListboxItem>
      </UiListboxGroup>
    </UiListboxContent>
  </UiListbox>
</template>`;

/**
 * Listbox with grouped items.
 */
export const WithGroups: Story = {
  render: () => ({
    components: {
      UiListbox,
      UiListboxContent,
      UiListboxItem,
      UiListboxItemIndicator,
      UiListboxGroup,
      UiListboxGroupLabel,
    },
    setup() {
      const selected = ref('apple');
      return { selected };
    },
    template: `
      <UiListbox v-model="selected" class="w-[200px] p-1">
        <UiListboxContent>
          <UiListboxGroup>
            <UiListboxGroupLabel>Fruits</UiListboxGroupLabel>
            <UiListboxItem value="apple">
              <span>Apple</span>
              <UiListboxItemIndicator />
            </UiListboxItem>
            <UiListboxItem value="banana">
              <span>Banana</span>
              <UiListboxItemIndicator />
            </UiListboxItem>
          </UiListboxGroup>
          <UiListboxGroup>
            <UiListboxGroupLabel>Vegetables</UiListboxGroupLabel>
            <UiListboxItem value="carrot">
              <span>Carrot</span>
              <UiListboxItemIndicator />
            </UiListboxItem>
            <UiListboxItem value="broccoli">
              <span>Broccoli</span>
              <UiListboxItemIndicator />
            </UiListboxItem>
          </UiListboxGroup>
        </UiListboxContent>
      </UiListbox>
    `,
  }),
  parameters: {
    docs: {
      source: {
        code: withGroupsTemplateSource,
      },
    },
  },
};

const disabledTemplateSource = `<script setup lang="ts">
import { ref } from 'vue'
import {
  UiListbox,
  UiListboxContent,
  UiListboxItem,
  UiListboxItemIndicator
} from '@aleph-alpha/ui-library'

const selected = ref('apple')
const fruits = [
  { value: 'apple', label: 'Apple' },
  { value: 'banana', label: 'Banana' },
  { value: 'cherry', label: 'Cherry' },
]
</script>

<template>
  <UiListbox v-model="selected" disabled class="w-[200px] p-1">
    <UiListboxContent>
      <UiListboxItem
        v-for="fruit in fruits"
        :key="fruit.value"
        :value="fruit.value"
      >
        <span>{{ fruit.label }}</span>
        <UiListboxItemIndicator />
      </UiListboxItem>
    </UiListboxContent>
  </UiListbox>
</template>`;

/**
 * Disabled listbox.
 */
export const Disabled: Story = {
  args: {
    disabled: true,
  },
  render: () => ({
    components: {
      UiListbox,
      UiListboxContent,
      UiListboxItem,
      UiListboxItemIndicator,
    },
    setup() {
      const selected = ref('apple');
      return { selected, fruits };
    },
    template: `
      <UiListbox v-model="selected" disabled class="w-[200px] p-1">
        <UiListboxContent>
          <UiListboxItem
            v-for="fruit in fruits"
            :key="fruit.value"
            :value="fruit.value"
          >
            <span>{{ fruit.label }}</span>
            <UiListboxItemIndicator />
          </UiListboxItem>
        </UiListboxContent>
      </UiListbox>
    `,
  }),
  parameters: {
    docs: {
      source: {
        code: disabledTemplateSource,
      },
    },
  },
};

const highlightOnHoverTemplateSource = `<script setup lang="ts">
import { ref } from 'vue'
import {
  UiListbox,
  UiListboxContent,
  UiListboxItem,
  UiListboxItemIndicator
} from '@aleph-alpha/ui-library'

const selected = ref('apple')
const fruits = [
  { value: 'apple', label: 'Apple' },
  { value: 'banana', label: 'Banana' },
  { value: 'cherry', label: 'Cherry' },
]
</script>

<template>
  <UiListbox v-model="selected" highlight-on-hover class="w-[200px] p-1">
    <UiListboxContent>
      <UiListboxItem
        v-for="fruit in fruits"
        :key="fruit.value"
        :value="fruit.value"
      >
        <span>{{ fruit.label }}</span>
        <UiListboxItemIndicator />
      </UiListboxItem>
    </UiListboxContent>
  </UiListbox>
</template>`;

/**
 * Listbox with highlight on hover enabled.
 */
export const HighlightOnHover: Story = {
  args: {
    highlightOnHover: true,
  },
  render: () => ({
    components: {
      UiListbox,
      UiListboxContent,
      UiListboxItem,
      UiListboxItemIndicator,
    },
    setup() {
      const selected = ref('apple');
      return { selected, fruits };
    },
    template: `
      <UiListbox v-model="selected" highlight-on-hover class="w-[200px] p-1">
        <UiListboxContent>
          <UiListboxItem
            v-for="fruit in fruits"
            :key="fruit.value"
            :value="fruit.value"
          >
            <span>{{ fruit.label }}</span>
            <UiListboxItemIndicator />
          </UiListboxItem>
        </UiListboxContent>
      </UiListbox>
    `,
  }),
  parameters: {
    docs: {
      source: {
        code: highlightOnHoverTemplateSource,
      },
    },
  },
};

const withDisabledItemsTemplateSource = `<script setup lang="ts">
import { ref } from 'vue'
import {
  UiListbox,
  UiListboxContent,
  UiListboxItem,
  UiListboxItemIndicator
} from '@aleph-alpha/ui-library'

const selected = ref('apple')
</script>

<template>
  <UiListbox v-model="selected" class="w-[200px] p-1">
    <UiListboxContent>
      <UiListboxItem value="apple">
        <span>Apple</span>
        <UiListboxItemIndicator />
      </UiListboxItem>
      <UiListboxItem value="banana" disabled>
        <span>Banana (unavailable)</span>
        <UiListboxItemIndicator />
      </UiListboxItem>
      <UiListboxItem value="cherry">
        <span>Cherry</span>
        <UiListboxItemIndicator />
      </UiListboxItem>
    </UiListboxContent>
  </UiListbox>
</template>`;

/**
 * Listbox with some disabled items.
 */
export const WithDisabledItems: Story = {
  render: () => ({
    components: {
      UiListbox,
      UiListboxContent,
      UiListboxItem,
      UiListboxItemIndicator,
    },
    setup() {
      const selected = ref('apple');
      return { selected };
    },
    template: `
      <UiListbox v-model="selected" class="w-[200px] p-1">
        <UiListboxContent>
          <UiListboxItem value="apple">
            <span>Apple</span>
            <UiListboxItemIndicator />
          </UiListboxItem>
          <UiListboxItem value="banana" disabled>
            <span>Banana (unavailable)</span>
            <UiListboxItemIndicator />
          </UiListboxItem>
          <UiListboxItem value="cherry">
            <span>Cherry</span>
            <UiListboxItemIndicator />
          </UiListboxItem>
        </UiListboxContent>
      </UiListbox>
    `,
  }),
  parameters: {
    docs: {
      source: {
        code: withDisabledItemsTemplateSource,
      },
    },
  },
};
